Merge "NN HAL: Upgrade IPreparedModel::execute to 1.3."
diff --git a/audio/6.0/IDevice.hal b/audio/6.0/IDevice.hal
index 42a545b..e885fe2 100644
--- a/audio/6.0/IDevice.hal
+++ b/audio/6.0/IDevice.hal
@@ -260,7 +260,8 @@
     /**
      * Returns an array with available microphones in device.
      *
-     * @return retval INVALID_STATE if the call is not successful,
+     * @return retval NOT_SUPPORTED if there are no microphones on this device
+     *                INVALID_STATE if the call is not successful,
      *                OK otherwise.
      *
      * @return microphones array with microphones info
diff --git a/audio/6.0/IStream.hal b/audio/6.0/IStream.hal
index f4c91f8..451e116 100644
--- a/audio/6.0/IStream.hal
+++ b/audio/6.0/IStream.hal
@@ -123,9 +123,11 @@
      * equivalent to getting AUDIO_PARAMETER_STREAM_SUP_FORMATS on the legacy
      * HAL.
      *
+     * @return retval operation completion status.
      * @return formats supported audio formats.
+     *                 Must be non empty if retval is OK.
      */
-    getSupportedFormats() generates (vec<AudioFormat> formats);
+    getSupportedFormats() generates (Result retval, vec<AudioFormat> formats);
 
     /**
      * Sets the audio format of the stream. Calling this method is equivalent to
diff --git a/audio/6.0/config/api/current.txt b/audio/6.0/config/api/current.txt
index 7aa147c..e67831c 100644
--- a/audio/6.0/config/api/current.txt
+++ b/audio/6.0/config/api/current.txt
@@ -250,7 +250,9 @@
 
   public class GlobalConfiguration {
     ctor public GlobalConfiguration();
+    method public boolean getCall_screen_mode_supported();
     method public boolean getSpeaker_drc_enabled();
+    method public void setCall_screen_mode_supported(boolean);
     method public void setSpeaker_drc_enabled(boolean);
   }
 
diff --git a/audio/6.0/config/audio_policy_configuration.xsd b/audio/6.0/config/audio_policy_configuration.xsd
index 0dc89bb..29f6f38 100644
--- a/audio/6.0/config/audio_policy_configuration.xsd
+++ b/audio/6.0/config/audio_policy_configuration.xsd
@@ -66,6 +66,7 @@
     </xs:element>
     <xs:complexType name="globalConfiguration">
         <xs:attribute name="speaker_drc_enabled" type="xs:boolean" use="required"/>
+        <xs:attribute name="call_screen_mode_supported" type="xs:boolean" use="optional"/>
     </xs:complexType>
     <xs:complexType name="modules">
         <xs:annotation>
diff --git a/audio/README b/audio/README
index abe979c..afafbe3 100644
--- a/audio/README
+++ b/audio/README
@@ -1,5 +1,8 @@
 Directory structure of the audio HIDL related code.
 
+Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL
+based on an existing one.
+
 audio
 |-- 2.0              <== core 2.0 HIDL API. .hal can not be moved into the core directory
 |                        because that would change its namespace and include path
@@ -11,13 +14,13 @@
 |   |-- 2.0          <== HIDL API of V2
 |   |-- 4.0
 |   |-- ...
-|   `-- all_versions <== code common to all version of both core and effect API
+|   `-- all-versions <== code common to all version of both core and effect API
 |       |-- default  <== implementation shared code between core and effect impl
 |       |-- test     <== utilities used by tests
 |       `-- util     <== utilities used by both implementation and tests
 |
 |-- core             <== VTS and default implementation of the core API (not HIDL, see /audio/2.0))
-|   `-- all_versions <== Code is version independent through #if and separate files
+|   `-- all-versions <== Code is version independent through #if and separate files
 |       |-- default  <== code that wraps the legacy API
 |       `-- vts      <== vts of core API
 |           |-- 2.0  <== 2.0 specific tests and helpers
@@ -28,6 +31,6 @@
     |-- 2.0
     |-- 4.0
     |-- ...
-    `-- all_versions
+    `-- all-versions
         |-- default
         `-- vts
diff --git a/audio/common/2.0/Android.bp b/audio/common/2.0/Android.bp
index 475b309..bd3b069 100644
--- a/audio/common/2.0/Android.bp
+++ b/audio/common/2.0/Android.bp
@@ -9,6 +9,6 @@
     srcs: [
         "types.hal",
     ],
-    gen_java: false,
+    gen_java: true,
     gen_java_constants: true,
 }
diff --git a/audio/common/4.0/Android.bp b/audio/common/4.0/Android.bp
index 83f5aad..c01c486 100644
--- a/audio/common/4.0/Android.bp
+++ b/audio/common/4.0/Android.bp
@@ -9,6 +9,6 @@
     srcs: [
         "types.hal",
     ],
-    gen_java: false,
+    gen_java: true,
     gen_java_constants: true,
 }
diff --git a/audio/common/5.0/Android.bp b/audio/common/5.0/Android.bp
index be0f59e..761c171 100644
--- a/audio/common/5.0/Android.bp
+++ b/audio/common/5.0/Android.bp
@@ -12,6 +12,6 @@
     interfaces: [
         "android.hidl.safe_union@1.0",
     ],
-    gen_java: false,
+    gen_java: true,
     gen_java_constants: true,
 }
diff --git a/audio/common/6.0/types.hal b/audio/common/6.0/types.hal
index 132f86d..0c97c36 100644
--- a/audio/common/6.0/types.hal
+++ b/audio/common/6.0/types.hal
@@ -556,6 +556,8 @@
     IN_CALL          = 2,
     /** Calls handled by apps (Eg: Hangout). */
     IN_COMMUNICATION = 3,
+    /** Call screening in progress */
+    CALL_SCREEN      = 4,
 };
 
 @export(name="", value_prefix="AUDIO_DEVICE_")
diff --git a/audio/core/all-versions/default/Stream.cpp b/audio/core/all-versions/default/Stream.cpp
index 2a4ef6d..74e5945 100644
--- a/audio/core/all-versions/default/Stream.cpp
+++ b/audio/core/all-versions/default/Stream.cpp
@@ -175,8 +175,17 @@
         for (size_t i = 0; i < halFormats.size(); ++i) {
             formats[i] = AudioFormat(halFormats[i]);
         }
+        // Legacy get_parameter does not return a status_t, thus can not advertise of failure.
+        // Note that the method must not return an empty list if this capability is supported.
+        if (formats.size() == 0) {
+            result = Result::NOT_SUPPORTED;
+        }
     }
+#if MAJOR_VERSION <= 5
     _hidl_cb(formats);
+#elif MAJOR_VERSION >= 6
+    _hidl_cb(result, formats);
+#endif
     return Void();
 }
 
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index b8defb6..e267a5e 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -18,15 +18,16 @@
 
 TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
     doc::test("Calling openDevice(\"primary\") should return the primary device.");
+    if (getDeviceName() != DeviceManager::kPrimaryDevice) {
+        GTEST_SKIP() << "No primary device on this factory";  // returns
+    }
+
     struct WaitExecutor {
         ~WaitExecutor() { DeviceManager::waitForInstanceDestruction(); }
     } waitExecutor;  // Make sure we wait for the device destruction on exiting from the test.
     Result result;
     sp<IDevice> baseDevice;
     ASSERT_OK(getDevicesFactory()->openDevice("primary", returnIn(result, baseDevice)));
-    if (result != Result::OK && isPrimaryDeviceOptional()) {
-        GTEST_SKIP() << "No primary device on this factory";  // returns
-    }
     ASSERT_OK(result);
     ASSERT_TRUE(baseDevice != nullptr);
 
@@ -39,10 +40,13 @@
 /////////////////////////// get(Active)Microphones ///////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-TEST_P(AudioPrimaryHidlTest, GetMicrophonesTest) {
+TEST_P(AudioHidlDeviceTest, GetMicrophonesTest) {
     doc::test("Make sure getMicrophones always succeeds");
     hidl_vec<MicrophoneInfo> microphones;
     ASSERT_OK(getDevice()->getMicrophones(returnIn(res, microphones)));
+    if (res == Result::NOT_SUPPORTED) {
+        GTEST_SKIP() << "getMicrophones is not supported";  // returns
+    }
     ASSERT_OK(res);
     if (microphones.size() > 0) {
         // When there is microphone on the phone, try to open an input stream
@@ -120,7 +124,7 @@
     }
 }
 
-TEST_P(AudioPrimaryHidlTest, SetConnectedState) {
+TEST_P(AudioHidlDeviceTest, SetConnectedState) {
     doc::test("Check that the HAL can be notified of device connection and deconnection");
     using AD = AudioDevice;
     for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
@@ -142,7 +146,7 @@
     // Because there is no way of knowing if the devices were connected before
     // calling setConnectedState, there is no way to restore the HAL to its
     // initial state. To workaround this, destroy the HAL at the end of this test.
-    ASSERT_TRUE(DeviceManager::getInstance().resetPrimary(getFactoryName()));
+    ASSERT_TRUE(resetDevice());
 }
 
 static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
@@ -168,9 +172,10 @@
     DeviceAddress otherAddress = address;
     otherAddress.device = (address.device & AudioDevice::BIT_IN) == 0 ? AudioDevice::OUT_SPEAKER
                                                                       : AudioDevice::IN_BUILTIN_MIC;
-    EXPECT_OK(stream->setDevices({otherAddress}));
+    EXPECT_RESULT(okOrNotSupported, stream->setDevices({otherAddress}));
 
-    ASSERT_OK(stream->setDevices({address}));  // Go back to the original value
+    ASSERT_RESULT(okOrNotSupported,
+                  stream->setDevices({address}));  // Go back to the original value
 }
 
 TEST_IO_STREAM(SetDevices, "Check that the stream can be rerouted to SPEAKER or BUILTIN_MIC",
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
index 8415053..7a52d0e 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalUtils.h
@@ -75,11 +75,18 @@
         return res;
     }
 
+#if MAJOR_VERSION <= 5
     static Result formats(IStream* stream, hidl_vec<AudioFormat>& capabilities) {
         EXPECT_OK(stream->getSupportedFormats(returnIn(capabilities)));
-        // TODO: this should be an optional function
         return Result::OK;
     }
+#elif MAJOR_VERSION >= 6
+    static Result formats(IStream* stream, hidl_vec<AudioFormat>& capabilities) {
+        Result res;
+        EXPECT_OK(stream->getSupportedFormats(returnIn(res, capabilities)));
+        return res;
+    }
+#endif
 };
 
 template <class T>
diff --git a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
index 6314ea7..30f8a7a 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -16,3 +16,131 @@
 
 // pull in all the <= 5.0 tests
 #include "5.0/AudioPrimaryHidlHalTest.cpp"
+
+const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests() {
+    static std::vector<DeviceParameter> parameters = [] {
+        std::vector<DeviceParameter> result;
+        const auto factories =
+                ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+        for (const auto& factoryName : factories) {
+            result.emplace_back(factoryName,
+                                DeviceManager::getInstance().getPrimary(factoryName) != nullptr
+                                        ? DeviceManager::kPrimaryDevice
+                                        : "");
+        }
+        return result;
+    }();
+    return parameters;
+}
+
+const std::vector<DeviceParameter>& getDeviceParametersForPrimaryDeviceTests() {
+    static std::vector<DeviceParameter> parameters = [] {
+        std::vector<DeviceParameter> result;
+        const auto primary = std::find_if(
+                getDeviceParameters().begin(), getDeviceParameters().end(), [](const auto& elem) {
+                    return std::get<PARAM_DEVICE_NAME>(elem) == DeviceManager::kPrimaryDevice;
+                });
+        if (primary != getDeviceParameters().end()) result.push_back(*primary);
+        return result;
+    }();
+    return parameters;
+}
+
+const std::vector<DeviceParameter>& getDeviceParameters() {
+    static std::vector<DeviceParameter> parameters = [] {
+        std::vector<DeviceParameter> result;
+        const auto factories =
+                ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+        const auto devices = getCachedPolicyConfig().getModulesWithDevicesNames();
+        result.reserve(devices.size());
+        for (const auto& factoryName : factories) {
+            for (const auto& deviceName : devices) {
+                if (DeviceManager::getInstance().get(factoryName, deviceName) != nullptr) {
+                    result.emplace_back(factoryName, deviceName);
+                }
+            }
+        }
+        return result;
+    }();
+    return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters = [] {
+        std::vector<DeviceConfigParameter> result;
+        for (const auto& device : getDeviceParameters()) {
+            auto module =
+                    getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+            for (const auto& ioProfile : module->getOutputProfiles()) {
+                for (const auto& profile : ioProfile->getAudioProfiles()) {
+                    const auto& channels = profile->getChannels();
+                    const auto& sampleRates = profile->getSampleRates();
+                    auto configs = ConfigHelper::combineAudioConfig(
+                            vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+                            vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+                            profile->getFormat());
+                    auto flags = ioProfile->getFlags();
+                    for (auto& config : configs) {
+                        // Some combinations of flags declared in the config file require special
+                        // treatment.
+                        bool special = false;
+                        if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
+                            config.offloadInfo.sampleRateHz = config.sampleRateHz;
+                            config.offloadInfo.channelMask = config.channelMask;
+                            config.offloadInfo.format = config.format;
+                            config.offloadInfo.streamType = AudioStreamType::MUSIC;
+                            config.offloadInfo.bitRatePerSecond = 320;
+                            config.offloadInfo.durationMicroseconds = -1;
+                            config.offloadInfo.bitWidth = 16;
+                            config.offloadInfo.bufferSize = 256;  // arbitrary value
+                            config.offloadInfo.usage = AudioUsage::MEDIA;
+                            result.emplace_back(
+                                    device, config,
+                                    AudioOutputFlag(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
+                            special = true;
+                        }
+                        if ((flags & AUDIO_OUTPUT_FLAG_DIRECT) &&
+                            !(flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC)) {
+                            result.emplace_back(device, config,
+                                                AudioOutputFlag(AUDIO_OUTPUT_FLAG_DIRECT));
+                            special = true;
+                        }
+                        if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {  // ignore the flag
+                            flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
+                        }
+                        if (!special) {
+                            result.emplace_back(device, config, AudioOutputFlag(flags));
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }();
+    return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters = [] {
+        std::vector<DeviceConfigParameter> result;
+        for (const auto& device : getDeviceParameters()) {
+            auto module =
+                    getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+            for (const auto& ioProfile : module->getInputProfiles()) {
+                for (const auto& profile : ioProfile->getAudioProfiles()) {
+                    const auto& channels = profile->getChannels();
+                    const auto& sampleRates = profile->getSampleRates();
+                    auto configs = ConfigHelper::combineAudioConfig(
+                            vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+                            vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+                            profile->getFormat());
+                    for (const auto& config : configs) {
+                        result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
+                    }
+                }
+            }
+        }
+        return result;
+    }();
+    return parameters;
+}
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index e59ab98..468f9b2 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -24,7 +24,9 @@
 #include <limits>
 #include <list>
 #include <map>
+#include <set>
 #include <string>
+#include <variant>
 #include <vector>
 
 #include <fcntl.h>
@@ -96,7 +98,9 @@
 using ::android::hardware::MessageQueue;
 using ::android::hardware::MQDescriptorSync;
 using ::android::hardware::Return;
+using ::android::hardware::audio::common::utils::EnumBitfield;
 using ::android::hardware::audio::common::utils::mkEnumBitfield;
+using ::android::hardware::details::toHexString;
 
 using namespace ::android::hardware::audio::common::CPP_VERSION;
 using namespace ::android::hardware::audio::common::test::utility;
@@ -129,11 +133,31 @@
 #include "DeviceManager.h"
 
 #if MAJOR_VERSION <= 5
-class HidlTest : public ::testing::VtsHalHidlTargetTestBase {
+using HidlTestBase = ::testing::VtsHalHidlTargetTestBase;
 #elif MAJOR_VERSION >= 6
-class HidlTest : public ::testing::Test {
+using HidlTestBase = ::testing::Test;
 #endif
+
+class HidlTest : public HidlTestBase {
+  public:
+    virtual ~HidlTest() = default;
+
   protected:
+    // Factory and device name getters to be overridden in subclasses.
+    virtual const std::string& getFactoryName() const = 0;
+    virtual const std::string& getDeviceName() const = 0;
+
+    sp<IDevicesFactory> getDevicesFactory() const {
+        return DevicesFactoryManager::getInstance().get(getFactoryName());
+    }
+    sp<IDevice> getDevice() const {
+        return DeviceManager::getInstance().get(getFactoryName(), getDeviceName());
+    }
+    bool resetDevice() const {
+        return DeviceManager::getInstance().reset(getFactoryName(), getDeviceName());
+    }
+    bool areAudioPatchesSupported() { return extract(getDevice()->supportsAudioPatches()); }
+
     // Convenient member to store results
     Result res;
 };
@@ -179,7 +203,25 @@
         }
         mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
         if (mStatus == OK) {
-            mPrimaryModule = getHwModules().getModuleFromName("primary");
+            mPrimaryModule = getHwModules().getModuleFromName(DeviceManager::kPrimaryDevice);
+            // Available devices are not 'attached' to modules at this moment.
+            // Need to go over available devices and find their module.
+            for (const auto& device : availableOutputDevices) {
+                for (const auto& module : hwModules) {
+                    if (module->getDeclaredDevices().indexOf(device) >= 0) {
+                        mModulesWithDevicesNames.insert(module->getName());
+                        break;
+                    }
+                }
+            }
+            for (const auto& device : availableInputDevices) {
+                for (const auto& module : hwModules) {
+                    if (module->getDeclaredDevices().indexOf(device) >= 0) {
+                        mModulesWithDevicesNames.insert(module->getName());
+                        break;
+                    }
+                }
+            }
         }
     }
     status_t getStatus() const { return mStatus; }
@@ -192,12 +234,19 @@
         }
     }
     const std::string& getFilePath() const { return mFilePath; }
+    sp<const HwModule> getModuleFromName(const std::string& name) const {
+        return getHwModules().getModuleFromName(name.c_str());
+    }
     sp<const HwModule> getPrimaryModule() const { return mPrimaryModule; }
+    const std::set<std::string>& getModulesWithDevicesNames() const {
+        return mModulesWithDevicesNames;
+    }
 
    private:
     status_t mStatus = NO_INIT;
     std::string mFilePath;
     sp<HwModule> mPrimaryModule = nullptr;
+    std::set<std::string> mModulesWithDevicesNames;
 };
 
 // Cached policy config after parsing for faster test startup
@@ -210,40 +259,26 @@
     return *policyConfig;
 }
 
-class AudioPolicyConfigTest : public HidlTest {
-   public:
+class AudioPolicyConfigTest : public HidlTestBase {
+  public:
     void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp());  // setup base
-
+        ASSERT_NO_FATAL_FAILURE(HidlTestBase::SetUp());  // setup base
         auto& policyConfig = getCachedPolicyConfig();
         ASSERT_EQ(0, policyConfig.getStatus()) << policyConfig.getError();
-
-        mPrimaryConfig = policyConfig.getPrimaryModule();
-        ASSERT_TRUE(mPrimaryConfig) << "Could not find primary module in configuration file: "
-                                    << policyConfig.getFilePath();
     }
-
-  protected:
-    sp<IDevicesFactory> getDevicesFactory(const std::string& factoryName) const {
-        return DevicesFactoryManager::getInstance().get(factoryName);
-    }
-
-    sp<IPrimaryDevice> getPrimaryDevice(const std::string& factoryName) const {
-        return DeviceManager::getInstance().getPrimary(factoryName);
-    }
-
-    bool isPrimaryDeviceOptional(const std::string& factoryName) const {
-        // It's OK not to have "primary" device on non-default audio HAL service.
-        return factoryName != kDefaultServiceName;
-    }
-
-    sp<const HwModule> mPrimaryConfig = nullptr;
 };
 
 TEST_F(AudioPolicyConfigTest, LoadAudioPolicyXMLConfiguration) {
     doc::test("Test parsing audio_policy_configuration.xml (called in SetUp)");
 }
 
+TEST_F(AudioPolicyConfigTest, HasPrimaryModule) {
+    auto& policyConfig = getCachedPolicyConfig();
+    ASSERT_TRUE(policyConfig.getPrimaryModule() != nullptr)
+            << "Could not find primary module in configuration file: "
+            << policyConfig.getFilePath();
+}
+
 //////////////////////////////////////////////////////////////////////////////
 //////////////////// Test parameter types and definitions ////////////////////
 //////////////////////////////////////////////////////////////////////////////
@@ -253,13 +288,13 @@
 
 static inline std::string DeviceParameterToString(
         const ::testing::TestParamInfo<DeviceParameter>& info) {
+    const auto& deviceName = std::get<PARAM_DEVICE_NAME>(info.param);
 #if MAJOR_VERSION <= 5
-    return std::get<PARAM_DEVICE_NAME>(info.param);
+    return !deviceName.empty() ? deviceName : std::to_string(info.index);
 #elif MAJOR_VERSION >= 6
     const auto factoryName =
             ::android::hardware::PrintInstanceNameToString(::testing::TestParamInfo<std::string>{
                     std::get<PARAM_FACTORY_NAME>(info.param), info.index});
-    const auto& deviceName = std::get<PARAM_DEVICE_NAME>(info.param);
     return !deviceName.empty() ? factoryName + "_" + deviceName : factoryName;
 #endif
 }
@@ -268,41 +303,48 @@
 // For V2..5 the factory is looked up using the instance name passed
 // in the environment, only one factory is returned. This is because the VTS
 // framework will call the test for each instance. Only the primary device of
-// the factory specified in the environment is tested.
-const std::vector<DeviceParameter>& getDeviceParameters() {
+// the default service factory can be tested.
+
+// Return a pair of <"default", "primary"> or <[non-default name], "">
+// This is used to parametrize device factory tests.
+// The device name is used to indicate whether IPrimaryDevice is required.
+const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests() {
     static std::vector<DeviceParameter> parameters = {
-            {environment->getServiceName<IDevicesFactory>(), DeviceManager::kPrimaryDevice}};
+            {environment->getServiceName<IDevicesFactory>(),
+             environment->getServiceName<IDevicesFactory>() == kDefaultServiceName
+                     ? DeviceManager::kPrimaryDevice
+                     : ""}};
     return parameters;
 }
+// Return a pair of <"default", "primary"> or nothing.
+// This is used to parametrize primary device tests.
+const std::vector<DeviceParameter>& getDeviceParametersForPrimaryDeviceTests() {
+    static std::vector<DeviceParameter> parameters =
+            !std::get<PARAM_DEVICE_NAME>(*getDeviceParametersForFactoryTests().begin()).empty()
+                    ? getDeviceParametersForFactoryTests()
+                    : std::vector<DeviceParameter>{};
+    return parameters;
+}
+// In V2..5 device tests must only test the primary device.
+// No device tests are executed for non-primary devices.
+const std::vector<DeviceParameter>& getDeviceParameters() {
+    return getDeviceParametersForPrimaryDeviceTests();
+}
 #elif MAJOR_VERSION >= 6
-// FIXME: Will be replaced with code that analyzes the audio policy config file.
-const std::vector<DeviceParameter>& getDeviceParameters() {
-    static std::vector<DeviceParameter> parameters = [] {
-        const auto instances =
-                ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
-        std::vector<DeviceParameter> result;
-        result.reserve(instances.size());
-        for (const auto& instance : instances) {
-            result.emplace_back(instance, DeviceManager::kPrimaryDevice);
-        }
-        return result;
-    }();
-    return parameters;
-}
+// For V6 and above these functions are implemented in 6.0/AudioPrimaryHidlHalTest.cpp
+const std::vector<DeviceParameter>& getDeviceParametersForFactoryTests();
+const std::vector<DeviceParameter>& getDeviceParametersForPrimaryDeviceTests();
+const std::vector<DeviceParameter>& getDeviceParameters();
 #endif
 
-class AudioHidlTestWithDeviceParameter : public AudioPolicyConfigTest,
+class AudioHidlTestWithDeviceParameter : public HidlTest,
                                          public ::testing::WithParamInterface<DeviceParameter> {
   protected:
-    const std::string& getFactoryName() const { return std::get<PARAM_FACTORY_NAME>(GetParam()); }
-    bool isPrimaryDeviceOptional() const {
-        return AudioPolicyConfigTest::isPrimaryDeviceOptional(getFactoryName());
+    const std::string& getFactoryName() const override {
+        return std::get<PARAM_FACTORY_NAME>(GetParam());
     }
-    sp<IDevicesFactory> getDevicesFactory() const {
-        return AudioPolicyConfigTest::getDevicesFactory(getFactoryName());
-    }
-    sp<IPrimaryDevice> getPrimaryDevice() const {
-        return AudioPolicyConfigTest::getPrimaryDevice(getFactoryName());
+    const std::string& getDeviceName() const override {
+        return std::get<PARAM_DEVICE_NAME>(GetParam());
     }
 };
 
@@ -310,7 +352,7 @@
 ////////////////////// getService audio_devices_factory //////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-// Test all audio devices
+// Test audio devices factory
 class AudioHidlTest : public AudioHidlTestWithDeviceParameter {
   public:
     void SetUp() override {
@@ -337,53 +379,75 @@
     ASSERT_TRUE(device == nullptr);
 }
 
-INSTANTIATE_TEST_CASE_P(AudioHidl, AudioHidlTest, ::testing::ValuesIn(getDeviceParameters()),
+INSTANTIATE_TEST_CASE_P(AudioHidl, AudioHidlTest,
+                        ::testing::ValuesIn(getDeviceParametersForFactoryTests()),
                         &DeviceParameterToString);
 
 //////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// openDevice ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+// Test all audio devices
+class AudioHidlDeviceTest : public AudioHidlTest {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp());  // setup base
+        ASSERT_TRUE(getDevice() != nullptr);
+    }
+};
+
+TEST_P(AudioHidlDeviceTest, OpenDevice) {
+    doc::test("Test openDevice (called during setup)");
+}
+
+TEST_P(AudioHidlDeviceTest, Init) {
+    doc::test("Test that the audio hal initialized correctly");
+    ASSERT_OK(getDevice()->initCheck());
+}
+
+INSTANTIATE_TEST_CASE_P(AudioHidlDevice, AudioHidlDeviceTest,
+                        ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
+
+//////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// openDevice primary ///////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
 // Test the primary device
-class AudioPrimaryHidlTest : public AudioHidlTest {
-   public:
+class AudioPrimaryHidlTest : public AudioHidlDeviceTest {
+  public:
     void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp());  // setup base
-        if (getDevice() == nullptr && isPrimaryDeviceOptional()) {
-            GTEST_SKIP() << "No primary device on this factory";
-        }
+        ASSERT_NO_FATAL_FAILURE(AudioHidlDeviceTest::SetUp());  // setup base
         ASSERT_TRUE(getDevice() != nullptr);
     }
 
-   protected:
-     sp<IPrimaryDevice> getDevice() const { return getPrimaryDevice(); }
+  protected:
+    sp<IPrimaryDevice> getDevice() const {
+        return DeviceManager::getInstance().getPrimary(getFactoryName());
+    }
 };
 
 TEST_P(AudioPrimaryHidlTest, OpenPrimaryDevice) {
-    doc::test("Test the openDevice (called during setup)");
-}
-
-TEST_P(AudioPrimaryHidlTest, Init) {
-    doc::test("Test that the audio primary hal initialized correctly");
-    ASSERT_OK(getDevice()->initCheck());
+    doc::test("Test openPrimaryDevice (called during setup)");
 }
 
 INSTANTIATE_TEST_CASE_P(AudioPrimaryHidl, AudioPrimaryHidlTest,
-                        ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
+                        ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                        &DeviceParameterToString);
 
 //////////////////////////////////////////////////////////////////////////////
 ///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-template <class Property>
-class AccessorPrimaryHidlTest : public AudioPrimaryHidlTest {
-   protected:
+template <class Property, class BaseTestClass = AudioHidlDeviceTest>
+class AccessorHidlTest : public BaseTestClass {
+  protected:
     enum Optionality { REQUIRED, OPTIONAL };
     struct Initial {  // Initial property value
         Initial(Property value, Optionality check = REQUIRED) : value(value), check(check) {}
         Property value;
         Optionality check;  // If this initial value should be checked
     };
+    using BaseTestClass::res;
     /** Test a property getter and setter.
      *  The getter and/or the setter may return NOT_SUPPORTED if optionality == OPTIONAL.
      */
@@ -395,7 +459,7 @@
                                       optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
 
         Property initialValue = expectedInitial.value;
-        ASSERT_OK((getDevice().get()->*getter)(returnIn(res, initialValue)));
+        ASSERT_OK((BaseTestClass::getDevice().get()->*getter)(returnIn(res, initialValue)));
         ASSERT_RESULT(expectedResults, res);
         if (res == Result::OK && expectedInitial.check == REQUIRED) {
             EXPECT_EQ(expectedInitial.value, initialValue);
@@ -406,7 +470,7 @@
         for (Property setValue : valuesToTest) {
             SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
                          testing::PrintToString(setValue));
-            auto ret = (getDevice().get()->*setter)(setValue);
+            auto ret = (BaseTestClass::getDevice().get()->*setter)(setValue);
             ASSERT_RESULT(expectedResults, ret);
             if (ret == Result::NOT_SUPPORTED) {
                 doc::partialTest(propertyName + " setter is not supported");
@@ -414,7 +478,7 @@
             }
             Property getValue;
             // Make sure the getter returns the same value just set
-            ASSERT_OK((getDevice().get()->*getter)(returnIn(res, getValue)));
+            ASSERT_OK((BaseTestClass::getDevice().get()->*getter)(returnIn(res, getValue)));
             ASSERT_RESULT(expectedResults, res);
             if (res == Result::NOT_SUPPORTED) {
                 doc::partialTest(propertyName + " getter is not supported");
@@ -426,34 +490,40 @@
         for (Property invalidValue : invalidValues) {
             SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
                          testing::PrintToString(invalidValue));
-            EXPECT_RESULT(invalidArgsOrNotSupported, (getDevice().get()->*setter)(invalidValue));
+            EXPECT_RESULT(invalidArgsOrNotSupported,
+                          (BaseTestClass::getDevice().get()->*setter)(invalidValue));
         }
 
         // Restore initial value
-        EXPECT_RESULT(expectedResults, (getDevice().get()->*setter)(initialValue));
+        EXPECT_RESULT(expectedResults, (BaseTestClass::getDevice().get()->*setter)(initialValue));
     }
 };
 
-using BoolAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<bool>;
+using BoolAccessorHidlTest = AccessorHidlTest<bool>;
+using BoolAccessorPrimaryHidlTest = AccessorHidlTest<bool, AudioPrimaryHidlTest>;
 
-TEST_P(BoolAccessorPrimaryHidlTest, MicMuteTest) {
+TEST_P(BoolAccessorHidlTest, MicMuteTest) {
     doc::test("Check that the mic can be muted and unmuted");
-    testAccessors("mic mute", Initial{false}, {true}, &IDevice::setMicMute, &IDevice::getMicMute);
+    testAccessors<OPTIONAL>("mic mute", Initial{false}, {true}, &IDevice::setMicMute,
+                            &IDevice::getMicMute);
     // TODO: check that the mic is really muted (all sample are 0)
 }
 
-TEST_P(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
+TEST_P(BoolAccessorHidlTest, MasterMuteTest) {
     doc::test("If master mute is supported, try to mute and unmute the master output");
     testAccessors<OPTIONAL>("master mute", Initial{false}, {true}, &IDevice::setMasterMute,
                             &IDevice::getMasterMute);
     // TODO: check that the master volume is really muted
 }
 
-INSTANTIATE_TEST_CASE_P(BoolAccessorPrimaryHidl, BoolAccessorPrimaryHidlTest,
+INSTANTIATE_TEST_CASE_P(BoolAccessorHidl, BoolAccessorHidlTest,
                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
+INSTANTIATE_TEST_CASE_P(BoolAccessorPrimaryHidl, BoolAccessorPrimaryHidlTest,
+                        ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                        &DeviceParameterToString);
 
-using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
-TEST_P(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
+using FloatAccessorHidlTest = AccessorHidlTest<float>;
+TEST_P(FloatAccessorHidlTest, MasterVolumeTest) {
     doc::test("Test the master volume if supported");
     testAccessors<OPTIONAL>(
         "master volume", Initial{1}, {0, 0.5}, &IDevice::setMasterVolume, &IDevice::getMasterVolume,
@@ -461,115 +531,53 @@
     // TODO: check that the master volume is really changed
 }
 
-INSTANTIATE_TEST_CASE_P(FloatAccessorPrimaryHidl, FloatAccessorPrimaryHidlTest,
+INSTANTIATE_TEST_CASE_P(FloatAccessorHidl, FloatAccessorHidlTest,
                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
 
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////// AudioPatches ////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-class AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest {
-   protected:
-     bool areAudioPatchesSupported() { return extract(getDevice()->supportsAudioPatches()); }
+class AudioPatchHidlTest : public AudioHidlDeviceTest {
+  public:
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(AudioHidlDeviceTest::SetUp());  // setup base
+        if (!areAudioPatchesSupported()) {
+            GTEST_SKIP() << "Audio patches are not supported";
+        }
+    }
 };
 
-TEST_P(AudioPatchPrimaryHidlTest, AudioPatches) {
+TEST_P(AudioPatchHidlTest, AudioPatches) {
     doc::test("Test if audio patches are supported");
-    if (!areAudioPatchesSupported()) {
-        doc::partialTest("Audio patches are not supported");
-        return;
-    }
     // TODO: test audio patches
 }
 
-INSTANTIATE_TEST_CASE_P(AudioPatchPrimaryHidl, AudioPatchPrimaryHidlTest,
+INSTANTIATE_TEST_CASE_P(AudioPatchHidl, AudioPatchHidlTest,
                         ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
 
-//////////////////////////////////////////////////////////////////////////////
-//////////////// Required and recommended audio format support ///////////////
-// From:
-// https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
-// From:
-// https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
-/////////// TODO: move to the beginning of the file for easier update ////////
-//////////////////////////////////////////////////////////////////////////////
-
-struct ConfigHelper {
-    // for retro compatibility only test the primary device IN_BUILTIN_MIC
-    // FIXME: in the next audio HAL version, test all available devices
-    static bool primaryHasMic() {
-        auto& policyConfig = getCachedPolicyConfig();
-        if (policyConfig.getStatus() != OK || policyConfig.getPrimaryModule() == nullptr) {
-            return true;  // Could not get the information, run all tests
-        }
-        auto getMic = [](auto& devs) { return devs.getDevice(
-                AUDIO_DEVICE_IN_BUILTIN_MIC, {}, AUDIO_FORMAT_DEFAULT); };
-        auto primaryMic = getMic(policyConfig.getPrimaryModule()->getDeclaredDevices());
-        auto availableMic = getMic(policyConfig.getAvailableInputDevices());
-
-        return primaryMic != nullptr && primaryMic->equals(availableMic);
-    }
-
-    // Cache result ?
-    static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
-        return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
-                                  {8000, 11025, 16000, 22050, 32000, 44100},
-                                  {AudioFormat::PCM_16_BIT});
-    }
-
-    static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
-        return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
-                                  {24000, 48000}, {AudioFormat::PCM_16_BIT});
-    }
-
-    static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
-        // TODO: retrieve audio config supported by the platform
-        // as declared in the policy configuration
-        return {};
-    }
-
-    static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
-        if (!primaryHasMic()) return {};
-        return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
-                                  {AudioFormat::PCM_16_BIT});
-    }
-    static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
-        if (!primaryHasMic()) return {};
-        return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
-                                  {AudioFormat::PCM_16_BIT});
-    }
-    static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
-        // TODO: retrieve audio config supported by the platform
-        // as declared in the policy configuration
-        return {};
-    }
-
-   private:
-    static const vector<AudioConfig> combineAudioConfig(vector<AudioChannelMask> channelMasks,
-                                                        vector<uint32_t> sampleRates,
-                                                        vector<AudioFormat> formats) {
-        vector<AudioConfig> configs;
-        for (auto channelMask : channelMasks) {
-            for (auto sampleRate : sampleRates) {
-                for (auto format : formats) {
-                    AudioConfig config{};
-                    // leave offloadInfo to 0
-                    config.channelMask = mkEnumBitfield(channelMask);
-                    config.sampleRateHz = sampleRate;
-                    config.format = format;
-                    // FIXME: leave frameCount to 0 ?
-                    configs.push_back(config);
-                }
-            }
-        }
-        return configs;
-    }
-};
-
 // Nesting a tuple in another tuple allows to use GTest Combine function to generate
 // all combinations of devices and configs.
-enum { PARAM_DEVICE, PARAM_CONFIG };
-using DeviceConfigParameter = std::tuple<DeviceParameter, AudioConfig>;
+enum { PARAM_DEVICE, PARAM_CONFIG, PARAM_FLAGS };
+enum { INDEX_INPUT, INDEX_OUTPUT };
+using DeviceConfigParameter =
+        std::tuple<DeviceParameter, AudioConfig, std::variant<AudioInputFlag, AudioOutputFlag>>;
+
+#if MAJOR_VERSION >= 6
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
+#endif
+
+#if MAJOR_VERSION >= 4
+static string SanitizeStringForGTestName(const string& s) {
+    string result = s;
+    for (size_t i = 0; i < result.size(); i++) {
+        // gtest test names must only contain alphanumeric characters
+        if (!std::isalnum(result[i])) result[i] = '_';
+    }
+    return result;
+}
+#endif
 
 /** Generate a test name based on an audio config.
  *
@@ -587,30 +595,71 @@
            ((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
              config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO))
                     ? "MONO"
-                    : ::testing::PrintToString(config.channelMask));
+#if MAJOR_VERSION == 2
+                    : ::testing::PrintToString(config.channelMask)
+#elif MAJOR_VERSION >= 4
+                    // In V4 and above the channel mask is a bitfield.
+                    // Printing its value using HIDL's toString for a bitfield emits a lot of extra
+                    // text due to overlapping constant values. Instead, we print the bitfield value
+                    // as if it was a single value + its hex representation
+                    : SanitizeStringForGTestName(
+                              ::testing::PrintToString(AudioChannelMask(config.channelMask)) + "_" +
+                              toHexString(config.channelMask))
+#endif
+                    ) +
+           "_" +
+#if MAJOR_VERSION == 2
+           std::visit([](auto&& arg) -> std::string { return ::testing::PrintToString(arg); },
+                      std::get<PARAM_FLAGS>(info.param));
+#elif MAJOR_VERSION >= 4
+           SanitizeStringForGTestName(std::visit(
+                   [](auto&& arg) -> std::string {
+                       using T = std::decay_t<decltype(arg)>;
+                       // Need to use FQN of toString to avoid confusing the compiler
+                       return ::android::hardware::audio::common::CPP_VERSION::toString<T>(
+                               hidl_bitfield<T>(arg));
+                   },
+                   std::get<PARAM_FLAGS>(info.param)));
+#endif
 }
 
 class AudioHidlTestWithDeviceConfigParameter
-    : public AudioPolicyConfigTest,
+    : public HidlTest,
       public ::testing::WithParamInterface<DeviceConfigParameter> {
   protected:
-    const std::string& getFactoryName() const {
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(HidlTest::SetUp());  // setup base
+        ASSERT_TRUE(getDevicesFactory() != nullptr);
+        ASSERT_TRUE(getDevice() != nullptr);
+    }
+    const std::string& getFactoryName() const override {
         return std::get<PARAM_FACTORY_NAME>(std::get<PARAM_DEVICE>(GetParam()));
     }
-    bool isPrimaryDeviceOptional() const {
-        return AudioPolicyConfigTest::isPrimaryDeviceOptional(getFactoryName());
-    }
-    sp<IDevicesFactory> getDevicesFactory() const {
-        return AudioPolicyConfigTest::getDevicesFactory(getFactoryName());
-    }
-    sp<IPrimaryDevice> getPrimaryDevice() const {
-        return AudioPolicyConfigTest::getPrimaryDevice(getFactoryName());
+    const std::string& getDeviceName() const override {
+        return std::get<PARAM_DEVICE_NAME>(std::get<PARAM_DEVICE>(GetParam()));
     }
     const AudioConfig& getConfig() const { return std::get<PARAM_CONFIG>(GetParam()); }
-    // FIXME: Split out tests that don't require primary device
-    sp<IPrimaryDevice> getDevice() const { return getPrimaryDevice(); }
+#if MAJOR_VERSION == 2
+    AudioInputFlag getInputFlags() const {
+        return std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam()));
+    }
+    AudioOutputFlag getOutputFlags() const {
+        return std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam()));
+    }
+#elif MAJOR_VERSION >= 4
+    hidl_bitfield<AudioInputFlag> getInputFlags() const {
+        return hidl_bitfield<AudioInputFlag>(
+                std::get<INDEX_INPUT>(std::get<PARAM_FLAGS>(GetParam())));
+    }
+    hidl_bitfield<AudioOutputFlag> getOutputFlags() const {
+        return hidl_bitfield<AudioOutputFlag>(
+                std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam())));
+    }
+#endif
 };
 
+#include "ConfigHelper.h"
+
 //////////////////////////////////////////////////////////////////////////////
 ///////////////////////////// getInputBufferSize /////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
@@ -619,17 +668,7 @@
 // android.hardware.microphone
 //        how to get this value ? is it a property ???
 
-class AudioCaptureConfigPrimaryTest : public AudioHidlTestWithDeviceConfigParameter {
-  public:
-    void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceConfigParameter::SetUp());  // setup base
-        ASSERT_TRUE(getDevicesFactory() != nullptr);
-        if (getDevice() == nullptr && isPrimaryDeviceOptional()) {
-            GTEST_SKIP() << "No primary device on this factory";
-        }
-        ASSERT_TRUE(getDevice() != nullptr);
-    }
-
+class AudioCaptureConfigTest : public AudioHidlTestWithDeviceConfigParameter {
   protected:
     void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
         uint64_t bufferSize;
@@ -652,46 +691,57 @@
 
 // Test that the required capture config and those declared in the policy are
 // indeed supported
-class RequiredInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
+class RequiredInputBufferSizeTest : public AudioCaptureConfigTest {};
 TEST_P(RequiredInputBufferSizeTest, RequiredInputBufferSizeTest) {
     doc::test(
         "Input buffer size must be retrievable for a format with required "
         "support.");
     inputBufferSizeTest(getConfig(), true);
 }
+
+// Test that the recommended capture config are supported or lead to a
+// INVALID_ARGUMENTS return
+class OptionalInputBufferSizeTest : public AudioCaptureConfigTest {};
+TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
+    doc::test(
+            "Input buffer size should be retrievable for a format with recommended "
+            "support.");
+    inputBufferSizeTest(getConfig(), false);
+}
+
+#if MAJOR_VERSION <= 5
+// For V2..5 test the primary device according to CDD requirements.
 INSTANTIATE_TEST_CASE_P(
         RequiredInputBufferSize, RequiredInputBufferSizeTest,
         ::testing::Combine(
-                ::testing::ValuesIn(getDeviceParameters()),
-                ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig())),
+                ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig()),
+                ::testing::Values(AudioInputFlag::NONE)),
         &DeviceConfigParameterToString);
 INSTANTIATE_TEST_CASE_P(
         SupportedInputBufferSize, RequiredInputBufferSizeTest,
         ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
-                           ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig())),
+                           ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig()),
+                           ::testing::Values(AudioInputFlag::NONE)),
         &DeviceConfigParameterToString);
-
-// Test that the recommended capture config are supported or lead to a
-// INVALID_ARGUMENTS return
-class OptionalInputBufferSizeTest : public AudioCaptureConfigPrimaryTest {};
-TEST_P(OptionalInputBufferSizeTest, OptionalInputBufferSizeTest) {
-    doc::test(
-        "Input buffer size should be retrievable for a format with recommended "
-        "support.");
-    inputBufferSizeTest(getConfig(), false);
-}
 INSTANTIATE_TEST_CASE_P(
         RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
         ::testing::Combine(
-                ::testing::ValuesIn(getDeviceParameters()),
-                ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig())),
+                ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig()),
+                ::testing::Values(AudioInputFlag::NONE)),
         &DeviceConfigParameterToString);
+#elif MAJOR_VERSION >= 6
+INSTANTIATE_TEST_CASE_P(SupportedInputBufferSize, RequiredInputBufferSizeTest,
+                        ::testing::ValuesIn(getInputDeviceConfigParameters()),
+                        &DeviceConfigParameterToString);
+#endif
 
 //////////////////////////////////////////////////////////////////////////////
 /////////////////////////////// setScreenState ///////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-TEST_P(AudioPrimaryHidlTest, setScreenState) {
+TEST_P(AudioHidlDeviceTest, setScreenState) {
     doc::test("Check that the hal can receive the screen state");
     for (bool turnedOn : {false, true, true, false, false}) {
         ASSERT_RESULT(okOrNotSupported, getDevice()->setScreenState(turnedOn));
@@ -702,15 +752,16 @@
 //////////////////////////// {get,set}Parameters /////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-TEST_P(AudioPrimaryHidlTest, getParameters) {
+TEST_P(AudioHidlDeviceTest, getParameters) {
     doc::test("Check that the hal can set and get parameters");
     hidl_vec<ParameterValue> context;
     hidl_vec<hidl_string> keys;
     hidl_vec<ParameterValue> values;
     ASSERT_OK(Parameters::get(getDevice(), keys, returnIn(res, values)));
-    ASSERT_OK(Parameters::set(getDevice(), values));
+    ASSERT_RESULT(okOrNotSupported, res);
+    ASSERT_RESULT(okOrNotSupported, Parameters::set(getDevice(), values));
     values.resize(0);
-    ASSERT_OK(Parameters::set(getDevice(), values));
+    ASSERT_RESULT(okOrNotSupported, Parameters::set(getDevice(), values));
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -751,12 +802,12 @@
     EXPECT_EQ(0, close(fds[1])) << errno;
 }
 
-TEST_P(AudioPrimaryHidlTest, DebugDump) {
+TEST_P(AudioHidlDeviceTest, DebugDump) {
     doc::test("Check that the hal can dump its state without error");
     testDebugDump([this](const auto& handle) { return dump(getDevice(), handle); });
 }
 
-TEST_P(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
+TEST_P(AudioHidlDeviceTest, DebugDumpInvalidArguments) {
     doc::test("Check that the hal dump doesn't crash on invalid arguments");
     ASSERT_OK(dump(getDevice(), hidl_handle()));
 }
@@ -768,15 +819,6 @@
 template <class Stream>
 class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
   protected:
-    void SetUp() override {
-        ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceConfigParameter::SetUp());  // setup base
-        ASSERT_TRUE(getDevicesFactory() != nullptr);
-        if (getDevice() == nullptr && isPrimaryDeviceOptional()) {
-            GTEST_SKIP() << "No primary device on this factory";
-        }
-        ASSERT_TRUE(getDevice() != nullptr);
-    }
-
     template <class Open>
     void testOpen(Open openStream, const AudioConfig& config) {
         // FIXME: Open a stream without an IOHandle
@@ -828,14 +870,12 @@
         usleep(100 * 1000);
     }
 
-    bool areAudioPatchesSupported() { return extract(getDevice()->supportsAudioPatches()); }
-
   private:
     void TearDown() override {
         if (open) {
             ASSERT_OK(closeStream());
         }
-        AudioPolicyConfigTest::TearDown();
+        AudioHidlTestWithDeviceConfigParameter::TearDown();
     }
 
    protected:
@@ -850,11 +890,9 @@
 class OutputStreamTest : public OpenStreamTest<IStreamOut> {
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
-        if (IsSkipped()) return;                           // do not attempt to use 'device'
         address.device = AudioDevice::OUT_DEFAULT;
         const AudioConfig& config = getConfig();
-        // TODO: test all flag combination
-        auto flags = mkEnumBitfield(AudioOutputFlag::NONE);
+        auto flags = getOutputFlags();
         testOpen(
                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
 #if MAJOR_VERSION == 2
@@ -881,35 +919,46 @@
         "recommended config");
     // Open done in SetUp
 }
+
+#if MAJOR_VERSION <= 5
+// For V2..5 test the primary device according to CDD requirements.
 INSTANTIATE_TEST_CASE_P(
         RequiredOutputStreamConfigSupport, OutputStreamTest,
         ::testing::Combine(
-                ::testing::ValuesIn(getDeviceParameters()),
-                ::testing::ValuesIn(ConfigHelper::getRequiredSupportPlaybackAudioConfig())),
+                ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                ::testing::ValuesIn(ConfigHelper::getRequiredSupportPlaybackAudioConfig()),
+                ::testing::Values(AudioOutputFlag::NONE)),
         &DeviceConfigParameterToString);
 INSTANTIATE_TEST_CASE_P(
         SupportedOutputStreamConfig, OutputStreamTest,
         ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
-                           ::testing::ValuesIn(ConfigHelper::getSupportedPlaybackAudioConfig())),
+                           ::testing::ValuesIn(ConfigHelper::getSupportedPlaybackAudioConfig()),
+                           ::testing::Values(AudioOutputFlag::NONE)),
         &DeviceConfigParameterToString);
-
 INSTANTIATE_TEST_CASE_P(
         RecommendedOutputStreamConfigSupport, OutputStreamTest,
         ::testing::Combine(
-                ::testing::ValuesIn(getDeviceParameters()),
-                ::testing::ValuesIn(ConfigHelper::getRecommendedSupportPlaybackAudioConfig())),
+                ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                ::testing::ValuesIn(ConfigHelper::getRecommendedSupportPlaybackAudioConfig()),
+                ::testing::Values(AudioOutputFlag::NONE)),
         &DeviceConfigParameterToString);
+#elif MAJOR_VERSION >= 6
+// For V6 and above test according to the audio policy manager configuration.
+// This is more correct as CDD is written from the apps perspective.
+// Audio system provides necessary format conversions for the missing configurations.
+INSTANTIATE_TEST_CASE_P(DeclaredOutputStreamConfigSupport, OutputStreamTest,
+                        ::testing::ValuesIn(getOutputDeviceConfigParameters()),
+                        &DeviceConfigParameterToString);
+#endif
 
 ////////////////////////////// openInputStream //////////////////////////////
 
 class InputStreamTest : public OpenStreamTest<IStreamIn> {
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp());  // setup base
-        if (IsSkipped()) return;                           // do not attempt to use 'device'
         address.device = AudioDevice::IN_DEFAULT;
         const AudioConfig& config = getConfig();
-        // TODO: test all supported flags and source
-        auto flags = mkEnumBitfield(AudioInputFlag::NONE);
+        auto flags = getInputFlags();
         testOpen(
                 [&](AudioIoHandle handle, AudioConfig config, auto cb) {
                     return getDevice()->openInputStream(handle, address, config, flags,
@@ -932,24 +981,36 @@
         "recommended config");
     // Open done in setup
 }
+#if MAJOR_VERSION <= 5
+// For V2..5 test the primary device according to CDD requirements.
 INSTANTIATE_TEST_CASE_P(
         RequiredInputStreamConfigSupport, InputStreamTest,
         ::testing::Combine(
-                ::testing::ValuesIn(getDeviceParameters()),
-                ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig())),
+                ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig()),
+                ::testing::Values(AudioInputFlag::NONE)),
         &DeviceConfigParameterToString);
 INSTANTIATE_TEST_CASE_P(
         SupportedInputStreamConfig, InputStreamTest,
         ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
-                           ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig())),
+                           ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig()),
+                           ::testing::Values(AudioInputFlag::NONE)),
         &DeviceConfigParameterToString);
-
 INSTANTIATE_TEST_CASE_P(
         RecommendedInputStreamConfigSupport, InputStreamTest,
         ::testing::Combine(
-                ::testing::ValuesIn(getDeviceParameters()),
-                ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig())),
+                ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig()),
+                ::testing::Values(AudioInputFlag::NONE)),
         &DeviceConfigParameterToString);
+#elif MAJOR_VERSION >= 6
+// For V6 and above test according to the audio policy manager configuration.
+// This is more correct as CDD is written from the apps perspective.
+// Audio system provides necessary format conversions for the missing configurations.
+INSTANTIATE_TEST_CASE_P(DeclaredInputStreamConfigSupport, InputStreamTest,
+                        ::testing::ValuesIn(getInputDeviceConfigParameters()),
+                        &DeviceConfigParameterToString);
+#endif
 
 //////////////////////////////////////////////////////////////////////////////
 ////////////////////////////// IStream getters ///////////////////////////////
@@ -1481,7 +1542,8 @@
                             &IPrimaryDevice::getBtScoWidebandEnabled);
 }
 
-using TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<IPrimaryDevice::TtyMode>;
+using TtyModeAccessorPrimaryHidlTest =
+        AccessorHidlTest<IPrimaryDevice::TtyMode, AudioPrimaryHidlTest>;
 TEST_P(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
     doc::test("Query and set the TTY mode state");
     testAccessors<OPTIONAL>(
@@ -1490,7 +1552,8 @@
         &IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
 }
 INSTANTIATE_TEST_CASE_P(TtyModeAccessorPrimaryHidl, TtyModeAccessorPrimaryHidlTest,
-                        ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
+                        ::testing::ValuesIn(getDeviceParametersForPrimaryDeviceTests()),
+                        &DeviceParameterToString);
 
 TEST_P(BoolAccessorPrimaryHidlTest, setGetHac) {
     doc::test("Query and set the HAC state");
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
new file mode 100644
index 0000000..48aae8c
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Code in this file uses 'getCachedPolicyConfig'
+#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
+#error Must be included from AudioPrimaryHidlTest.h
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////// Required and recommended audio format support ///////////////
+// From:
+// https://source.android.com/compatibility/android-cdd.html#5_4_audio_recording
+// From:
+// https://source.android.com/compatibility/android-cdd.html#5_5_audio_playback
+/////////// TODO: move to the beginning of the file for easier update ////////
+//////////////////////////////////////////////////////////////////////////////
+
+struct ConfigHelper {
+    // for retro compatibility only test the primary device IN_BUILTIN_MIC
+    // FIXME: in the next audio HAL version, test all available devices
+    static bool primaryHasMic() {
+        auto& policyConfig = getCachedPolicyConfig();
+        if (policyConfig.getStatus() != OK || policyConfig.getPrimaryModule() == nullptr) {
+            return true;  // Could not get the information, run all tests
+        }
+        auto getMic = [](auto& devs) {
+            return devs.getDevice(AUDIO_DEVICE_IN_BUILTIN_MIC, {}, AUDIO_FORMAT_DEFAULT);
+        };
+        auto primaryMic = getMic(policyConfig.getPrimaryModule()->getDeclaredDevices());
+        auto availableMic = getMic(policyConfig.getAvailableInputDevices());
+
+        return primaryMic != nullptr && primaryMic->equals(availableMic);
+    }
+
+    // Cache result ?
+    static const vector<AudioConfig> getRequiredSupportPlaybackAudioConfig() {
+        return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
+                                  {8000, 11025, 16000, 22050, 32000, 44100},
+                                  {AudioFormat::PCM_16_BIT});
+    }
+
+    static const vector<AudioConfig> getRecommendedSupportPlaybackAudioConfig() {
+        return combineAudioConfig({AudioChannelMask::OUT_STEREO, AudioChannelMask::OUT_MONO},
+                                  {24000, 48000}, {AudioFormat::PCM_16_BIT});
+    }
+
+    static const vector<AudioConfig> getSupportedPlaybackAudioConfig() {
+        // TODO: retrieve audio config supported by the platform
+        // as declared in the policy configuration
+        return {};
+    }
+
+    static const vector<AudioConfig> getRequiredSupportCaptureAudioConfig() {
+        if (!primaryHasMic()) return {};
+        return combineAudioConfig({AudioChannelMask::IN_MONO}, {8000, 11025, 16000, 44100},
+                                  {AudioFormat::PCM_16_BIT});
+    }
+    static const vector<AudioConfig> getRecommendedSupportCaptureAudioConfig() {
+        if (!primaryHasMic()) return {};
+        return combineAudioConfig({AudioChannelMask::IN_STEREO}, {22050, 48000},
+                                  {AudioFormat::PCM_16_BIT});
+    }
+    static const vector<AudioConfig> getSupportedCaptureAudioConfig() {
+        // TODO: retrieve audio config supported by the platform
+        // as declared in the policy configuration
+        return {};
+    }
+
+    static vector<AudioConfig> combineAudioConfig(vector<audio_channel_mask_t> channelMasks,
+                                                  vector<uint32_t> sampleRates,
+                                                  audio_format_t format) {
+        vector<AudioConfig> configs;
+        configs.reserve(channelMasks.size() * sampleRates.size());
+        for (auto channelMask : channelMasks) {
+            for (auto sampleRate : sampleRates) {
+                AudioConfig config{};
+                // leave offloadInfo to 0
+                config.channelMask = EnumBitfield<AudioChannelMask>(channelMask);
+                config.sampleRateHz = sampleRate;
+                config.format = AudioFormat(format);
+                configs.push_back(config);
+            }
+        }
+        return configs;
+    }
+
+    static vector<AudioConfig> combineAudioConfig(vector<AudioChannelMask> channelMasks,
+                                                  vector<uint32_t> sampleRates,
+                                                  vector<AudioFormat> formats) {
+        vector<AudioConfig> configs;
+        configs.reserve(channelMasks.size() * sampleRates.size() * formats.size());
+        for (auto channelMask : channelMasks) {
+            for (auto sampleRate : sampleRates) {
+                for (auto format : formats) {
+                    AudioConfig config{};
+                    // leave offloadInfo to 0
+                    config.channelMask = mkEnumBitfield(channelMask);
+                    config.sampleRateHz = sampleRate;
+                    config.format = format;
+                    // FIXME: leave frameCount to 0 ?
+                    configs.push_back(config);
+                }
+            }
+        }
+        return configs;
+    }
+};
diff --git a/automotive/can/1.0/Android.bp b/automotive/can/1.0/Android.bp
index fe2a2be..2221e66 100644
--- a/automotive/can/1.0/Android.bp
+++ b/automotive/can/1.0/Android.bp
@@ -10,6 +10,7 @@
         "types.hal",
         "ICanBus.hal",
         "ICanController.hal",
+        "ICanErrorListener.hal",
         "ICanMessageListener.hal",
         "ICloseHandle.hal",
     ],
diff --git a/automotive/can/1.0/ICanBus.hal b/automotive/can/1.0/ICanBus.hal
index 6ed89f3..e68f16c 100644
--- a/automotive/can/1.0/ICanBus.hal
+++ b/automotive/can/1.0/ICanBus.hal
@@ -15,6 +15,7 @@
  */
 package android.hardware.automotive.can@1.0;
 
+import ICanErrorListener;
 import ICanMessageListener;
 import ICloseHandle;
 
@@ -57,4 +58,15 @@
      */
     listen(vec<CanMessageFilter> filter, ICanMessageListener listener)
             generates (Result result, ICloseHandle close);
+
+    /**
+     * Adds a new listener for CAN bus or interface errors.
+     *
+     * If the error is fatal, the client is supposed to drop any references to
+     * this specific ICanBus instance (see ICanErrorListener).
+     *
+     * @param listener The interface to receive the error events on
+     * @return close A handle to call in order to remove the listener
+     */
+    listenForErrors(ICanErrorListener listener) generates (ICloseHandle close);
 };
diff --git a/automotive/can/1.0/ICanErrorListener.hal b/automotive/can/1.0/ICanErrorListener.hal
new file mode 100644
index 0000000..8a6ba05
--- /dev/null
+++ b/automotive/can/1.0/ICanErrorListener.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.automotive.can@1.0;
+
+/**
+ * CAN error listener.
+ */
+interface ICanErrorListener {
+    /**
+     * Called on error event.
+     *
+     * If the error is fatal, the client is supposed to drop any references to
+     * this specific ICanBus instance.
+     *
+     * @param error Error type
+     * @param isFatal Whether an error would result with ICanBus instance being unusable.
+     */
+    onError(ErrorEvent error, bool isFatal);
+};
diff --git a/automotive/can/1.0/ICanMessageListener.hal b/automotive/can/1.0/ICanMessageListener.hal
index 992d1c7..28161fa 100644
--- a/automotive/can/1.0/ICanMessageListener.hal
+++ b/automotive/can/1.0/ICanMessageListener.hal
@@ -30,11 +30,4 @@
      * @param message Received CAN message
      */
     onReceive(CanMessage message);
-
-    /**
-     * Called on error event.
-     *
-     * @param error Error type
-     */
-    onError(ErrorEvent error);
 };
diff --git a/automotive/can/1.0/default/CanBus.cpp b/automotive/can/1.0/default/CanBus.cpp
index 65da291..38a9974 100644
--- a/automotive/can/1.0/default/CanBus.cpp
+++ b/automotive/can/1.0/default/CanBus.cpp
@@ -68,14 +68,14 @@
         return {};
     }
 
-    std::lock_guard<std::mutex> lckListeners(mListenersGuard);
+    std::lock_guard<std::mutex> lckListeners(mMsgListenersGuard);
 
     sp<CloseHandle> closeHandle = new CloseHandle([this, listenerCb]() {
-        std::lock_guard<std::mutex> lck(mListenersGuard);
-        std::erase_if(mListeners, [&](const auto& e) { return e.callback == listenerCb; });
+        std::lock_guard<std::mutex> lck(mMsgListenersGuard);
+        std::erase_if(mMsgListeners, [&](const auto& e) { return e.callback == listenerCb; });
     });
-    mListeners.emplace_back(CanMessageListener{listenerCb, filter, closeHandle});
-    auto& listener = mListeners.back();
+    mMsgListeners.emplace_back(CanMessageListener{listenerCb, filter, closeHandle});
+    auto& listener = mMsgListeners.back();
 
     // fix message IDs to have all zeros on bits not covered by mask
     std::for_each(listener.filter.begin(), listener.filter.end(),
@@ -91,8 +91,15 @@
     std::lock_guard<std::mutex> lck(mIsUpGuard);
     CHECK(!mIsUp) << "Interface is still up while being destroyed";
 
-    std::lock_guard<std::mutex> lckListeners(mListenersGuard);
-    CHECK(mListeners.empty()) << "Listeners list is not empty while interface is being destroyed";
+    std::lock_guard<std::mutex> lckListeners(mMsgListenersGuard);
+    CHECK(mMsgListeners.empty()) << "Listener list is not empty while interface is being destroyed";
+}
+
+void CanBus::setErrorCallback(ErrorCallback errcb) {
+    CHECK(!mIsUp) << "Can't set error callback while interface is up";
+    CHECK(mErrCb == nullptr) << "Error callback is already set";
+    mErrCb = errcb;
+    CHECK(!mIsUp) << "Can't set error callback while interface is up";
 }
 
 ICanController::Result CanBus::preUp() {
@@ -120,19 +127,19 @@
         LOG(ERROR) << "Interface " << mIfname << " didn't get prepared";
         return ICanController::Result::BAD_ADDRESS;
     }
-    mWasUpInitially = *isUp;
 
-    if (!mWasUpInitially && !netdevice::up(mIfname)) {
+    if (!*isUp && !netdevice::up(mIfname)) {
         LOG(ERROR) << "Can't bring " << mIfname << " up";
         return ICanController::Result::UNKNOWN_ERROR;
     }
+    mDownAfterUse = !*isUp;
 
     using namespace std::placeholders;
     CanSocket::ReadCallback rdcb = std::bind(&CanBus::onRead, this, _1, _2);
-    CanSocket::ErrorCallback errcb = std::bind(&CanBus::onError, this);
+    CanSocket::ErrorCallback errcb = std::bind(&CanBus::onError, this, _1);
     mSocket = CanSocket::open(mIfname, rdcb, errcb);
     if (!mSocket) {
-        if (!mWasUpInitially) netdevice::down(mIfname);
+        if (mDownAfterUse) netdevice::down(mIfname);
         return ICanController::Result::UNKNOWN_ERROR;
     }
 
@@ -140,24 +147,50 @@
     return ICanController::Result::OK;
 }
 
-void CanBus::clearListeners() {
+void CanBus::clearMsgListeners() {
     std::vector<wp<ICloseHandle>> listenersToClose;
     {
-        std::lock_guard<std::mutex> lck(mListenersGuard);
-        std::transform(mListeners.begin(), mListeners.end(), std::back_inserter(listenersToClose),
+        std::lock_guard<std::mutex> lck(mMsgListenersGuard);
+        std::transform(mMsgListeners.begin(), mMsgListeners.end(),
+                       std::back_inserter(listenersToClose),
                        [](const auto& e) { return e.closeHandle; });
     }
 
     for (auto& weakListener : listenersToClose) {
         /* Between populating listenersToClose and calling close method here, some listeners might
-         * have been already removed from the original mListeners list (resulting in a dangling weak
-         * pointer here). It's fine - we just want to clean them up. */
+         * have been already removed from the original mMsgListeners list (resulting in a dangling
+         * weak pointer here). It's fine - we just want to clean them up. */
         auto listener = weakListener.promote();
         if (listener != nullptr) listener->close();
     }
 
-    std::lock_guard<std::mutex> lck(mListenersGuard);
-    CHECK(mListeners.empty()) << "Listeners list wasn't emptied";
+    std::lock_guard<std::mutex> lck(mMsgListenersGuard);
+    CHECK(mMsgListeners.empty()) << "Listeners list wasn't emptied";
+}
+
+void CanBus::clearErrListeners() {
+    std::lock_guard<std::mutex> lck(mErrListenersGuard);
+    mErrListeners.clear();
+}
+
+Return<sp<ICloseHandle>> CanBus::listenForErrors(const sp<ICanErrorListener>& listener) {
+    if (listener == nullptr) {
+        return new CloseHandle();
+    }
+
+    std::lock_guard<std::mutex> upLck(mIsUpGuard);
+    if (!mIsUp) {
+        listener->onError(ErrorEvent::INTERFACE_DOWN, true);
+        return new CloseHandle();
+    }
+
+    std::lock_guard<std::mutex> errLck(mErrListenersGuard);
+    mErrListeners.emplace_back(listener);
+
+    return new CloseHandle([this, listener]() {
+        std::lock_guard<std::mutex> lck(mErrListenersGuard);
+        std::erase(mErrListeners, listener);
+    });
 }
 
 bool CanBus::down() {
@@ -169,12 +202,13 @@
     }
     mIsUp = false;
 
-    clearListeners();
+    clearMsgListeners();
+    clearErrListeners();
     mSocket.reset();
 
     bool success = true;
 
-    if (!mWasUpInitially && !netdevice::down(mIfname)) {
+    if (mDownAfterUse && !netdevice::down(mIfname)) {
         LOG(ERROR) << "Can't bring " << mIfname << " down";
         // don't return yet, let's try to do best-effort cleanup
         success = false;
@@ -223,22 +257,35 @@
         LOG(VERBOSE) << "Got message " << toString(message);
     }
 
-    std::lock_guard<std::mutex> lck(mListenersGuard);
-    for (auto& listener : mListeners) {
+    std::lock_guard<std::mutex> lck(mMsgListenersGuard);
+    for (auto& listener : mMsgListeners) {
         if (!match(listener.filter, message.id)) continue;
-        if (!listener.callback->onReceive(message).isOk()) {
+        if (!listener.callback->onReceive(message).isOk() && !listener.failedOnce) {
+            listener.failedOnce = true;
             LOG(WARNING) << "Failed to notify listener about message";
         }
     }
 }
 
-void CanBus::onError() {
-    std::lock_guard<std::mutex> lck(mListenersGuard);
-    for (auto& listener : mListeners) {
-        if (!listener.callback->onError(ErrorEvent::HARDWARE_ERROR).isOk()) {
-            LOG(WARNING) << "Failed to notify listener about error";
+void CanBus::onError(int errnoVal) {
+    auto eventType = ErrorEvent::HARDWARE_ERROR;
+
+    if (errnoVal == ENODEV || errnoVal == ENETDOWN) {
+        mDownAfterUse = false;
+        eventType = ErrorEvent::INTERFACE_DOWN;
+    }
+
+    {
+        std::lock_guard<std::mutex> lck(mErrListenersGuard);
+        for (auto& listener : mErrListeners) {
+            if (!listener->onError(eventType, true).isOk()) {
+                LOG(WARNING) << "Failed to notify listener about error";
+            }
         }
     }
+
+    const auto errcb = mErrCb;
+    if (errcb != nullptr) errcb();
 }
 
 }  // namespace implementation
diff --git a/automotive/can/1.0/default/CanBus.h b/automotive/can/1.0/default/CanBus.h
index 81a83c8..30a2924 100644
--- a/automotive/can/1.0/default/CanBus.h
+++ b/automotive/can/1.0/default/CanBus.h
@@ -34,12 +34,16 @@
 namespace implementation {
 
 struct CanBus : public ICanBus {
+    using ErrorCallback = std::function<void()>;
+
     virtual ~CanBus();
 
     Return<Result> send(const CanMessage& message) override;
     Return<void> listen(const hidl_vec<CanMessageFilter>& filter,
                         const sp<ICanMessageListener>& listener, listen_cb _hidl_cb) override;
+    Return<sp<ICloseHandle>> listenForErrors(const sp<ICanErrorListener>& listener) override;
 
+    void setErrorCallback(ErrorCallback errcb);
     ICanController::Result up();
     bool down();
 
@@ -68,17 +72,22 @@
         sp<ICanMessageListener> callback;
         hidl_vec<CanMessageFilter> filter;
         wp<ICloseHandle> closeHandle;
+        bool failedOnce = false;
     };
-    void clearListeners();
+    void clearMsgListeners();
+    void clearErrListeners();
 
     void onRead(const struct canfd_frame& frame, std::chrono::nanoseconds timestamp);
-    void onError();
+    void onError(int errnoVal);
 
-    std::mutex mListenersGuard;
-    std::vector<CanMessageListener> mListeners GUARDED_BY(mListenersGuard);
+    std::mutex mMsgListenersGuard;
+    std::vector<CanMessageListener> mMsgListeners GUARDED_BY(mMsgListenersGuard);
+
+    std::mutex mErrListenersGuard;
+    std::vector<sp<ICanErrorListener>> mErrListeners GUARDED_BY(mErrListenersGuard);
 
     std::unique_ptr<CanSocket> mSocket;
-    bool mWasUpInitially;
+    bool mDownAfterUse;
 
     /**
      * Guard for up flag is required to be held for entire time when the interface is being used
@@ -87,6 +96,8 @@
      */
     std::mutex mIsUpGuard;
     bool mIsUp GUARDED_BY(mIsUpGuard) = false;
+
+    ErrorCallback mErrCb;
 };
 
 }  // namespace implementation
diff --git a/automotive/can/1.0/default/CanController.cpp b/automotive/can/1.0/default/CanController.cpp
index 20adbe1..3b63fe4 100644
--- a/automotive/can/1.0/default/CanController.cpp
+++ b/automotive/can/1.0/default/CanController.cpp
@@ -81,6 +81,8 @@
         return ICanController::Result::NOT_SUPPORTED;
     }
 
+    busService->setErrorCallback([this, name = config.name]() { downInterface(name); });
+
     const auto result = busService->up();
     if (result != ICanController::Result::OK) return result;
 
@@ -97,6 +99,14 @@
     return ICanController::Result::OK;
 }
 
+static bool unregisterCanBusService(const hidl_string& name, sp<CanBus> busService) {
+    auto manager = hidl::manager::V1_2::IServiceManager::getService();
+    if (!manager) return false;
+    const auto res = manager->tryUnregister(ICanBus::descriptor, name, busService);
+    if (!res.isOk()) return false;
+    return res;
+}
+
 Return<bool> CanController::downInterface(const hidl_string& name) {
     LOG(VERBOSE) << "Attempting to bring interface down: " << name;
 
@@ -110,8 +120,7 @@
 
     auto success = true;
 
-    auto manager = hidl::manager::V1_2::IServiceManager::getService();
-    if (!manager || !manager->tryUnregister(ICanBus::descriptor, name, busEntry.mapped())) {
+    if (!unregisterCanBusService(name, busEntry.mapped())) {
         LOG(ERROR) << "Couldn't unregister " << name;
         // don't return yet, let's try to do best-effort cleanup
         success = false;
diff --git a/automotive/can/1.0/default/CanSocket.cpp b/automotive/can/1.0/default/CanSocket.cpp
index 4d86de6..ecf4044 100644
--- a/automotive/can/1.0/default/CanSocket.cpp
+++ b/automotive/can/1.0/default/CanSocket.cpp
@@ -61,7 +61,14 @@
 
 CanSocket::~CanSocket() {
     mStopReaderThread = true;
-    mReaderThread.join();
+
+    /* CanSocket can be brought down as a result of read failure, from the same thread,
+     * so let's just detach and let it finish on its own. */
+    if (mReaderThreadFinished) {
+        mReaderThread.detach();
+    } else {
+        mReaderThread.join();
+    }
 }
 
 bool CanSocket::send(const struct canfd_frame& frame) {
@@ -94,6 +101,7 @@
 
 void CanSocket::readerThread() {
     LOG(VERBOSE) << "Reader thread started";
+    int errnoCopy = 0;
 
     while (!mStopReaderThread) {
         /* The ideal would be to have a blocking read(3) call and interrupt it with shutdown(3).
@@ -130,14 +138,20 @@
             }
             if (errno == EAGAIN) continue;
 
-            LOG(ERROR) << "Failed to read CAN packet: " << errno;
+            errnoCopy = errno;
+            LOG(ERROR) << "Failed to read CAN packet: " << strerror(errno) << " (" << errno << ")";
             break;
         }
 
         mReadCallback(frame, ts);
     }
 
-    if (!mStopReaderThread) mErrorCallback();
+    bool failed = !mStopReaderThread;
+    auto errCb = mErrorCallback;
+    mReaderThreadFinished = true;
+
+    // Don't access any fields from here, see CanSocket::~CanSocket comment about detached thread
+    if (failed) errCb(errnoCopy);
 
     LOG(VERBOSE) << "Reader thread stopped";
 }
diff --git a/automotive/can/1.0/default/CanSocket.h b/automotive/can/1.0/default/CanSocket.h
index cd7162d..284e1ea 100644
--- a/automotive/can/1.0/default/CanSocket.h
+++ b/automotive/can/1.0/default/CanSocket.h
@@ -36,7 +36,7 @@
  */
 struct CanSocket {
     using ReadCallback = std::function<void(const struct canfd_frame&, std::chrono::nanoseconds)>;
-    using ErrorCallback = std::function<void()>;
+    using ErrorCallback = std::function<void(int errnoVal)>;
 
     /**
      * Open and bind SocketCAN socket.
@@ -68,6 +68,7 @@
     const base::unique_fd mSocket;
     std::thread mReaderThread;
     std::atomic<bool> mStopReaderThread = false;
+    std::atomic<bool> mReaderThreadFinished = false;
 
     DISALLOW_COPY_AND_ASSIGN(CanSocket);
 };
diff --git a/automotive/can/1.0/default/CloseHandle.cpp b/automotive/can/1.0/default/CloseHandle.cpp
index 13693d2..aba2c49 100644
--- a/automotive/can/1.0/default/CloseHandle.cpp
+++ b/automotive/can/1.0/default/CloseHandle.cpp
@@ -33,7 +33,7 @@
     const auto wasClosed = mIsClosed.exchange(true);
     if (wasClosed) return {};
 
-    mCallback();
+    if (mCallback != nullptr) mCallback();
     return {};
 }
 
diff --git a/automotive/can/1.0/default/CloseHandle.h b/automotive/can/1.0/default/CloseHandle.h
index 94972e0..5191739 100644
--- a/automotive/can/1.0/default/CloseHandle.h
+++ b/automotive/can/1.0/default/CloseHandle.h
@@ -39,13 +39,13 @@
      *
      * \param callback Called on the first close() call, or on destruction of the handle
      */
-    CloseHandle(Callback callback);
+    CloseHandle(Callback callback = nullptr);
     virtual ~CloseHandle();
 
     Return<void> close() override;
 
   private:
-    Callback mCallback;
+    const Callback mCallback;
     std::atomic<bool> mIsClosed = false;
 
     DISALLOW_COPY_AND_ASSIGN(CloseHandle);
diff --git a/automotive/can/1.0/hidl-utils/Android.bp b/automotive/can/1.0/hidl-utils/Android.bp
index bc8ff13..63b07c9 100644
--- a/automotive/can/1.0/hidl-utils/Android.bp
+++ b/automotive/can/1.0/hidl-utils/Android.bp
@@ -17,4 +17,5 @@
 cc_library_headers {
     name: "android.hardware.automotive.can@hidl-utils-lib",
     export_include_dirs: ["include"],
+    vendor_available: true,
 }
diff --git a/automotive/can/1.0/types.hal b/automotive/can/1.0/types.hal
index 37877c6..6f690f7 100644
--- a/automotive/can/1.0/types.hal
+++ b/automotive/can/1.0/types.hal
@@ -95,6 +95,9 @@
     /** A problem with CAN interface HW. */
     HARDWARE_ERROR,
 
+    /** CAN interface is down. */
+    INTERFACE_DOWN,
+
     /** TX buffer overflow: client is sending too many packets. */
     TX_OVERFLOW,
 
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
index 215328e..1a05716 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusV1_0TargetTest.cpp
@@ -36,8 +36,11 @@
 static utils::SimpleHidlEnvironment<ICanBus>* gEnv = nullptr;
 
 struct CanMessageListener : public can::V1_0::ICanMessageListener {
-    virtual Return<void> onReceive(const can::V1_0::CanMessage&) { return {}; }
-    virtual Return<void> onError(can::V1_0::ErrorEvent) { return {}; }
+    virtual Return<void> onReceive(const can::V1_0::CanMessage&) override { return {}; }
+};
+
+struct CanErrorListener : public can::V1_0::ICanErrorListener {
+    virtual Return<void> onError(ErrorEvent, bool) override { return {}; }
 };
 
 class CanBusHalTest : public ::testing::VtsHalHidlTargetTestBase {
@@ -47,6 +50,7 @@
 
     std::tuple<Result, sp<ICloseHandle>> listen(const hidl_vec<CanMessageFilter>& filter,
                                                 const sp<ICanMessageListener>& listener);
+    sp<ICloseHandle> listenForErrors(const sp<ICanErrorListener>& listener);
 
     sp<ICanBus> mCanBus;
 };
@@ -70,6 +74,12 @@
     return {halResult, closeHandle};
 }
 
+sp<ICloseHandle> CanBusHalTest::listenForErrors(const sp<ICanErrorListener>& listener) {
+    const auto res = mCanBus->listenForErrors(listener);
+    res.assertOk();
+    return res;
+}
+
 TEST_F(CanBusHalTest, SendNoPayload) {
     CanMessage msg = {};
     msg.id = 0x123;
@@ -129,7 +139,7 @@
     ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
 }
 
-TEST_F(CanBusHalTest, DoubleCloseListen) {
+TEST_F(CanBusHalTest, DoubleCloseListener) {
     const auto [result, closeHandle] = listen({}, new CanMessageListener());
     ASSERT_EQ(Result::OK, result);
 
@@ -137,11 +147,32 @@
     closeHandle->close().assertOk();
 }
 
-TEST_F(CanBusHalTest, DontCloseListen) {
+TEST_F(CanBusHalTest, DontCloseListener) {
     const auto [result, closeHandle] = listen({}, new CanMessageListener());
     ASSERT_EQ(Result::OK, result);
 }
 
+TEST_F(CanBusHalTest, DoubleCloseErrorListener) {
+    auto closeHandle = listenForErrors(new CanErrorListener());
+    ASSERT_NE(nullptr, closeHandle.get());
+
+    closeHandle->close().assertOk();
+    closeHandle->close().assertOk();
+}
+
+TEST_F(CanBusHalTest, DoubleCloseNullErrorListener) {
+    auto closeHandle = listenForErrors(nullptr);
+    ASSERT_NE(nullptr, closeHandle.get());
+
+    closeHandle->close().assertOk();
+    closeHandle->close().assertOk();
+}
+
+TEST_F(CanBusHalTest, DontCloseErrorListener) {
+    auto closeHandle = listenForErrors(new CanErrorListener());
+    ASSERT_NE(nullptr, closeHandle.get());
+}
+
 }  // namespace vts
 }  // namespace V1_0
 }  // namespace can
diff --git a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
index 699c138..ba29c29 100644
--- a/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
+++ b/automotive/can/1.0/vts/functional/VtsHalCanBusVirtualV1_0TargetTest.cpp
@@ -50,18 +50,13 @@
 
     CanMessageListener() {}
 
-    virtual Return<void> onReceive(const can::V1_0::CanMessage& msg) {
+    virtual Return<void> onReceive(const can::V1_0::CanMessage& msg) override {
         std::unique_lock<std::mutex> lk(mMessagesGuard);
         mMessages.push_back(msg);
         mMessagesUpdated.notify_one();
         return {};
     }
 
-    virtual Return<void> onError(can::V1_0::ErrorEvent event) {
-        EXPECT_TRUE(false) << "Got error: " << event;
-        return {};
-    }
-
     virtual ~CanMessageListener() { mCloseHandle->close(); }
 
     void assignCloseHandle(sp<ICloseHandle> closeHandle) {
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 3fd0539..ed09859 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -71,10 +71,10 @@
     whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
     shared_libs: [
         "libbase",
+        "libjsoncpp",
         "libprotobuf-cpp-lite",
     ],
     static_libs: [
-        "libjsoncpp",
         "libqemu_pipe",
         "android.hardware.automotive.vehicle@2.0-libproto-native",
     ],
@@ -106,13 +106,13 @@
     srcs: ["VehicleService.cpp"],
     shared_libs: [
         "libbase",
+        "libjsoncpp",
         "libprotobuf-cpp-lite",
     ],
     static_libs: [
         "android.hardware.automotive.vehicle@2.0-manager-lib",
         "android.hardware.automotive.vehicle@2.0-default-impl-lib",
         "android.hardware.automotive.vehicle@2.0-libproto-native",
-        "libjsoncpp",
         "libqemu_pipe",
     ],
 }
diff --git a/boot/1.1/default/service.cpp b/boot/1.1/default/service.cpp
index 93eaeda..89251b5 100644
--- a/boot/1.1/default/service.cpp
+++ b/boot/1.1/default/service.cpp
@@ -15,12 +15,13 @@
  */
 #define LOG_TAG "android.hardware.boot@1.1-service"
 
-#include <android/hardware/boot/1.0/IBootControl.h>
+#include <android/hardware/boot/1.1/IBootControl.h>
 #include <hidl/LegacySupport.h>
 
 using android::hardware::defaultPassthroughServiceImplementation;
-using ::android::hardware::boot::V1_0::IBootControl;
+using IBootControl_V1_0 = android::hardware::boot::V1_0::IBootControl;
+using IBootControl_V1_1 = android::hardware::boot::V1_1::IBootControl;
 
 int main(int /* argc */, char* /* argv */[]) {
-    return defaultPassthroughServiceImplementation<IBootControl>();
+    return defaultPassthroughServiceImplementation<IBootControl_V1_0, IBootControl_V1_1>();
 }
diff --git a/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp b/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
index fba9a5e..7c58ef3 100644
--- a/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
+++ b/boot/1.1/vts/functional/VtsHalBootV1_1TargetTest.cpp
@@ -81,6 +81,6 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(
-        , BootHidlTest,
+        PerInstance, BootHidlTest,
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBootControl::descriptor)),
         android::hardware::PrintInstanceNameToString);
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 1b0d7cb..49f9fe1 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -6320,9 +6320,10 @@
         android::hardware::graphics::mapper::V3_0::IMapper::getService();
     sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
         android::hardware::graphics::mapper::V2_0::IMapper::getService();
-    ::android::hardware::hidl_vec<uint32_t> descriptor;
     if (mapperV4 != nullptr && allocatorV4 != nullptr) {
+        ::android::hardware::hidl_vec<uint8_t> descriptor;
         android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo descriptorInfo{};
+        descriptorInfo.name = "VtsHalCameraProviderV2_4";
         descriptorInfo.width = width;
         descriptorInfo.height = height;
         descriptorInfo.layerCount = 1;
@@ -6332,7 +6333,7 @@
 
         auto ret = mapperV4->createDescriptor(
                 descriptorInfo, [&descriptor](android::hardware::graphics::mapper::V4_0::Error err,
-                                              ::android::hardware::hidl_vec<uint32_t> desc) {
+                                              ::android::hardware::hidl_vec<uint8_t> desc) {
                     ASSERT_EQ(err, android::hardware::graphics::mapper::V4_0::Error::NONE);
                     descriptor = desc;
                 });
@@ -6349,6 +6350,7 @@
                 });
         ASSERT_TRUE(ret.isOk());
     } else if (mapperV3 != nullptr && allocatorV3 != nullptr) {
+        ::android::hardware::hidl_vec<uint32_t> descriptor;
         android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo descriptorInfo {};
         descriptorInfo.width = width;
         descriptorInfo.height = height;
@@ -6374,6 +6376,7 @@
             });
         ASSERT_TRUE(ret.isOk());
     } else {
+        ::android::hardware::hidl_vec<uint32_t> descriptor;
         ASSERT_NE(mapper.get(), nullptr);
         ASSERT_NE(allocator.get(), nullptr);
         android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo {};
diff --git a/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy_64.rc b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy_64.rc
index aa070d9..955b28e 100644
--- a/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy_64.rc
+++ b/camera/provider/2.5/default/android.hardware.camera.provider@2.5-service-lazy_64.rc
@@ -1,6 +1,6 @@
 service vendor.camera-provider-2-5 /vendor/bin/hw/android.hardware.camera.provider@2.5-service-lazy_64
     interface android.hardware.camera.provider@2.5::ICameraProvider legacy/0
-    interface android.hardware.camera.provider@2.5::ICameraProvider legacy/0
+    interface android.hardware.camera.provider@2.4::ICameraProvider legacy/0
     oneshot
     disabled
     class hal
diff --git a/cas/1.2/types.hal b/cas/1.2/types.hal
index 40c06cf..06199cd 100644
--- a/cas/1.2/types.hal
+++ b/cas/1.2/types.hal
@@ -45,6 +45,10 @@
      *  ERROR_CAS_BLACKOUT is used to report geographical blackout.
      */
     ERROR_CAS_BLACKOUT,
+    /**
+     * ERROR_CAS_REBOOTING is used to report CAS is during rebooting.
+     */
+    ERROR_CAS_REBOOTING,
 };
 
 /**
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 8ffed4b..1535979 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -123,7 +123,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.cas</name>
-        <version>1.1</version>
+        <version>1.1-2</version>
         <interface>
             <name>IMediaCasService</name>
             <instance>default</instance>
diff --git a/current.txt b/current.txt
index 3b236a5..74586b7 100644
--- a/current.txt
+++ b/current.txt
@@ -587,6 +587,10 @@
 # HALs released in Android R
 07d0a252b2d8fa35887908a996ba395cf392968395fc30afab791f46e0c22a52 android.hardware.boot@1.1::IBootControl
 74049a402be913963edfdd80828a53736570e9d8124a1bf18166b6ed46a6b0ab android.hardware.boot@1.1::types
+c1aa508d00b66ed5feefea398fd5edf28fa651ac89773adad7dfda4e0a73a952 android.hardware.cas@1.2::ICas
+9811f867def49b420d8c707f7e38d3bdd64f835244e1d2a5e9762ab9835672dc android.hardware.cas@1.2::ICasListener
+f18695dd36ee205640b8326a17453858a7b4596653aaa6ef0016b0aef1bd4dac android.hardware.cas@1.2::IMediaCasService
+4d85e814f94949dae4dc6cb82bbd7d6bb24ffafda6ddb2eac928d2a4fc2e21ce android.hardware.cas@1.2::types
 ce8dbe76eb9ee94b46ef98f725be992e760a5751073d4f4912484026541371f3 android.hardware.health@2.1::IHealth
 26f04510a0b57aba5167c5c0a7c2f077c2acbb98b81902a072517829fd9fd67f android.hardware.health@2.1::IHealthInfoCallback
 db47f4ceceb1f06c656f39caa70c557b0f8471ef59fd58611bea667ffca20101 android.hardware.health@2.1::types
@@ -594,15 +598,12 @@
 4a6c3b3556da951b4def21ba579a227c022980fe4465df6cdfbe20628fa75f5a android.hardware.neuralnetworks@1.3::IPreparedModel
 94e803236398bed1febb11cc21051bc42ec003700139b099d6c479e02a7ca3c3 android.hardware.neuralnetworks@1.3::IPreparedModelCallback
 b74fe72cfe438f50e772e6a307657ff449d5bde83c15dd1f140ff2edbe73499c android.hardware.neuralnetworks@1.3::types
-544049dcda3f943ad67d83d5277f06681a3782982a9af5a78b5d4e8d295d061a android.hardware.vibrator@1.4::IVibrator
-5e1c12efbbba89c9143d10b1b90eceff8bc79aa079f5106215b528e104fef101 android.hardware.vibrator@1.4::IVibratorCallback
-033eae03c09ebc75e82db37bc39995dfaa9086745577b44d9e14e9ccb48bd8cc android.hardware.vibrator@1.4::types
 3e01d4446cd69fd1c48f8572efd97487bc179564b32bd795800b97bbe10be37b android.hardware.wifi@1.4::IWifi
 a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant
-0a7ff83fd0326b82232e1609da98f34960be11335df72fc407ad238d7bd0e081 android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
+44445b8a03d7b9e68b2fbd954672c18a8fce9e32851b0692f4f4ab3407f86ecb android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
 619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
 c9273429fcf98d797d3bb07fdba6f1be95bf960f9255cde169fd1ca4db85f856 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
-b0f8c9cd61a45a8c1b4a8e40913ecaea0921011cbe2305a6fa5a2feaa0d36c30 android.hardware.wifi.supplicant@1.3::types
+9b0a3ab6f4f74b971ed094426d8a443e29b512ff03e1ab50c07156396cdb2483 android.hardware.wifi.supplicant@1.3::types
 41c602462ccd1b19cfd645994be4de4c07fc197ff58a54e84476b31908e61e21 android.hardware.radio@1.5::types
 a8691c71747c3f14f7a043598e856425077f755e55990507a9132ad62f8ab3f7 android.hardware.radio@1.5::IRadio
 a62a93faf173b14a6175b683ebf61ffa568dc61f81e369d2dce7b1265e86cf2f android.hardware.radio@1.5::IRadioIndication
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
index 0af9745..ec7a0b9 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/Android.bp
@@ -22,40 +22,12 @@
         "-Werror",
     ],
     cppflags: [
-        "-Weverything",
+        "-Wextra",
         "-Wunused",
         "-Wunreachable-code",
 
-        // The static constructors and destructors in this library have not been noted to
-        // introduce significant overheads
-        "-Wno-exit-time-destructors",
-        "-Wno-global-constructors",
-
-        // We only care about compiling as C++14
-        "-Wno-c++98-compat-pedantic",
-
-        // android/sensors.h uses nested anonymous unions and anonymous structs
-        "-Wno-nested-anon-types",
-        "-Wno-gnu-anonymous-struct",
-
-        // Don't warn about struct padding
-        "-Wno-padded",
-
-        // hwcomposer2.h features switch covering all cases.
-        "-Wno-covered-switch-default",
-
-        // hwcomposer.h features zero size array.
-        "-Wno-zero-length-array",
-
         // Disabling warning specific to hwc2on1adapter code
-        "-Wno-double-promotion",
-        "-Wno-sign-conversion",
-        "-Wno-switch-enum",
-        "-Wno-float-equal",
-        "-Wno-shorten-64-to-32",
         "-Wno-sign-compare",
-        "-Wno-missing-prototypes",
-        "-Wno-format-pedantic",
     ],
 
     srcs: [
diff --git a/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp b/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
index 3d138f7..5a75ae1 100644
--- a/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
+++ b/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
@@ -1389,7 +1389,7 @@
 }
 
 static std::string approximateFloatString(float f) {
-    if (static_cast<int32_t>(f) == f) {
+    if (static_cast<float>(static_cast<int32_t>(f)) == f) {
         return std::to_string(static_cast<int32_t>(f));
     }
     int32_t truncated = static_cast<int32_t>(f * 10);
@@ -1680,10 +1680,10 @@
     if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
             mAttributes.at(HWC2::Attribute::DpiX) != -1) {
         std::memset(buffer, 0, BUFFER_SIZE);
-        writtenBytes = snprintf(buffer, BUFFER_SIZE,
-                ", DPI: %.1f x %.1f",
-                mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
-                mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
+        writtenBytes =
+                snprintf(buffer, BUFFER_SIZE, ", DPI: %.1f x %.1f",
+                         static_cast<float>(mAttributes.at(HWC2::Attribute::DpiX)) / 1000.0f,
+                         static_cast<float>(mAttributes.at(HWC2::Attribute::DpiY)) / 1000.0f);
         output.append(buffer, writtenBytes);
     }
 
diff --git a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
index e8a3905..5db3e16 100644
--- a/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
+++ b/graphics/composer/2.4/utils/vts/include/composer-vts/2.4/ComposerVts.h
@@ -51,12 +51,10 @@
   public:
     Composer();
     explicit Composer(const std::string& name);
+    explicit Composer(const sp<IComposer>& composer);
 
     std::unique_ptr<ComposerClient> createClient();
 
-  protected:
-    explicit Composer(const sp<IComposer>& composer);
-
   private:
     const sp<IComposer> mComposer;
 };
diff --git a/graphics/composer/2.4/vts/functional/Android.bp b/graphics/composer/2.4/vts/functional/Android.bp
index 921c421..937af3d 100644
--- a/graphics/composer/2.4/vts/functional/Android.bp
+++ b/graphics/composer/2.4/vts/functional/Android.bp
@@ -51,4 +51,6 @@
         "android.hardware.graphics.composer@2.3-command-buffer",
         "android.hardware.graphics.composer@2.4-command-buffer",
     ],
+    disable_framework: true,
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
index 3d967fc..2c87666 100644
--- a/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
+++ b/graphics/composer/2.4/vts/functional/VtsHalGraphicsComposerV2_4TargetTest.cpp
@@ -19,13 +19,15 @@
 #include <algorithm>
 #include <thread>
 
-#include <VtsHalHidlTargetTestBase.h>
 #include <android-base/logging.h>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
 #include <composer-command-buffer/2.4/ComposerCommandBuffer.h>
 #include <composer-vts/2.1/GraphicsComposerCallback.h>
 #include <composer-vts/2.1/TestCommandReader.h>
 #include <composer-vts/2.4/ComposerVts.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 #include <mapper-vts/2.0/MapperVts.h>
 #include <utils/Timers.h>
 
@@ -45,29 +47,11 @@
 using mapper::V2_0::IMapper;
 using mapper::V2_0::vts::Gralloc;
 
-// Test environment for graphics.composer
-class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-  public:
-    // get the test environment singleton
-    static GraphicsComposerHidlEnvironment* Instance() {
-        static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IComposer>(); }
-
-  private:
-    GraphicsComposerHidlEnvironment() {}
-
-    GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
-};
-
-class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class GraphicsComposerHidlTest : public ::testing::TestWithParam<std::string> {
   protected:
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(
-                mComposer = std::make_unique<Composer>(
-                        GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
+                mComposer = std::make_unique<Composer>(IComposer::getService(GetParam())));
         ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient());
 
         mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
@@ -194,13 +178,13 @@
     std::unique_ptr<Gralloc> mGralloc;
 };
 
-TEST_F(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
+TEST_P(GraphicsComposerHidlTest, getDisplayCapabilitiesBadDisplay) {
     std::vector<IComposerClient::DisplayCapability> capabilities;
     const auto error = mComposerClient->getDisplayCapabilities(mInvalidDisplayId, &capabilities);
     EXPECT_EQ(Error::BAD_DISPLAY, error);
 }
 
-TEST_F(GraphicsComposerHidlTest, getDisplayConnectionType) {
+TEST_P(GraphicsComposerHidlTest, getDisplayConnectionType) {
     IComposerClient::DisplayConnectionType type;
     EXPECT_EQ(Error::BAD_DISPLAY,
               mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type));
@@ -210,13 +194,13 @@
     }
 }
 
-TEST_F(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods_BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods_BadDisplay) {
     std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
     EXPECT_EQ(Error::BAD_DISPLAY, mComposerClient->getSupportedDisplayVsyncPeriods(
                                           mInvalidDisplayId, Config(0), &supportedVsyncPeriods));
 }
 
-TEST_F(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods_BadConfig) {
+TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods_BadConfig) {
     for (Display display : mComposerCallback->getDisplays()) {
         Config invalidConfigId = GetInvalidConfigId(display);
         std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
@@ -225,7 +209,7 @@
     }
 }
 
-TEST_F(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods) {
+TEST_P(GraphicsComposerHidlTest, getSupportedDisplayVsyncPeriods) {
     for (Display display : mComposerCallback->getDisplays()) {
         for (Config config : mComposerClient->getDisplayConfigs(display)) {
             std::vector<VsyncPeriodNanos> supportedVsyncPeriods;
@@ -250,13 +234,13 @@
     }
 }
 
-TEST_F(GraphicsComposerHidlTest, getDisplayVsyncPeriod_BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, getDisplayVsyncPeriod_BadDisplay) {
     VsyncPeriodNanos vsyncPeriodNanos;
     EXPECT_EQ(Error::BAD_DISPLAY,
               mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos));
 }
 
-TEST_F(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadDisplay) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadDisplay) {
     int64_t newVsyncAppliedTime;
     IComposerClient::VsyncPeriodChangeConstraints constraints;
 
@@ -268,7 +252,7 @@
                                           constraints, &newVsyncAppliedTime));
 }
 
-TEST_F(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadConfig) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadConfig) {
     int64_t newVsyncAppliedTime;
     IComposerClient::VsyncPeriodChangeConstraints constraints;
 
@@ -283,7 +267,7 @@
     }
 }
 
-TEST_F(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadVsyncPeriod) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_BadVsyncPeriod) {
     int64_t newVsyncAppliedTime;
     IComposerClient::VsyncPeriodChangeConstraints constraints;
 
@@ -349,7 +333,7 @@
     }
 }
 
-TEST_F(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod) {
     IComposerClient::VsyncPeriodChangeConstraints constraints;
 
     constraints.seamlessRequired = false;
@@ -357,7 +341,7 @@
     Test_setActiveConfigAndVsyncPeriod(constraints);
 }
 
-TEST_F(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_delayed) {
+TEST_P(GraphicsComposerHidlTest, setActiveConfigAndVsyncPeriod_delayed) {
     IComposerClient::VsyncPeriodChangeConstraints constraints;
 
     constexpr auto kDelayForChange = 300ms;
@@ -366,6 +350,11 @@
     Test_setActiveConfigAndVsyncPeriod(constraints);
 }
 
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, GraphicsComposerHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IComposer::descriptor)),
+        android::hardware::PrintInstanceNameToString);
+
 }  // namespace
 }  // namespace vts
 }  // namespace V2_4
@@ -373,12 +362,3 @@
 }  // namespace graphics
 }  // namespace hardware
 }  // namespace android
-
-int main(int argc, char** argv) {
-    using android::hardware::graphics::composer::V2_4::vts::GraphicsComposerHidlEnvironment;
-    ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    return status;
-}
diff --git a/graphics/mapper/4.0/IMapper.hal b/graphics/mapper/4.0/IMapper.hal
index 85c7c81..640539f 100644
--- a/graphics/mapper/4.0/IMapper.hal
+++ b/graphics/mapper/4.0/IMapper.hal
@@ -23,6 +23,11 @@
 interface IMapper {
     struct BufferDescriptorInfo {
         /**
+         * The name of the buffer. Useful for debugging/tracing.
+         */
+        string name;
+
+        /**
          * The width specifies how many columns of pixels must be in the
          * allocated buffer, but does not necessarily represent the offset in
          * columns between the same column in adjacent rows. The rows may be
@@ -219,7 +224,8 @@
      *     - `BAD_BUFFER` if the buffer is invalid or is incompatible with this
      *       function.
      *     - `BAD_VALUE` if @p cpuUsage is 0, contains non-CPU usage flags, or
-     *       is incompatible with the buffer.
+     *       is incompatible with the buffer. Also if the @p accessRegion is
+     *       outside the bounds of the buffer or the accessRegion is invalid.
      *     - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
      *       that locking may succeed at a later time.
      * @return data CPU-accessible pointer to the buffer data.
diff --git a/graphics/mapper/4.0/types.hal b/graphics/mapper/4.0/types.hal
index 603b243..2fdfa65 100644
--- a/graphics/mapper/4.0/types.hal
+++ b/graphics/mapper/4.0/types.hal
@@ -51,7 +51,7 @@
  * createDescriptor(). It describes the properties of a buffer and is consumed
  * by the allocator.
  */
-typedef vec<uint32_t> BufferDescriptor;
+typedef vec<uint8_t> BufferDescriptor;
 
 /**
  * Structure for describing YCbCr formats for consumption by applications.
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 706c658..62ff613 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -58,6 +58,7 @@
                         GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
                         GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
 
+        mDummyDescriptorInfo.name = "dummy";
         mDummyDescriptorInfo.width = 64;
         mDummyDescriptorInfo.height = 64;
         mDummyDescriptorInfo.layerCount = 1;
@@ -404,6 +405,49 @@
 }
 
 /**
+ * Test IMapper::unlock with bad access region
+ */
+TEST_F(GraphicsMapperHidlTest, LockBadAccessRegion) {
+    const auto& info = mDummyDescriptorInfo;
+
+    const native_handle_t* bufferHandle;
+    ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
+
+    const IMapper::Rect accessRegion{0, 0, static_cast<int32_t>(info.width * 2),
+                                     static_cast<int32_t>(info.height * 2)};
+    int acquireFence = -1;
+
+    NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+    hidl_handle acquireFenceHandle;
+    if (acquireFence >= 0) {
+        auto h = native_handle_init(acquireFenceStorage, 1, 0);
+        h->data[0] = acquireFence;
+        acquireFenceHandle = h;
+    }
+
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+    mGralloc->getMapper()->lock(buffer, info.usage, accessRegion, acquireFenceHandle,
+                                [&](const auto& tmpError, const auto& /*tmpData*/,
+                                    int32_t /*tmpBytesPerPixel*/, int32_t /*tmpBytesPerStride*/) {
+                                    EXPECT_EQ(Error::BAD_VALUE, tmpError)
+                                            << "locking with a bad access region should fail";
+                                });
+
+    if (::testing::Test::HasFailure()) {
+        if (acquireFence >= 0) {
+            close(acquireFence);
+        }
+
+        int releaseFence = -1;
+        ASSERT_NO_FATAL_FAILURE(releaseFence = mGralloc->unlock(bufferHandle));
+
+        if (releaseFence >= 0) {
+            close(releaseFence);
+        }
+    }
+}
+
+/**
  * Test IMapper::unlock with invalid buffers.
  */
 TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
diff --git a/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp b/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp
index 7df4926..da9f5bb 100644
--- a/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp
+++ b/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp
@@ -252,7 +252,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(
-        , HealthHidlTest,
+        PerInstance, HealthHidlTest,
         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IHealth::descriptor)),
         android::hardware::PrintInstanceNameToString);
 
diff --git a/radio/1.5/Android.bp b/radio/1.5/Android.bp
index 06a2a6e..de9ec6e 100644
--- a/radio/1.5/Android.bp
+++ b/radio/1.5/Android.bp
@@ -19,7 +19,6 @@
         "android.hardware.radio@1.3",
         "android.hardware.radio@1.4",
         "android.hidl.base@1.0",
-        "android.hidl.safe_union@1.0",
     ],
     gen_java: true,
 }
diff --git a/radio/config/1.1/vts/functional/Android.bp b/radio/config/1.1/vts/functional/Android.bp
index de909a3..8cf7b62 100644
--- a/radio/config/1.1/vts/functional/Android.bp
+++ b/radio/config/1.1/vts/functional/Android.bp
@@ -29,5 +29,5 @@
         "android.hardware.radio.config@1.1",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/radio/config/1.1/vts/functional/VtsHalRadioConfigV1_1TargetTest.cpp b/radio/config/1.1/vts/functional/VtsHalRadioConfigV1_1TargetTest.cpp
index 2fc6b62..b3fae86 100644
--- a/radio/config/1.1/vts/functional/VtsHalRadioConfigV1_1TargetTest.cpp
+++ b/radio/config/1.1/vts/functional/VtsHalRadioConfigV1_1TargetTest.cpp
@@ -16,11 +16,7 @@
 
 #include <radio_config_hidl_hal_utils.h>
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(RadioConfigHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    RadioConfigHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioConfigHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IRadioConfig::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/radio/config/1.1/vts/functional/radio_config_hidl_hal_api.cpp b/radio/config/1.1/vts/functional/radio_config_hidl_hal_api.cpp
index 5d0e867..49c7aad 100644
--- a/radio/config/1.1/vts/functional/radio_config_hidl_hal_api.cpp
+++ b/radio/config/1.1/vts/functional/radio_config_hidl_hal_api.cpp
@@ -21,7 +21,7 @@
 /*
  * Test IRadioConfig.getModemsConfig()
  */
-TEST_F(RadioConfigHidlTest, getModemsConfig) {
+TEST_P(RadioConfigHidlTest, getModemsConfig) {
     serial = GetRandomSerialNumber();
     Return<void> res = radioConfig->getModemsConfig(serial);
     ASSERT_OK(res);
@@ -37,7 +37,7 @@
 /*
  * Test IRadioConfig.setModemsConfig()
  */
-TEST_F(RadioConfigHidlTest, setModemsConfig_invalidArgument) {
+TEST_P(RadioConfigHidlTest, setModemsConfig_invalidArgument) {
     serial = GetRandomSerialNumber();
     ModemsConfig* mConfig = new ModemsConfig();
     Return<void> res = radioConfig->setModemsConfig(serial, *mConfig);
@@ -55,7 +55,7 @@
 /*
  * Test IRadioConfig.setModemsConfig()
  */
-TEST_F(RadioConfigHidlTest, setModemsConfig_goodRequest) {
+TEST_P(RadioConfigHidlTest, setModemsConfig_goodRequest) {
     serial = GetRandomSerialNumber();
     ModemsConfig* mConfig = new ModemsConfig();
     mConfig->numOfLiveModems = 1;
@@ -73,7 +73,7 @@
 /*
  * Test IRadioConfig.getPhoneCapability()
  */
-TEST_F(RadioConfigHidlTest, getPhoneCapability) {
+TEST_P(RadioConfigHidlTest, getPhoneCapability) {
     serial = GetRandomSerialNumber();
     Return<void> res = radioConfig->getPhoneCapability(serial);
     ASSERT_OK(res);
@@ -99,7 +99,7 @@
 /*
  * Test IRadioConfig.getPhoneCapability()
  */
-TEST_F(RadioConfigHidlTest, setPreferredDataModem) {
+TEST_P(RadioConfigHidlTest, setPreferredDataModem) {
     serial = GetRandomSerialNumber();
     Return<void> res = radioConfig->getPhoneCapability(serial);
     ASSERT_OK(res);
@@ -141,7 +141,7 @@
 /*
  * Test IRadioConfig.getPhoneCapability()
  */
-TEST_F(RadioConfigHidlTest, setPreferredDataModem_invalidArgument) {
+TEST_P(RadioConfigHidlTest, setPreferredDataModem_invalidArgument) {
     serial = GetRandomSerialNumber();
     uint8_t modemId = -1;
     Return<void> res = radioConfig->setPreferredDataModem(serial, modemId);
diff --git a/radio/config/1.1/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.1/vts/functional/radio_config_hidl_hal_test.cpp
index 39e6487..2e5e424 100644
--- a/radio/config/1.1/vts/functional/radio_config_hidl_hal_test.cpp
+++ b/radio/config/1.1/vts/functional/radio_config_hidl_hal_test.cpp
@@ -17,14 +17,10 @@
 #include <radio_config_hidl_hal_utils.h>
 
 void RadioConfigHidlTest::SetUp() {
-    radioConfig = ::testing::VtsHalHidlTargetTestBase::getService<IRadioConfig>(
-        RadioConfigHidlEnvironment::Instance()->getServiceName<IRadioConfig>(
-            hidl_string(RADIO_SERVICE_NAME)));
+    radioConfig = IRadioConfig::getService(GetParam());
     if (radioConfig == NULL) {
         sleep(60);
-        radioConfig = ::testing::VtsHalHidlTargetTestBase::getService<IRadioConfig>(
-            RadioConfigHidlEnvironment::Instance()->getServiceName<IRadioConfig>(
-                hidl_string(RADIO_SERVICE_NAME)));
+        radioConfig = IRadioConfig::getService(GetParam());
     }
     ASSERT_NE(nullptr, radioConfig.get());
 
diff --git a/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h
index c980901..e9951dc 100644
--- a/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h
+++ b/radio/config/1.1/vts/functional/radio_config_hidl_hal_utils.h
@@ -16,8 +16,6 @@
 
 #include <android-base/logging.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <chrono>
 #include <condition_variable>
 #include <mutex>
@@ -25,6 +23,9 @@
 #include <android/hardware/radio/config/1.1/IRadioConfig.h>
 #include <android/hardware/radio/config/1.1/IRadioConfigResponse.h>
 #include <android/hardware/radio/config/1.1/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 #include "vts_test_util.h"
 
@@ -73,22 +74,8 @@
     Return<void> setModemsConfigResponse(const RadioResponseInfo& info);
 };
 
-// Test environment for Radio HIDL HAL.
-class RadioConfigHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static RadioConfigHidlEnvironment* Instance() {
-        static RadioConfigHidlEnvironment* instance = new RadioConfigHidlEnvironment;
-        return instance;
-    }
-    virtual void registerTestServices() override { registerTestService<IRadioConfig>(); }
-
-   private:
-    RadioConfigHidlEnvironment() {}
-};
-
 // The main test class for Radio config HIDL.
-class RadioConfigHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class RadioConfigHidlTest : public ::testing::TestWithParam<std::string> {
    protected:
     std::mutex mtx_;
     std::condition_variable cv_;
diff --git a/radio/config/1.2/vts/functional/Android.bp b/radio/config/1.2/vts/functional/Android.bp
index 0cafc24..2c2073a 100644
--- a/radio/config/1.2/vts/functional/Android.bp
+++ b/radio/config/1.2/vts/functional/Android.bp
@@ -31,5 +31,5 @@
         "android.hardware.radio.config@1.2",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/radio/config/1.2/vts/functional/VtsHalRadioConfigV1_2TargetTest.cpp b/radio/config/1.2/vts/functional/VtsHalRadioConfigV1_2TargetTest.cpp
index ec6544e..f09ac3a 100644
--- a/radio/config/1.2/vts/functional/VtsHalRadioConfigV1_2TargetTest.cpp
+++ b/radio/config/1.2/vts/functional/VtsHalRadioConfigV1_2TargetTest.cpp
@@ -16,11 +16,7 @@
 
 #include <radio_config_hidl_hal_utils.h>
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(RadioConfigHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    RadioConfigHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, RadioConfigHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IRadioConfig::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/radio/config/1.2/vts/functional/radio_config_hidl_hal_api.cpp b/radio/config/1.2/vts/functional/radio_config_hidl_hal_api.cpp
index a3729ac..2129ecd 100644
--- a/radio/config/1.2/vts/functional/radio_config_hidl_hal_api.cpp
+++ b/radio/config/1.2/vts/functional/radio_config_hidl_hal_api.cpp
@@ -21,7 +21,7 @@
 /*
  * Test IRadioConfig.getSimSlotsStatus()
  */
-TEST_F(RadioConfigHidlTest, getSimSlotsStatus) {
+TEST_P(RadioConfigHidlTest, getSimSlotsStatus) {
     const int serial = GetRandomSerialNumber();
     Return<void> res = radioConfig->getSimSlotsStatus(serial);
     ASSERT_OK(res);
diff --git a/radio/config/1.2/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.2/vts/functional/radio_config_hidl_hal_test.cpp
index cd7a172..fd344b0 100644
--- a/radio/config/1.2/vts/functional/radio_config_hidl_hal_test.cpp
+++ b/radio/config/1.2/vts/functional/radio_config_hidl_hal_test.cpp
@@ -17,14 +17,10 @@
 #include <radio_config_hidl_hal_utils.h>
 
 void RadioConfigHidlTest::SetUp() {
-    radioConfig = ::testing::VtsHalHidlTargetTestBase::getService<IRadioConfig>(
-            RadioConfigHidlEnvironment::Instance()->getServiceName<IRadioConfig>(
-                    hidl_string(RADIO_SERVICE_NAME)));
+    radioConfig = IRadioConfig::getService(GetParam());
     if (radioConfig == NULL) {
         sleep(60);
-        radioConfig = ::testing::VtsHalHidlTargetTestBase::getService<IRadioConfig>(
-                RadioConfigHidlEnvironment::Instance()->getServiceName<IRadioConfig>(
-                        hidl_string(RADIO_SERVICE_NAME)));
+        radioConfig = IRadioConfig::getService(GetParam());
     }
     ASSERT_NE(nullptr, radioConfig.get());
 
diff --git a/radio/config/1.2/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.2/vts/functional/radio_config_hidl_hal_utils.h
index a876766..e9cbcbd 100644
--- a/radio/config/1.2/vts/functional/radio_config_hidl_hal_utils.h
+++ b/radio/config/1.2/vts/functional/radio_config_hidl_hal_utils.h
@@ -16,8 +16,6 @@
 
 #include <android-base/logging.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <chrono>
 #include <condition_variable>
 #include <mutex>
@@ -27,6 +25,9 @@
 #include <android/hardware/radio/config/1.2/IRadioConfigIndication.h>
 #include <android/hardware/radio/config/1.2/IRadioConfigResponse.h>
 #include <android/hardware/radio/config/1.2/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
 #include "vts_test_util.h"
 
@@ -112,7 +113,7 @@
 };
 
 // The main test class for Radio config HIDL.
-class RadioConfigHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class RadioConfigHidlTest : public ::testing::TestWithParam<std::string> {
   protected:
     std::mutex mtx_;
     std::condition_variable cv_;
diff --git a/sensors/2.0/multihal/HalProxy.cpp b/sensors/2.0/multihal/HalProxy.cpp
index 49c5a0d..03ff605 100644
--- a/sensors/2.0/multihal/HalProxy.cpp
+++ b/sensors/2.0/multihal/HalProxy.cpp
@@ -150,6 +150,7 @@
 
     // Clears the queue if any events were pending write before.
     mPendingWriteEventsQueue = std::queue<std::pair<std::vector<Event>, size_t>>();
+    mSizePendingWriteEventsQueue = 0;
 
     // Clears previously connected dynamic sensors
     mDynamicSensors.clear();
@@ -287,7 +288,7 @@
            << " ms ago" << std::endl;
     // TODO(b/142969448): Add logging for history of wakelock acquisition per subhal.
     stream << "  Wakelock ref count: " << mWakelockRefCount << std::endl;
-    stream << "  Size of pending write events queue: " << mPendingWriteEventsQueue.size()
+    stream << "  # of events on pending write writes queue: " << mSizePendingWriteEventsQueue
            << std::endl;
     if (!mPendingWriteEventsQueue.empty()) {
         stream << "  Size of events list on front of pending writes queue: "
@@ -490,8 +491,10 @@
                 // all the events ahead of it down to fill gap off array at front after the erase.
                 pendingWriteEvents.erase(pendingWriteEvents.begin(),
                                          pendingWriteEvents.begin() + eventQueueSize);
+                mSizePendingWriteEventsQueue -= eventQueueSize;
             } else {
                 mPendingWriteEventsQueue.pop();
+                mSizePendingWriteEventsQueue -= pendingWriteEvents.size();
             }
         }
     }
@@ -563,11 +566,12 @@
             }
         }
     }
-    if (numToWrite < events.size()) {
-        // TODO(b/143302327): Bound the mPendingWriteEventsQueue so that we do not trigger OOMs if
-        // framework stalls
+    size_t numLeft = events.size() - numToWrite;
+    if (numToWrite < events.size() &&
+        mSizePendingWriteEventsQueue + numLeft <= kMaxSizePendingWriteEventsQueue) {
         std::vector<Event> eventsLeft(events.begin() + numToWrite, events.end());
         mPendingWriteEventsQueue.push({eventsLeft, numWakeupEvents});
+        mSizePendingWriteEventsQueue += numLeft;
         mEventQueueWriteCV.notify_one();
     }
 }
diff --git a/sensors/2.0/multihal/include/HalProxy.h b/sensors/2.0/multihal/include/HalProxy.h
index b1dd737..ce28e67 100644
--- a/sensors/2.0/multihal/include/HalProxy.h
+++ b/sensors/2.0/multihal/include/HalProxy.h
@@ -200,6 +200,12 @@
      */
     std::queue<std::pair<std::vector<Event>, size_t>> mPendingWriteEventsQueue;
 
+    //! The max number of events allowed in the pending write events queue
+    static constexpr size_t kMaxSizePendingWriteEventsQueue = 100000;
+
+    //! The number of events in the pending write events queue
+    size_t mSizePendingWriteEventsQueue = 0;
+
     //! The mutex protecting writing to the fmq and the pending events queue
     std::mutex mEventQueueWriteMutex;
 
diff --git a/sensors/common/vts/utils/GrallocWrapper.cpp b/sensors/common/vts/utils/GrallocWrapper.cpp
index e63faa2..1cad913 100644
--- a/sensors/common/vts/utils/GrallocWrapper.cpp
+++ b/sensors/common/vts/utils/GrallocWrapper.cpp
@@ -147,8 +147,8 @@
             .width = size,
             .height = 1,
             .layerCount = 1,
-            .format = static_cast<decltype(descriptorInfo.format)>(PixelFormat::BLOB),
             .usage = kBufferUsage,
+            .format = static_cast<decltype(descriptorInfo.format)>(PixelFormat::BLOB),
     };
 
     BufferDescriptor descriptor;
diff --git a/soundtrigger/2.0/Android.bp b/soundtrigger/2.0/Android.bp
index 5613abd..07c05bc 100644
--- a/soundtrigger/2.0/Android.bp
+++ b/soundtrigger/2.0/Android.bp
@@ -15,5 +15,5 @@
         "android.hardware.audio.common@2.0",
         "android.hidl.base@1.0",
     ],
-    gen_java: false,
+    gen_java: true,
 }
diff --git a/tests/libhwbinder/1.0/default/Android.bp b/tests/libhwbinder/1.0/default/Android.bp
index 81022b8..3bf08ed 100644
--- a/tests/libhwbinder/1.0/default/Android.bp
+++ b/tests/libhwbinder/1.0/default/Android.bp
@@ -1,5 +1,5 @@
 cc_library {
-    name: "android.hardware.tests.libhwbinder@1.0-impl",
+    name: "android.hardware.tests.libhwbinder@1.0-impl.test",
     defaults: ["hidl_defaults"],
     relative_install_path: "hw",
     srcs: [
diff --git a/tests/trie/1.0/Android.bp b/tests/trie/1.0/Android.bp
index 5a33aea..3cb67c7 100644
--- a/tests/trie/1.0/Android.bp
+++ b/tests/trie/1.0/Android.bp
@@ -10,5 +10,5 @@
     interfaces: [
         "android.hidl.base@1.0",
     ],
-    gen_java: false,
+    gen_java: true,
 }
diff --git a/tetheroffload/config/1.0/vts/functional/Android.bp b/tetheroffload/config/1.0/vts/functional/Android.bp
index 52b9810..7b472e3 100644
--- a/tetheroffload/config/1.0/vts/functional/Android.bp
+++ b/tetheroffload/config/1.0/vts/functional/Android.bp
@@ -17,5 +17,5 @@
     defaults: ["VtsHalTargetTestDefaults"],
     srcs: ["VtsHalTetheroffloadConfigV1_0TargetTest.cpp"],
     static_libs: ["android.hardware.tetheroffload.config@1.0"],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
index 34a95f2..02fe96f 100644
--- a/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
+++ b/tetheroffload/config/1.0/vts/functional/VtsHalTetheroffloadConfigV1_0TargetTest.cpp
@@ -16,11 +16,12 @@
 
 #define LOG_TAG "VtsOffloadConfigV1_0TargetTest"
 
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
 #include <android/hardware/tetheroffload/config/1.0/IOffloadConfig.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 #include <linux/netfilter/nfnetlink.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
@@ -78,25 +79,10 @@
     return netlinkSocket(NETLINK_NETFILTER, groups);
 }
 
-// Test environment for OffloadConfig HIDL HAL.
-class OffloadConfigHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    // get the test environment singleton
-    static OffloadConfigHidlEnvironment* Instance() {
-        static OffloadConfigHidlEnvironment* instance = new OffloadConfigHidlEnvironment;
-        return instance;
-    }
-
-    virtual void registerTestServices() override { registerTestService<IOffloadConfig>(); }
-   private:
-    OffloadConfigHidlEnvironment() {}
-};
-
-class OffloadConfigHidlTest : public testing::VtsHalHidlTargetTestBase {
+class OffloadConfigHidlTest : public testing::TestWithParam<std::string> {
    public:
     virtual void SetUp() override {
-        config = testing::VtsHalHidlTargetTestBase::getService<IOffloadConfig>(
-            OffloadConfigHidlEnvironment::Instance()->getServiceName<IOffloadConfig>());
+        config = IOffloadConfig::getService(GetParam());
         ASSERT_NE(nullptr, config.get()) << "Could not get HIDL instance";
     }
 
@@ -106,7 +92,7 @@
 };
 
 // Ensure handles can be set with correct socket options.
-TEST_F(OffloadConfigHidlTest, TestSetHandles) {
+TEST_P(OffloadConfigHidlTest, TestSetHandles) {
     // Try multiple times in a row to see if it provokes file descriptor leaks.
     for (int i = 0; i < 1024; i++) {
         unique_fd fd1(netlinkSocket(kFd1Groups));
@@ -136,7 +122,7 @@
 
 // Passing a handle without an associated file descriptor should return an error
 // (e.g. "Failed Input Checks"). Check that this occurs when both FDs are empty.
-TEST_F(OffloadConfigHidlTest, TestSetHandleNone) {
+TEST_P(OffloadConfigHidlTest, TestSetHandleNone) {
     native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
     hidl_handle h1;
     h1.setTo(nativeHandle1, true);
@@ -150,7 +136,7 @@
 
 // Passing a handle without an associated file descriptor should return an error
 // (e.g. "Failed Input Checks"). Check that this occurs when FD2 is empty.
-TEST_F(OffloadConfigHidlTest, TestSetHandle1Only) {
+TEST_P(OffloadConfigHidlTest, TestSetHandle1Only) {
     unique_fd fd1(netlinkSocket(kFd1Groups));
     if (fd1.get() < 0) {
         ALOGE("Unable to create conntrack handles: %d/%s", errno, strerror(errno));
@@ -171,7 +157,7 @@
 
 // Passing a handle without an associated file descriptor should return an error
 // (e.g. "Failed Input Checks"). Check that this occurs when FD1 is empty.
-TEST_F(OffloadConfigHidlTest, TestSetHandle2OnlyNotOk) {
+TEST_P(OffloadConfigHidlTest, TestSetHandle2OnlyNotOk) {
     native_handle_t* const nativeHandle1 = native_handle_create(0, 0);
     hidl_handle h1;
     h1.setTo(nativeHandle1, true);
@@ -190,11 +176,7 @@
     ASSERT_TRUE(ret.isOk());
 }
 
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(OffloadConfigHidlEnvironment::Instance());
-    ::testing::InitGoogleTest(&argc, argv);
-    OffloadConfigHidlEnvironment::Instance()->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    ALOGE("Test result with status=%d", status);
-    return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, OffloadConfigHidlTest,
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(IOffloadConfig::descriptor)),
+        android::hardware::PrintInstanceNameToString);
diff --git a/tv/input/1.0/Android.bp b/tv/input/1.0/Android.bp
index 7288558..1164430 100644
--- a/tv/input/1.0/Android.bp
+++ b/tv/input/1.0/Android.bp
@@ -15,6 +15,6 @@
         "android.hardware.audio.common@2.0",
         "android.hidl.base@1.0",
     ],
-    gen_java: false,
+    gen_java: true,
     gen_java_constants: true,
 }
diff --git a/vibrator/staidl/Android.bp b/vibrator/aidl/Android.bp
similarity index 100%
rename from vibrator/staidl/Android.bp
rename to vibrator/aidl/Android.bp
diff --git a/vibrator/staidl/android/hardware/vibrator/Effect.aidl b/vibrator/aidl/android/hardware/vibrator/Effect.aidl
similarity index 100%
rename from vibrator/staidl/android/hardware/vibrator/Effect.aidl
rename to vibrator/aidl/android/hardware/vibrator/Effect.aidl
diff --git a/vibrator/staidl/android/hardware/vibrator/EffectStrength.aidl b/vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl
similarity index 100%
rename from vibrator/staidl/android/hardware/vibrator/EffectStrength.aidl
rename to vibrator/aidl/android/hardware/vibrator/EffectStrength.aidl
diff --git a/vibrator/staidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
similarity index 65%
rename from vibrator/staidl/android/hardware/vibrator/IVibrator.aidl
rename to vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index b2008f4..8c4fd05 100644
--- a/vibrator/staidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -31,23 +31,28 @@
      */
     const int CAP_PERFORM_CALLBACK = 1 << 1;
     /**
-     * Whether setAmplitude is supported.
+     * Whether setAmplitude is supported (when external control is disabled)
      */
     const int CAP_AMPLITUDE_CONTROL = 1 << 2;
     /**
      * Whether setExternalControl is supported.
      */
     const int CAP_EXTERNAL_CONTROL = 1 << 3;
+    /**
+     * Whether setAmplitude is supported (when external control is enabled)
+     */
+    const int CAP_EXTERNAL_AMPLITUDE_CONTROL = 1 << 4;
 
     /**
-     * Determine capabilities of the vibrator HAL (CAP_* values)
+     * Determine capabilities of the vibrator HAL (CAP_* mask)
      */
     int getCapabilities();
 
     /**
      * Turn off vibrator
      *
-     * Cancel a previously-started vibration, if any.
+     * Cancel a previously-started vibration, if any. If a previously-started vibration is
+     * associated with a callback, then onComplete should still be called on that callback.
      */
     void off();
 
@@ -55,7 +60,12 @@
      * Turn on vibrator
      *
      * This function must only be called after the previous timeout has expired or
-     * was canceled (through off()).
+     * was canceled (through off()). A callback is only expected to be supported when
+     * getCapabilities CAP_ON_CALLBACK is specified.
+     *
+     * Doing this operation while the vibrator is already on is undefined behavior. Clients should
+     * explicitly call off.
+     *
      * @param timeoutMs number of milliseconds to vibrate.
      * @param callback A callback used to inform Frameworks of state change, if supported.
      */
@@ -64,6 +74,12 @@
     /**
      * Fire off a predefined haptic event.
      *
+     * A callback is only expected to be supported when getCapabilities CAP_PERFORM_CALLBACK
+     * is specified.
+     *
+     * Doing this operation while the vibrator is already on is undefined behavior. Clients should
+     * explicitly call off.
+     *
      * @param effect The type of haptic event to trigger.
      * @param strength The intensity of haptic event to trigger.
      * @param callback A callback used to inform Frameworks of state change, if supported.
@@ -74,9 +90,21 @@
     int perform(in Effect effect, in EffectStrength strength, in IVibratorCallback callback);
 
     /**
+     * List supported effects.
+     *
+     * Return the effects which are supported (an effect is expected to be supported at every
+     * strength level.
+     */
+    Effect[] getSupportedEffects();
+
+    /**
      * Sets the motor's vibrational amplitude.
      *
-     * Changes the force being produced by the underlying motor.
+     * Changes the force being produced by the underlying motor. This may not be supported and
+     * this support is reflected in getCapabilities (CAP_AMPLITUDE_CONTROL). When this device
+     * is under external control (via setExternalControl), amplitude control may not be supported
+     * even though it is supported normally. This can be checked with
+     * CAP_EXTERNAL_AMPLITUDE_CONTROL.
      *
      * @param amplitude The unitless force setting. Note that this number must
      *                  be between 1 and 255, inclusive. If the motor does not
@@ -88,12 +116,14 @@
     /**
      * Enables/disables control override of vibrator to audio.
      *
+     * Support is reflected in getCapabilities (CAP_EXTERNAL_CONTROL).
+     *
      * When this API is set, the vibrator control should be ceded to audio system
      * for haptic audio. While this is enabled, issuing of other commands to control
      * the vibrator is unsupported and the resulting behavior is undefined. Amplitude
      * control may or may not be supported and is reflected in the return value of
-     * supportsAmplitudeControl() while this is enabled. When this is disabled, the
-     * vibrator should resume to an off state.
+     * getCapabilities (CAP_EXTERNAL_AMPLITUDE_CONTROL) while this is enabled. When this is
+     * disabled, the vibrator should resume to an off state.
      *
      * @param enabled Whether external control should be enabled or disabled.
      */
diff --git a/vibrator/staidl/android/hardware/vibrator/IVibratorCallback.aidl b/vibrator/aidl/android/hardware/vibrator/IVibratorCallback.aidl
similarity index 100%
rename from vibrator/staidl/android/hardware/vibrator/IVibratorCallback.aidl
rename to vibrator/aidl/android/hardware/vibrator/IVibratorCallback.aidl
diff --git a/vibrator/staidl/default/Android.bp b/vibrator/aidl/default/Android.bp
similarity index 100%
rename from vibrator/staidl/default/Android.bp
rename to vibrator/aidl/default/Android.bp
diff --git a/vibrator/staidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
similarity index 92%
rename from vibrator/staidl/default/Vibrator.cpp
rename to vibrator/aidl/default/Vibrator.cpp
index cdf8e09..18be1a6 100644
--- a/vibrator/staidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -27,7 +27,8 @@
 ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
     LOG(INFO) << "Vibrator reporting capabilities";
     *_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
-                    IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL;
+                    IVibrator::CAP_AMPLITUDE_CONTROL | IVibrator::CAP_EXTERNAL_CONTROL |
+                    IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
     return ndk::ScopedAStatus::ok();
 }
 
@@ -78,6 +79,11 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect>* _aidl_return) {
+    *_aidl_return = {Effect::CLICK, Effect::TICK};
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus Vibrator::setAmplitude(int32_t amplitude) {
     LOG(INFO) << "Vibrator set amplitude: " << amplitude;
     if (amplitude <= 0 || amplitude > 255) {
diff --git a/vibrator/staidl/default/Vibrator.h b/vibrator/aidl/default/Vibrator.h
similarity index 94%
rename from vibrator/staidl/default/Vibrator.h
rename to vibrator/aidl/default/Vibrator.h
index 77e96e3..14e7292 100644
--- a/vibrator/staidl/default/Vibrator.h
+++ b/vibrator/aidl/default/Vibrator.h
@@ -31,6 +31,7 @@
     ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
                                const std::shared_ptr<IVibratorCallback>& callback,
                                int32_t* _aidl_return) override;
+    ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
     ndk::ScopedAStatus setAmplitude(int32_t amplitude) override;
     ndk::ScopedAStatus setExternalControl(bool enabled) override;
 };
diff --git a/vibrator/staidl/default/main.cpp b/vibrator/aidl/default/main.cpp
similarity index 100%
rename from vibrator/staidl/default/main.cpp
rename to vibrator/aidl/default/main.cpp
diff --git a/vibrator/staidl/default/vibrator-default.rc b/vibrator/aidl/default/vibrator-default.rc
similarity index 100%
rename from vibrator/staidl/default/vibrator-default.rc
rename to vibrator/aidl/default/vibrator-default.rc
diff --git a/vibrator/staidl/default/vibrator-default.xml b/vibrator/aidl/default/vibrator-default.xml
similarity index 100%
rename from vibrator/staidl/default/vibrator-default.xml
rename to vibrator/aidl/default/vibrator-default.xml
diff --git a/vibrator/staidl/vts/Android.bp b/vibrator/aidl/vts/Android.bp
similarity index 100%
rename from vibrator/staidl/vts/Android.bp
rename to vibrator/aidl/vts/Android.bp
diff --git a/vibrator/staidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
similarity index 73%
rename from vibrator/staidl/vts/VtsHalVibratorTargetTest.cpp
rename to vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 33bcaf5..b6aa9e2 100644
--- a/vibrator/staidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -32,6 +32,7 @@
 using android::hardware::vibrator::EffectStrength;
 using android::hardware::vibrator::IVibrator;
 
+// TODO(b/143992652): autogenerate
 const std::vector<Effect> kEffects = {
         Effect::CLICK,       Effect::DOUBLE_CLICK, Effect::TICK,        Effect::THUD,
         Effect::POP,         Effect::HEAVY_CLICK,  Effect::RINGTONE_1,  Effect::RINGTONE_2,
@@ -40,17 +41,18 @@
         Effect::RINGTONE_11, Effect::RINGTONE_12,  Effect::RINGTONE_13, Effect::RINGTONE_14,
         Effect::RINGTONE_15, Effect::TEXTURE_TICK};
 
+// TODO(b/143992652): autogenerate
 const std::vector<EffectStrength> kEffectStrengths = {EffectStrength::LIGHT, EffectStrength::MEDIUM,
                                                       EffectStrength::STRONG};
 
 const std::vector<Effect> kInvalidEffects = {
-        static_cast<Effect>(static_cast<int32_t>(*kEffects.begin()) - 1),
-        static_cast<Effect>(static_cast<int32_t>(*kEffects.end()) + 1),
+        static_cast<Effect>(static_cast<int32_t>(kEffects.front()) - 1),
+        static_cast<Effect>(static_cast<int32_t>(kEffects.back()) + 1),
 };
 
 const std::vector<EffectStrength> kInvalidEffectStrengths = {
-        static_cast<EffectStrength>(static_cast<int8_t>(*kEffectStrengths.begin()) - 1),
-        static_cast<EffectStrength>(static_cast<int8_t>(*kEffectStrengths.end()) + 1),
+        static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.front()) - 1),
+        static_cast<EffectStrength>(static_cast<int8_t>(kEffectStrengths.back()) + 1),
 };
 
 class CompletionCallback : public BnVibratorCallback {
@@ -105,15 +107,25 @@
 }
 
 TEST_P(VibratorAidl, ValidateEffect) {
+    std::vector<Effect> supported;
+    ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
+
     for (Effect effect : kEffects) {
+        bool isEffectSupported =
+                std::find(supported.begin(), supported.end(), effect) != supported.end();
+
         for (EffectStrength strength : kEffectStrengths) {
             int32_t lengthMs = 0;
             Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
-            EXPECT_TRUE(status.isOk() ||
-                        status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION);
-            if (status.isOk()) {
+
+            if (isEffectSupported) {
+                EXPECT_TRUE(status.isOk())
+                        << static_cast<int>(effect) << " " << static_cast<int>(strength);
                 EXPECT_GT(lengthMs, 0);
+                usleep(lengthMs * 1000);
             } else {
+                EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
+                        << static_cast<int>(effect) << " " << static_cast<int>(strength);
                 EXPECT_EQ(lengthMs, 0);
             }
         }
@@ -123,16 +135,29 @@
 TEST_P(VibratorAidl, ValidateEffectWithCallback) {
     if (!(capabilities & IVibrator::CAP_PERFORM_CALLBACK)) return;
 
+    std::vector<Effect> supported;
+    ASSERT_TRUE(vibrator->getSupportedEffects(&supported).isOk());
+
     for (Effect effect : kEffects) {
+        bool isEffectSupported =
+                std::find(supported.begin(), supported.end(), effect) != supported.end();
+
         for (EffectStrength strength : kEffectStrengths) {
             std::promise<void> completionPromise;
             std::future<void> completionFuture{completionPromise.get_future()};
             sp<CompletionCallback> callback =
                     new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
-            int lengthMs;
+            int lengthMs = 0;
             Status status = vibrator->perform(effect, strength, callback, &lengthMs);
-            EXPECT_TRUE(status.isOk() ||
-                        status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION);
+
+            if (isEffectSupported) {
+                EXPECT_TRUE(status.isOk());
+                EXPECT_GT(lengthMs, 0);
+            } else {
+                EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
+                EXPECT_EQ(lengthMs, 0);
+            }
+
             if (!status.isOk()) continue;
 
             std::chrono::milliseconds timeout{lengthMs * 2};
@@ -157,10 +182,19 @@
 
 TEST_P(VibratorAidl, InvalidEffectsUnsupported) {
     for (Effect effect : kInvalidEffects) {
+        for (EffectStrength strength : kEffectStrengths) {
+            int32_t lengthMs;
+            Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
+            EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
+                    << static_cast<int>(effect) << " " << static_cast<int>(strength);
+        }
+    }
+    for (Effect effect : kEffects) {
         for (EffectStrength strength : kInvalidEffectStrengths) {
             int32_t lengthMs;
             Status status = vibrator->perform(effect, strength, nullptr /*callback*/, &lengthMs);
-            EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
+            EXPECT_EQ(status.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION)
+                    << static_cast<int>(effect) << " " << static_cast<int>(strength);
         }
     }
 }
@@ -199,6 +233,25 @@
     }
 }
 
+TEST_P(VibratorAidl, ExternalAmplitudeControl) {
+    const bool supportsExternalAmplitudeControl =
+            (capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) > 0;
+
+    if (capabilities & IVibrator::CAP_EXTERNAL_CONTROL) {
+        EXPECT_TRUE(vibrator->setExternalControl(true).isOk());
+
+        Status amplitudeStatus = vibrator->setAmplitude(128);
+        if (supportsExternalAmplitudeControl) {
+            EXPECT_TRUE(amplitudeStatus.isOk());
+        } else {
+            EXPECT_EQ(amplitudeStatus.exceptionCode(), Status::EX_UNSUPPORTED_OPERATION);
+        }
+        EXPECT_TRUE(vibrator->setExternalControl(false).isOk());
+    } else {
+        EXPECT_FALSE(supportsExternalAmplitudeControl);
+    }
+}
+
 TEST_P(VibratorAidl, ExternalControlUnsupportedMatchingCapabilities) {
     if ((capabilities & IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
         EXPECT_EQ(Status::EX_UNSUPPORTED_OPERATION,
@@ -206,7 +259,7 @@
     }
 }
 
-INSTANTIATE_TEST_SUITE_P(, VibratorAidl,
+INSTANTIATE_TEST_SUITE_P(Vibrator, VibratorAidl,
                          testing::ValuesIn(android::getAidlHalInstanceNames(IVibrator::descriptor)),
                          android::PrintInstanceNameToString);
 
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
index 97a371b..f89f7b4 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <android/log.h>
+
 #include <VtsHalHidlTargetTestBase.h>
 
 #include "wifi_hidl_call_util.h"
@@ -87,14 +89,21 @@
 }
 }  // namespace
 
-sp<IWifi> getWifi() {
-    sp<IWifi> wifi = ::testing::VtsHalHidlTargetTestBase::getService<IWifi>(
-        gEnv->getServiceName<IWifi>());
-    return wifi;
+sp<IWifi> getWifi(const std::string& instance_name) {
+    if ((!gEnv && instance_name.empty()) || (gEnv && !instance_name.empty())) {
+        ALOGE("instance_name and gEnv must have one and only one set.");
+        return nullptr;
+    }
+    if (gEnv) {
+        return ::testing::VtsHalHidlTargetTestBase::getService<IWifi>(
+            gEnv->getServiceName<IWifi>());
+    } else {
+        return IWifi::getService(instance_name);
+    }
 }
 
-sp<IWifiChip> getWifiChip() {
-    sp<IWifi> wifi = getWifi();
+sp<IWifiChip> getWifiChip(const std::string& instance_name) {
+    sp<IWifi> wifi = getWifi(instance_name);
     if (!wifi.get()) {
         return nullptr;
     }
@@ -122,8 +131,8 @@
     return status_and_chip.second;
 }
 
-sp<IWifiApIface> getWifiApIface() {
-    sp<IWifiChip> wifi_chip = getWifiChip();
+sp<IWifiApIface> getWifiApIface(const std::string& instance_name) {
+    sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
     if (!wifi_chip.get()) {
         return nullptr;
     }
@@ -137,8 +146,8 @@
     return status_and_iface.second;
 }
 
-sp<IWifiNanIface> getWifiNanIface() {
-    sp<IWifiChip> wifi_chip = getWifiChip();
+sp<IWifiNanIface> getWifiNanIface(const std::string& instance_name) {
+    sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
     if (!wifi_chip.get()) {
         return nullptr;
     }
@@ -152,8 +161,8 @@
     return status_and_iface.second;
 }
 
-sp<IWifiP2pIface> getWifiP2pIface() {
-    sp<IWifiChip> wifi_chip = getWifiChip();
+sp<IWifiP2pIface> getWifiP2pIface(const std::string& instance_name) {
+    sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
     if (!wifi_chip.get()) {
         return nullptr;
     }
@@ -167,8 +176,8 @@
     return status_and_iface.second;
 }
 
-sp<IWifiStaIface> getWifiStaIface() {
-    sp<IWifiChip> wifi_chip = getWifiChip();
+sp<IWifiStaIface> getWifiStaIface(const std::string& instance_name) {
+    sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
     if (!wifi_chip.get()) {
         return nullptr;
     }
@@ -182,8 +191,8 @@
     return status_and_iface.second;
 }
 
-sp<IWifiRttController> getWifiRttController() {
-    sp<IWifiChip> wifi_chip = getWifiChip();
+sp<IWifiRttController> getWifiRttController(const std::string& instance_name) {
+    sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
     if (!wifi_chip.get()) {
         return nullptr;
     }
@@ -206,8 +215,8 @@
                                                    configured_mode_id);
 }
 
-void stopWifi() {
-    sp<IWifi> wifi = getWifi();
+void stopWifi(const std::string& instance_name) {
+    sp<IWifi> wifi = getWifi(instance_name);
     ASSERT_NE(wifi, nullptr);
     HIDL_INVOKE(wifi, stop);
 }
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
index 7dacaf1..bdee2ec 100644
--- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
@@ -31,14 +31,21 @@
 // Note: We only have a single instance of each of these objects currently.
 // These helper functions should be modified to return vectors if we support
 // multiple instances.
-android::sp<android::hardware::wifi::V1_0::IWifi> getWifi();
-android::sp<android::hardware::wifi::V1_0::IWifiChip> getWifiChip();
-android::sp<android::hardware::wifi::V1_0::IWifiApIface> getWifiApIface();
-android::sp<android::hardware::wifi::V1_0::IWifiNanIface> getWifiNanIface();
-android::sp<android::hardware::wifi::V1_0::IWifiP2pIface> getWifiP2pIface();
-android::sp<android::hardware::wifi::V1_0::IWifiStaIface> getWifiStaIface();
+// TODO(b/143892896): Remove the default value as part of the cleanup.
+android::sp<android::hardware::wifi::V1_0::IWifi> getWifi(
+    const std::string& instance_name = "");
+android::sp<android::hardware::wifi::V1_0::IWifiChip> getWifiChip(
+    const std::string& instance_name = "");
+android::sp<android::hardware::wifi::V1_0::IWifiApIface> getWifiApIface(
+    const std::string& instance_name = "");
+android::sp<android::hardware::wifi::V1_0::IWifiNanIface> getWifiNanIface(
+    const std::string& instance_name = "");
+android::sp<android::hardware::wifi::V1_0::IWifiP2pIface> getWifiP2pIface(
+    const std::string& instance_name = "");
+android::sp<android::hardware::wifi::V1_0::IWifiStaIface> getWifiStaIface(
+    const std::string& instance_name = "");
 android::sp<android::hardware::wifi::V1_0::IWifiRttController>
-getWifiRttController();
+getWifiRttController(const std::string& instance_name = "");
 // Configure the chip in a mode to support the creation of the provided
 // iface type.
 bool configureChipToSupportIfaceType(
@@ -46,7 +53,7 @@
     android::hardware::wifi::V1_0::IfaceType type,
     android::hardware::wifi::V1_0::ChipModeId* configured_mode_id);
 // Used to trigger IWifi.stop() at the end of every test.
-void stopWifi();
+void stopWifi(const std::string& instance_name = "");
 
 class WifiHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
    protected:
diff --git a/wifi/1.4/Android.bp b/wifi/1.4/Android.bp
index aba8b44..e197859 100644
--- a/wifi/1.4/Android.bp
+++ b/wifi/1.4/Android.bp
@@ -7,8 +7,12 @@
         enabled: true,
     },
     srcs: [
+        "types.hal",
         "IWifi.hal",
         "IWifiApIface.hal",
+        "IWifiChip.hal",
+        "IWifiRttController.hal",
+        "IWifiRttControllerEventCallback.hal",
     ],
     interfaces: [
         "android.hardware.wifi@1.0",
diff --git a/wifi/1.4/IWifiApIface.hal b/wifi/1.4/IWifiApIface.hal
index af88afb..80c576d 100644
--- a/wifi/1.4/IWifiApIface.hal
+++ b/wifi/1.4/IWifiApIface.hal
@@ -49,5 +49,5 @@
      *         |WifiStatusCode.ERROR_UNKNOWN|
      * @return mac factory MAC address of the interface
      */
-     getFactoryMacAddress() generates (WifiStatus status, MacAddress mac);
+    getFactoryMacAddress() generates (WifiStatus status, MacAddress mac);
 };
diff --git a/wifi/1.4/IWifiChip.hal b/wifi/1.4/IWifiChip.hal
new file mode 100644
index 0000000..d269427
--- /dev/null
+++ b/wifi/1.4/IWifiChip.hal
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.4;
+
+import @1.0::WifiStatus;
+import @1.0::IWifiIface;
+import @1.3::IWifiChip;
+import IWifiRttController;
+
+/**
+ * Interface that represents a chip that must be configured as a single unit.
+ */
+interface IWifiChip extends @1.3::IWifiChip {
+    /**
+     * Create a RTTController instance.
+     *
+     * RTT controller can be either:
+     * a) Bound to a specific iface by passing in the corresponding |IWifiIface|
+     * object in |iface| param, OR
+     * b) Let the implementation decide the iface to use for RTT operations by
+     * passing null in |iface| param.
+     *
+     * @param boundIface HIDL interface object representing the iface if
+     *        the responder must be bound to a specific iface, null otherwise.
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|
+     */
+    createRttController_1_4(IWifiIface boundIface)
+        generates (WifiStatus status, IWifiRttController rtt);
+};
diff --git a/wifi/1.4/IWifiRttController.hal b/wifi/1.4/IWifiRttController.hal
new file mode 100644
index 0000000..5c71975
--- /dev/null
+++ b/wifi/1.4/IWifiRttController.hal
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.4;
+
+import @1.0::IWifiRttController;
+import @1.0::CommandId;
+import @1.0::WifiChannelInfo;
+import @1.0::WifiStatus;
+import IWifiRttControllerEventCallback;
+
+/**
+ * Interface used to perform RTT(Round trip time) operations.
+ */
+interface IWifiRttController extends @1.0::IWifiRttController {
+    /**
+     * Requests notifications of significant events on this rtt controller.
+     * Multiple calls to this must register multiple callbacks each of which must
+     * receive all events.
+     *
+     * @param callback An instance of the |IWifiRttControllerEventCallback| HIDL
+     *        interface object.
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
+     */
+    registerEventCallback_1_4(IWifiRttControllerEventCallback callback)
+        generates (WifiStatus status);
+
+    /**
+     * API to request RTT measurement.
+     *
+     * @param cmdId command Id to use for this invocation.
+     * @param rttConfigs Vector of |RttConfig| parameters.
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    rangeRequest_1_4(CommandId cmdId, vec<RttConfig> rttConfigs) generates (WifiStatus status);
+
+    /**
+     * RTT capabilities of the device.
+     *
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     * @return capabilities Instance of |RttCapabilities|.
+     */
+    getCapabilities_1_4() generates (WifiStatus status, RttCapabilities capabilities);
+
+    /**
+     * Get RTT responder information e.g. WiFi channel to enable responder on.
+     *
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     * @return info Instance of |RttResponderInfo|.
+     */
+    getResponderInfo_1_4() generates (WifiStatus status, RttResponder info);
+
+    /**
+     * Enable RTT responder mode.
+     *
+     * @param cmdId command Id to use for this invocation.
+     * @parm channelHint Hint of the channel information where RTT responder must
+     *       be enabled on.
+     * @param maxDurationInSeconds Timeout of responder mode.
+     * @param info Instance of |RttResponderInfo|.
+     * @return status WifiStatus of the operation.
+     *         Possible status codes:
+     *         |WifiStatusCode.SUCCESS|,
+     *         |WifiStatusCode.ERROR_WIFI_RTT_CONTROLLER_INVALID|,
+     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|,
+     *         |WifiStatusCode.ERROR_UNKNOWN|
+     */
+    enableResponder_1_4(CommandId cmdId, WifiChannelInfo channelHint,
+        uint32_t maxDurationInSeconds, RttResponder info) generates (WifiStatus status);
+};
diff --git a/wifi/1.4/IWifiRttControllerEventCallback.hal b/wifi/1.4/IWifiRttControllerEventCallback.hal
new file mode 100644
index 0000000..75de3d4
--- /dev/null
+++ b/wifi/1.4/IWifiRttControllerEventCallback.hal
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.4;
+
+import @1.0::IWifiRttControllerEventCallback;
+import @1.0::CommandId;
+
+/**
+ * RTT Response and Event Callbacks.
+ */
+interface IWifiRttControllerEventCallback extends @1.0::IWifiRttControllerEventCallback {
+    /*
+     * Invoked when an RTT result is available.
+     *
+     * @param cmdId command Id corresponding to the original request.
+     * @param results Vector of |RttResult| instances.
+     */
+    oneway onResults_1_4(CommandId cmdId, vec<RttResult> results);
+};
diff --git a/wifi/1.4/default/hidl_struct_util.cpp b/wifi/1.4/default/hidl_struct_util.cpp
index 47713cd..61f311e 100644
--- a/wifi/1.4/default/hidl_struct_util.cpp
+++ b/wifi/1.4/default/hidl_struct_util.cpp
@@ -2279,6 +2279,8 @@
             return legacy_hal::WIFI_RTT_PREAMBLE_HT;
         case RttPreamble::VHT:
             return legacy_hal::WIFI_RTT_PREAMBLE_VHT;
+        case RttPreamble::HE:
+            return legacy_hal::WIFI_RTT_PREAMBLE_HE;
     };
     CHECK(false);
 }
@@ -2291,6 +2293,8 @@
             return RttPreamble::HT;
         case legacy_hal::WIFI_RTT_PREAMBLE_VHT:
             return RttPreamble::VHT;
+        case legacy_hal::WIFI_RTT_PREAMBLE_HE:
+            return RttPreamble::HE;
     };
     CHECK(false) << "Unknown legacy type: " << type;
 }
@@ -2354,6 +2358,8 @@
             return WifiRatePreamble::HT;
         case 3:
             return WifiRatePreamble::VHT;
+        case 4:
+            return WifiRatePreamble::HE;
         default:
             return WifiRatePreamble::RESERVED;
     };
@@ -2579,9 +2585,10 @@
     hidl_capabilities->responderSupported =
         legacy_capabilities.responder_supported;
     hidl_capabilities->preambleSupport = 0;
-    for (const auto flag : {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY,
-                            legacy_hal::WIFI_RTT_PREAMBLE_HT,
-                            legacy_hal::WIFI_RTT_PREAMBLE_VHT}) {
+    for (const auto flag :
+         {legacy_hal::WIFI_RTT_PREAMBLE_LEGACY,
+          legacy_hal::WIFI_RTT_PREAMBLE_HT, legacy_hal::WIFI_RTT_PREAMBLE_VHT,
+          legacy_hal::WIFI_RTT_PREAMBLE_HE}) {
         if (legacy_capabilities.preamble_support & flag) {
             hidl_capabilities->preambleSupport |=
                 static_cast<std::underlying_type<RttPreamble>::type>(
diff --git a/wifi/1.4/default/hidl_struct_util.h b/wifi/1.4/default/hidl_struct_util.h
index c9f1c26..a99c1ac 100644
--- a/wifi/1.4/default/hidl_struct_util.h
+++ b/wifi/1.4/default/hidl_struct_util.h
@@ -25,6 +25,7 @@
 #include <android/hardware/wifi/1.2/types.h>
 #include <android/hardware/wifi/1.3/IWifiChip.h>
 #include <android/hardware/wifi/1.3/types.h>
+#include <android/hardware/wifi/1.4/types.h>
 
 #include "wifi_legacy_hal.h"
 
diff --git a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
index b0357ba..90e81e1 100644
--- a/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.4/default/tests/wifi_chip_unit_tests.cpp
@@ -252,7 +252,7 @@
 
     bool createRttController() {
         bool success = false;
-        chip_->createRttController(
+        chip_->createRttController_1_4(
             NULL, [&success](const WifiStatus& status,
                              const sp<IWifiRttController>& rtt) {
                 if (WifiStatusCode::SUCCESS == status.code) {
@@ -750,7 +750,7 @@
 
     // Create RTT controller
     sp<IWifiRttController> rtt_controller;
-    chip_->createRttController(
+    chip_->createRttController_1_4(
         NULL, [&rtt_controller](const WifiStatus& status,
                                 const sp<IWifiRttController>& rtt) {
             if (WifiStatusCode::SUCCESS == status.code) {
diff --git a/wifi/1.4/default/wifi_chip.cpp b/wifi/1.4/default/wifi_chip.cpp
index 408096f..7685ac6 100644
--- a/wifi/1.4/default/wifi_chip.cpp
+++ b/wifi/1.4/default/wifi_chip.cpp
@@ -620,6 +620,14 @@
     return Void();
 }
 
+Return<void> WifiChip::createRttController_1_4(
+    const sp<IWifiIface>& bound_iface,
+    createRttController_1_4_cb hidl_status_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::createRttControllerInternal_1_4,
+                           hidl_status_cb, bound_iface);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
     invalidateAndClearAll(ap_ifaces_);
     invalidateAndClearAll(nan_ifaces_);
@@ -669,30 +677,6 @@
     return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
 }
 
-std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
-    legacy_hal::wifi_error legacy_status;
-    uint32_t legacy_feature_set;
-    uint32_t legacy_logger_feature_set;
-    const auto ifname = getFirstActiveWlanIfaceName();
-    std::tie(legacy_status, legacy_feature_set) =
-        legacy_hal_.lock()->getSupportedFeatureSet(ifname);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), 0};
-    }
-    std::tie(legacy_status, legacy_logger_feature_set) =
-        legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        // some devices don't support querying logger feature set
-        legacy_logger_feature_set = 0;
-    }
-    uint32_t hidl_caps;
-    if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
-            legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
-}
-
 std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
 WifiChip::getAvailableModesInternal() {
     return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
@@ -996,18 +980,10 @@
     return createWifiStatus(WifiStatusCode::SUCCESS);
 }
 
-std::pair<WifiStatus, sp<IWifiRttController>>
-WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
-    if (sta_ifaces_.size() == 0 &&
-        !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
-        LOG(ERROR) << "createRttControllerInternal: Chip cannot support STAs "
-                      "(and RTT by extension)";
-        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
-    }
-    sp<WifiRttController> rtt = new WifiRttController(
-        getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
-    rtt_controllers_.emplace_back(rtt);
-    return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
+std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
+WifiChip::createRttControllerInternal(const sp<IWifiIface>& /*bound_iface*/) {
+    LOG(ERROR) << "createRttController is not supported on this HAL";
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
 }
 
 std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
@@ -1158,6 +1134,45 @@
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
+std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
+    legacy_hal::wifi_error legacy_status;
+    uint32_t legacy_feature_set;
+    uint32_t legacy_logger_feature_set;
+    const auto ifname = getFirstActiveWlanIfaceName();
+    std::tie(legacy_status, legacy_feature_set) =
+        legacy_hal_.lock()->getSupportedFeatureSet(ifname);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), 0};
+    }
+    std::tie(legacy_status, legacy_logger_feature_set) =
+        legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        // some devices don't support querying logger feature set
+        legacy_logger_feature_set = 0;
+    }
+    uint32_t hidl_caps;
+    if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
+            legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, sp<IWifiRttController>>
+WifiChip::createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface) {
+    if (sta_ifaces_.size() == 0 &&
+        !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
+        LOG(ERROR)
+            << "createRttControllerInternal_1_4: Chip cannot support STAs "
+               "(and RTT by extension)";
+        return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
+    }
+    sp<WifiRttController> rtt = new WifiRttController(
+        getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
+    rtt_controllers_.emplace_back(rtt);
+    return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
+}
+
 WifiStatus WifiChip::handleChipConfiguration(
     /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
     ChipModeId mode_id) {
diff --git a/wifi/1.4/default/wifi_chip.h b/wifi/1.4/default/wifi_chip.h
index 0d7061c..3bf1847 100644
--- a/wifi/1.4/default/wifi_chip.h
+++ b/wifi/1.4/default/wifi_chip.h
@@ -21,7 +21,8 @@
 #include <map>
 
 #include <android-base/macros.h>
-#include <android/hardware/wifi/1.3/IWifiChip.h>
+#include <android/hardware/wifi/1.4/IWifiChip.h>
+#include <android/hardware/wifi/1.4/IWifiRttController.h>
 
 #include "hidl_callback_util.h"
 #include "ringbuffer.h"
@@ -46,7 +47,7 @@
  * Since there is only a single chip instance used today, there is no
  * identifying handle information stored here.
  */
-class WifiChip : public V1_3::IWifiChip {
+class WifiChip : public V1_4::IWifiChip {
    public:
     WifiChip(
         ChipId chip_id,
@@ -152,6 +153,9 @@
         getCapabilities_cb hidl_status_cb) override;
     Return<void> debug(const hidl_handle& handle,
                        const hidl_vec<hidl_string>& options) override;
+    Return<void> createRttController_1_4(
+        const sp<IWifiIface>& bound_iface,
+        createRttController_1_4_cb hidl_status_cb) override;
 
    private:
     void invalidateAndRemoveAllIfaces();
@@ -195,8 +199,8 @@
     std::pair<WifiStatus, sp<IWifiStaIface>> getStaIfaceInternal(
         const std::string& ifname);
     WifiStatus removeStaIfaceInternal(const std::string& ifname);
-    std::pair<WifiStatus, sp<IWifiRttController>> createRttControllerInternal(
-        const sp<IWifiIface>& bound_iface);
+    std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
+    createRttControllerInternal(const sp<IWifiIface>& bound_iface);
     std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
     getDebugRingBuffersStatusInternal();
     WifiStatus startLoggingToDebugRingBufferInternal(
@@ -217,6 +221,8 @@
         const sp<V1_2::IWifiChipEventCallback>& event_callback);
     WifiStatus selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario);
     std::pair<WifiStatus, uint32_t> getCapabilitiesInternal_1_3();
+    std::pair<WifiStatus, sp<IWifiRttController>>
+    createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface);
     WifiStatus handleChipConfiguration(
         std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
     WifiStatus registerDebugRingBufferCallback();
diff --git a/wifi/1.4/default/wifi_rtt_controller.cpp b/wifi/1.4/default/wifi_rtt_controller.cpp
index d50c7cf..594a116 100644
--- a/wifi/1.4/default/wifi_rtt_controller.cpp
+++ b/wifi/1.4/default/wifi_rtt_controller.cpp
@@ -58,7 +58,7 @@
 }
 
 Return<void> WifiRttController::registerEventCallback(
-    const sp<IWifiRttControllerEventCallback>& callback,
+    const sp<V1_0::IWifiRttControllerEventCallback>& callback,
     registerEventCallback_cb hidl_status_cb) {
     return validateAndCall(this,
                            WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
@@ -67,7 +67,7 @@
 }
 
 Return<void> WifiRttController::rangeRequest(
-    uint32_t cmd_id, const hidl_vec<RttConfig>& rtt_configs,
+    uint32_t cmd_id, const hidl_vec<V1_0::RttConfig>& rtt_configs,
     rangeRequest_cb hidl_status_cb) {
     return validateAndCall(this,
                            WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
@@ -115,7 +115,7 @@
 
 Return<void> WifiRttController::enableResponder(
     uint32_t cmd_id, const WifiChannelInfo& channel_hint,
-    uint32_t max_duration_seconds, const RttResponder& info,
+    uint32_t max_duration_seconds, const V1_0::RttResponder& info,
     enableResponder_cb hidl_status_cb) {
     return validateAndCall(
         this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
@@ -130,49 +130,64 @@
         &WifiRttController::disableResponderInternal, hidl_status_cb, cmd_id);
 }
 
+Return<void> WifiRttController::registerEventCallback_1_4(
+    const sp<IWifiRttControllerEventCallback>& callback,
+    registerEventCallback_1_4_cb hidl_status_cb) {
+    return validateAndCall(
+        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+        &WifiRttController::registerEventCallbackInternal_1_4, hidl_status_cb,
+        callback);
+}
+
+Return<void> WifiRttController::rangeRequest_1_4(
+    uint32_t cmd_id, const hidl_vec<RttConfig>& rtt_configs,
+    rangeRequest_1_4_cb hidl_status_cb) {
+    return validateAndCall(this,
+                           WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+                           &WifiRttController::rangeRequestInternal_1_4,
+                           hidl_status_cb, cmd_id, rtt_configs);
+}
+
+Return<void> WifiRttController::getCapabilities_1_4(
+    getCapabilities_1_4_cb hidl_status_cb) {
+    return validateAndCall(
+        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+        &WifiRttController::getCapabilitiesInternal_1_4, hidl_status_cb);
+}
+
+Return<void> WifiRttController::getResponderInfo_1_4(
+    getResponderInfo_1_4_cb hidl_status_cb) {
+    return validateAndCall(
+        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+        &WifiRttController::getResponderInfoInternal_1_4, hidl_status_cb);
+}
+
+Return<void> WifiRttController::enableResponder_1_4(
+    uint32_t cmd_id, const WifiChannelInfo& channel_hint,
+    uint32_t max_duration_seconds, const RttResponder& info,
+    enableResponder_1_4_cb hidl_status_cb) {
+    return validateAndCall(
+        this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
+        &WifiRttController::enableResponderInternal_1_4, hidl_status_cb, cmd_id,
+        channel_hint, max_duration_seconds, info);
+}
+
 std::pair<WifiStatus, sp<IWifiIface>>
 WifiRttController::getBoundIfaceInternal() {
     return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_};
 }
 
 WifiStatus WifiRttController::registerEventCallbackInternal(
-    const sp<IWifiRttControllerEventCallback>& callback) {
-    // TODO(b/31632518): remove the callback when the client is destroyed
-    event_callbacks_.emplace_back(callback);
-    return createWifiStatus(WifiStatusCode::SUCCESS);
+    const sp<V1_0::IWifiRttControllerEventCallback>& /* callback */) {
+    // Deprecated support for this api
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
 }
 
 WifiStatus WifiRttController::rangeRequestInternal(
-    uint32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
-    std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
-    if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(
-            rtt_configs, &legacy_configs)) {
-        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
-    }
-    android::wp<WifiRttController> weak_ptr_this(this);
-    const auto& on_results_callback =
-        [weak_ptr_this](
-            legacy_hal::wifi_request_id id,
-            const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
-            const auto shared_ptr_this = weak_ptr_this.promote();
-            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
-                LOG(ERROR) << "Callback invoked on an invalid object";
-                return;
-            }
-            std::vector<RttResult> hidl_results;
-            if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(
-                    results, &hidl_results)) {
-                LOG(ERROR) << "Failed to convert rtt results to HIDL structs";
-                return;
-            }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                callback->onResults(id, hidl_results);
-            }
-        };
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->startRttRangeRequest(
-            ifname_, cmd_id, legacy_configs, on_results_callback);
-    return createWifiStatusFromLegacyError(legacy_status);
+    uint32_t /* cmd_id */,
+    const std::vector<V1_0::RttConfig>& /* rtt_configs */) {
+    // Deprecated support for this api
+    return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
 }
 
 WifiStatus WifiRttController::rangeCancelInternal(
@@ -187,21 +202,10 @@
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-std::pair<WifiStatus, RttCapabilities>
+std::pair<WifiStatus, V1_0::RttCapabilities>
 WifiRttController::getCapabilitiesInternal() {
-    legacy_hal::wifi_error legacy_status;
-    legacy_hal::wifi_rtt_capabilities legacy_caps;
-    std::tie(legacy_status, legacy_caps) =
-        legacy_hal_.lock()->getRttCapabilities(ifname_);
-    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-        return {createWifiStatusFromLegacyError(legacy_status), {}};
-    }
-    RttCapabilities hidl_caps;
-    if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps,
-                                                              &hidl_caps)) {
-        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
-    }
-    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+    // Deprecated support for this api
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
 }
 
 WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id,
@@ -228,8 +232,84 @@
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
-std::pair<WifiStatus, RttResponder>
+std::pair<WifiStatus, V1_0::RttResponder>
 WifiRttController::getResponderInfoInternal() {
+    // Deprecated support for this api
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
+}
+
+WifiStatus WifiRttController::enableResponderInternal(
+    uint32_t /* cmd_id */, const WifiChannelInfo& /* channel_hint */,
+    uint32_t /* max_duration_seconds */, const V1_0::RttResponder& /* info */) {
+    // Deprecated support for this api
+    return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED)};
+}
+
+WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) {
+    legacy_hal::wifi_error legacy_status =
+        legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+WifiStatus WifiRttController::registerEventCallbackInternal_1_4(
+    const sp<IWifiRttControllerEventCallback>& callback) {
+    // TODO(b/31632518): remove the callback when the client is destroyed
+    event_callbacks_.emplace_back(callback);
+    return createWifiStatus(WifiStatusCode::SUCCESS);
+}
+
+WifiStatus WifiRttController::rangeRequestInternal_1_4(
+    uint32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
+    std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
+    if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(
+            rtt_configs, &legacy_configs)) {
+        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
+    }
+    android::wp<WifiRttController> weak_ptr_this(this);
+    const auto& on_results_callback =
+        [weak_ptr_this](
+            legacy_hal::wifi_request_id id,
+            const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
+            const auto shared_ptr_this = weak_ptr_this.promote();
+            if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+                LOG(ERROR) << "Callback invoked on an invalid object";
+                return;
+            }
+            std::vector<RttResult> hidl_results;
+            if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(
+                    results, &hidl_results)) {
+                LOG(ERROR) << "Failed to convert rtt results to HIDL structs";
+                return;
+            }
+            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+                callback->onResults_1_4(id, hidl_results);
+            }
+        };
+    legacy_hal::wifi_error legacy_status =
+        legacy_hal_.lock()->startRttRangeRequest(
+            ifname_, cmd_id, legacy_configs, on_results_callback);
+    return createWifiStatusFromLegacyError(legacy_status);
+}
+
+std::pair<WifiStatus, RttCapabilities>
+WifiRttController::getCapabilitiesInternal_1_4() {
+    legacy_hal::wifi_error legacy_status;
+    legacy_hal::wifi_rtt_capabilities legacy_caps;
+    std::tie(legacy_status, legacy_caps) =
+        legacy_hal_.lock()->getRttCapabilities(ifname_);
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    RttCapabilities hidl_caps;
+    if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps,
+                                                              &hidl_caps)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
+}
+
+std::pair<WifiStatus, RttResponder>
+WifiRttController::getResponderInfoInternal_1_4() {
     legacy_hal::wifi_error legacy_status;
     legacy_hal::wifi_rtt_responder legacy_responder;
     std::tie(legacy_status, legacy_responder) =
@@ -245,7 +325,7 @@
     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder};
 }
 
-WifiStatus WifiRttController::enableResponderInternal(
+WifiStatus WifiRttController::enableResponderInternal_1_4(
     uint32_t cmd_id, const WifiChannelInfo& channel_hint,
     uint32_t max_duration_seconds, const RttResponder& info) {
     legacy_hal::wifi_channel_info legacy_channel_info;
@@ -264,12 +344,6 @@
             legacy_responder);
     return createWifiStatusFromLegacyError(legacy_status);
 }
-
-WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) {
-    legacy_hal::wifi_error legacy_status =
-        legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
-    return createWifiStatusFromLegacyError(legacy_status);
-}
 }  // namespace implementation
 }  // namespace V1_4
 }  // namespace wifi
diff --git a/wifi/1.4/default/wifi_rtt_controller.h b/wifi/1.4/default/wifi_rtt_controller.h
index 1415ff7..1f12555 100644
--- a/wifi/1.4/default/wifi_rtt_controller.h
+++ b/wifi/1.4/default/wifi_rtt_controller.h
@@ -19,8 +19,8 @@
 
 #include <android-base/macros.h>
 #include <android/hardware/wifi/1.0/IWifiIface.h>
-#include <android/hardware/wifi/1.0/IWifiRttController.h>
-#include <android/hardware/wifi/1.0/IWifiRttControllerEventCallback.h>
+#include <android/hardware/wifi/1.4/IWifiRttController.h>
+#include <android/hardware/wifi/1.4/IWifiRttControllerEventCallback.h>
 
 #include "wifi_legacy_hal.h"
 
@@ -33,7 +33,7 @@
 /**
  * HIDL interface object used to control all RTT operations.
  */
-class WifiRttController : public V1_0::IWifiRttController {
+class WifiRttController : public V1_4::IWifiRttController {
    public:
     WifiRttController(
         const std::string& iface_name, const sp<IWifiIface>& bound_iface,
@@ -47,10 +47,10 @@
     // HIDL methods exposed.
     Return<void> getBoundIface(getBoundIface_cb hidl_status_cb) override;
     Return<void> registerEventCallback(
-        const sp<IWifiRttControllerEventCallback>& callback,
+        const sp<V1_0::IWifiRttControllerEventCallback>& callback,
         registerEventCallback_cb hidl_status_cb) override;
     Return<void> rangeRequest(uint32_t cmd_id,
-                              const hidl_vec<RttConfig>& rtt_configs,
+                              const hidl_vec<V1_0::RttConfig>& rtt_configs,
                               rangeRequest_cb hidl_status_cb) override;
     Return<void> rangeCancel(uint32_t cmd_id,
                              const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
@@ -64,29 +64,53 @@
     Return<void> enableResponder(uint32_t cmd_id,
                                  const WifiChannelInfo& channel_hint,
                                  uint32_t max_duration_seconds,
-                                 const RttResponder& info,
+                                 const V1_0::RttResponder& info,
                                  enableResponder_cb hidl_status_cb) override;
     Return<void> disableResponder(uint32_t cmd_id,
                                   disableResponder_cb hidl_status_cb) override;
+    Return<void> registerEventCallback_1_4(
+        const sp<IWifiRttControllerEventCallback>& callback,
+        registerEventCallback_1_4_cb hidl_status_cb) override;
+    Return<void> rangeRequest_1_4(uint32_t cmd_id,
+                                  const hidl_vec<RttConfig>& rtt_configs,
+                                  rangeRequest_1_4_cb hidl_status_cb) override;
+    Return<void> getCapabilities_1_4(
+        getCapabilities_1_4_cb hidl_status_cb) override;
+    Return<void> getResponderInfo_1_4(
+        getResponderInfo_1_4_cb hidl_status_cb) override;
+    Return<void> enableResponder_1_4(
+        uint32_t cmd_id, const WifiChannelInfo& channel_hint,
+        uint32_t max_duration_seconds, const RttResponder& info,
+        enableResponder_1_4_cb hidl_status_cb) override;
 
    private:
     // Corresponding worker functions for the HIDL methods.
     std::pair<WifiStatus, sp<IWifiIface>> getBoundIfaceInternal();
     WifiStatus registerEventCallbackInternal(
-        const sp<IWifiRttControllerEventCallback>& callback);
-    WifiStatus rangeRequestInternal(uint32_t cmd_id,
-                                    const std::vector<RttConfig>& rtt_configs);
+        const sp<V1_0::IWifiRttControllerEventCallback>& callback);
+    WifiStatus rangeRequestInternal(
+        uint32_t cmd_id, const std::vector<V1_0::RttConfig>& rtt_configs);
     WifiStatus rangeCancelInternal(
         uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs);
-    std::pair<WifiStatus, RttCapabilities> getCapabilitiesInternal();
+    std::pair<WifiStatus, V1_0::RttCapabilities> getCapabilitiesInternal();
     WifiStatus setLciInternal(uint32_t cmd_id, const RttLciInformation& lci);
     WifiStatus setLcrInternal(uint32_t cmd_id, const RttLcrInformation& lcr);
-    std::pair<WifiStatus, RttResponder> getResponderInfoInternal();
+    std::pair<WifiStatus, V1_0::RttResponder> getResponderInfoInternal();
     WifiStatus enableResponderInternal(uint32_t cmd_id,
                                        const WifiChannelInfo& channel_hint,
                                        uint32_t max_duration_seconds,
-                                       const RttResponder& info);
+                                       const V1_0::RttResponder& info);
     WifiStatus disableResponderInternal(uint32_t cmd_id);
+    WifiStatus registerEventCallbackInternal_1_4(
+        const sp<IWifiRttControllerEventCallback>& callback);
+    WifiStatus rangeRequestInternal_1_4(
+        uint32_t cmd_id, const std::vector<RttConfig>& rtt_configs);
+    std::pair<WifiStatus, RttCapabilities> getCapabilitiesInternal_1_4();
+    std::pair<WifiStatus, RttResponder> getResponderInfoInternal_1_4();
+    WifiStatus enableResponderInternal_1_4(uint32_t cmd_id,
+                                           const WifiChannelInfo& channel_hint,
+                                           uint32_t max_duration_seconds,
+                                           const RttResponder& info);
 
     std::string ifname_;
     sp<IWifiIface> bound_iface_;
diff --git a/wifi/1.4/default/wifi_status_util.h b/wifi/1.4/default/wifi_status_util.h
index 41bcfaf..3ff58f0 100644
--- a/wifi/1.4/default/wifi_status_util.h
+++ b/wifi/1.4/default/wifi_status_util.h
@@ -17,7 +17,7 @@
 #ifndef WIFI_STATUS_UTIL_H_
 #define WIFI_STATUS_UTIL_H_
 
-#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/1.4/IWifi.h>
 
 #include "wifi_legacy_hal.h"
 
diff --git a/wifi/1.4/types.hal b/wifi/1.4/types.hal
new file mode 100644
index 0000000..232e26f
--- /dev/null
+++ b/wifi/1.4/types.hal
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi@1.4;
+
+import @1.0::MacAddress;
+import @1.0::Rssi;
+import @1.0::RttBw;
+import @1.0::RttConfig;
+import @1.0::RttPeerType;
+import @1.0::RttPreamble;
+import @1.0::RttStatus;
+import @1.0::RttType;
+import @1.0::TimeSpanInPs;
+import @1.0::TimeStampInUs;
+import @1.0::WifiChannelInfo;
+import @1.0::WifiChannelWidthInMhz;
+import @1.0::WifiInformationElement;
+import @1.0::WifiRateNss;
+import @1.0::WifiRatePreamble;
+
+/**
+ * Wifi Rate Preamble
+ */
+enum WifiRatePreamble : @1.0::WifiRatePreamble {
+    /**
+     * Preamble type for 11ax
+     */
+    HE = 5,
+};
+
+/**
+ * RTT Measurement Preamble.
+ */
+enum RttPreamble : @1.0::RttPreamble {
+    /**
+     * Preamble type for 11ax
+     */
+    HE = 0x8,
+};
+
+/**
+ * RTT configuration.
+ */
+struct RttConfig {
+    /**
+     * Peer device mac address.
+     */
+    MacAddress addr;
+
+    /**
+     * 1-sided or 2-sided RTT.
+     */
+    RttType type;
+
+    /**
+     * Optional - peer device hint (STA, P2P, AP).
+     */
+    RttPeerType peer;
+
+    /**
+     * Required for STA-AP mode, optional for P2P, NBD etc.
+     */
+    WifiChannelInfo channel;
+
+    /**
+     * Time interval between bursts (units: 100 ms).
+     * Applies to 1-sided and 2-sided RTT multi-burst requests.
+     * Range: 0-31, 0: no preference by initiator (2-sided RTT).
+     */
+    uint32_t burstPeriod;
+
+    /**
+     * Total number of RTT bursts to be executed. It will be
+     * specified in the same way as the parameter "Number of
+     * Burst Exponent" found in the FTM frame format. It
+     * applies to both: 1-sided RTT and 2-sided RTT. Valid
+     * values are 0 to 15 as defined in 802.11mc std.
+     * 0 means single shot
+     * The implication of this parameter on the maximum
+     * number of RTT results is the following:
+     * for 1-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst)
+     * for 2-sided RTT: max num of RTT results = (2^num_burst)*(num_frames_per_burst - 1)
+     */
+    uint32_t numBurst;
+
+    /**
+     * Num of frames per burst.
+     * Minimum value = 1, Maximum value = 31
+     * For 2-sided this equals the number of FTM frames
+     * to be attempted in a single burst. This also
+     * equals the number of FTM frames that the
+     * initiator will request that the responder send
+     * in a single frame.
+     */
+    uint32_t numFramesPerBurst;
+
+    /**
+     * Number of retries for a failed RTT frame.
+     * Applies to 1-sided RTT only. Minimum value = 0, Maximum value = 3
+     */
+    uint32_t numRetriesPerRttFrame;
+
+    /**
+     * Following fields are only valid for 2-side RTT.
+     *
+     *
+     * Maximum number of retries that the initiator can
+     * retry an FTMR frame.
+     * Minimum value = 0, Maximum value = 3
+     */
+    uint32_t numRetriesPerFtmr;
+
+    /**
+     * Whether to request location civic info or not.
+     */
+    bool mustRequestLci;
+
+    /**
+     * Whether to request location civic records or not.
+     */
+    bool mustRequestLcr;
+
+    /**
+     * Applies to 1-sided and 2-sided RTT. Valid values will
+     * be 2-11 and 15 as specified by the 802.11mc std for
+     * the FTM parameter burst duration. In a multi-burst
+     * request, if responder overrides with larger value,
+     * the initiator will return failure. In a single-burst
+     * request if responder overrides with larger value,
+     * the initiator will sent TMR_STOP to terminate RTT
+     * at the end of the burst_duration it requested.
+     */
+    uint32_t burstDuration;
+
+    /**
+     * RTT preamble to be used in the RTT frames.
+     */
+    RttPreamble preamble;
+
+    /**
+     * RTT BW to be used in the RTT frames.
+     */
+    RttBw bw;
+};
+
+/**
+ * RTT Capabilities.
+ */
+struct RttCapabilities {
+    /**
+     * if 1-sided rtt data collection is supported.
+     */
+    bool rttOneSidedSupported;
+
+    /**
+     * if ftm rtt data collection is supported.
+     */
+    bool rttFtmSupported;
+
+    /**
+     * if initiator supports LCI request. Applies to 2-sided RTT.
+     */
+    bool lciSupported;
+
+    /**
+     * if initiator supports LCR request. Applies to 2-sided RTT.
+     */
+    bool lcrSupported;
+
+    /**
+     * if 11mc responder mode is supported.
+     */
+    bool responderSupported;
+
+    /**
+     * Bit mask indicates what preamble is supported by initiator.
+     * Combination of |RttPreamble| values.
+     */
+    bitfield<RttPreamble> preambleSupport;
+
+    /**
+     * Bit mask indicates what BW is supported by initiator.
+     * Combination of |RttBw| values.
+     */
+    bitfield<RttBw> bwSupport;
+
+    /**
+     * Draft 11mc spec version supported by chip.
+     * For instance, version 4.0 must be 40 and version 4.3 must be 43 etc.
+     */
+    uint8_t mcVersion;
+};
+
+/**
+ * RTT Responder information
+ */
+struct RttResponder {
+    WifiChannelInfo channel;
+
+    RttPreamble preamble;
+};
+
+/**
+ * Wifi rate info.
+ */
+struct WifiRateInfo {
+    /**
+     * Preamble used for RTT measurements.
+     */
+    WifiRatePreamble preamble;
+
+    /**
+     * Number of spatial streams.
+     */
+    WifiRateNss nss;
+
+    /**
+     * Bandwidth of channel.
+     */
+    WifiChannelWidthInMhz bw;
+
+    /**
+     * OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps.
+     * HT/VHT/HE it would be mcs index.
+     */
+    uint8_t rateMcsIdx;
+
+    /**
+     * Bitrate in units of 100 Kbps.
+     */
+    uint32_t bitRateInKbps;
+};
+
+/**
+ * RTT results.
+ */
+struct RttResult {
+    /**
+     * Peer device mac address.
+     */
+    MacAddress addr;
+
+    /**
+     * Burst number in a multi-burst request.
+     */
+    uint32_t burstNum;
+
+    /**
+     * Total RTT measurement frames attempted.
+     */
+    uint32_t measurementNumber;
+
+    /**
+     * Total successful RTT measurement frames.
+     */
+    uint32_t successNumber;
+
+    /**
+     * Maximum number of "FTM frames per burst" supported by
+     * the responder STA. Applies to 2-sided RTT only.
+     * If reponder overrides with larger value:
+     * - for single-burst request initiator will truncate the
+     * larger value and send a TMR_STOP after receiving as
+     * many frames as originally requested.
+     * - for multi-burst request, initiator will return
+     * failure right away.
+     */
+    uint8_t numberPerBurstPeer;
+
+    /**
+     * Ranging status.
+     */
+    RttStatus status;
+
+    /**
+     * When status == RTT_STATUS_FAIL_BUSY_TRY_LATER,
+     * this will be the time provided by the responder as to
+     * when the request can be tried again. Applies to 2-sided
+     * RTT only. In sec, 1-31sec.
+     */
+    uint8_t retryAfterDuration;
+
+    /**
+     * RTT type.
+     */
+    RttType type;
+
+    /**
+     * Average rssi in 0.5 dB steps e.g. 143 implies -71.5 dB.
+     */
+    Rssi rssi;
+
+    /**
+     * Rssi spread in 0.5 dB steps e.g. 5 implies 2.5 dB spread (optional).
+     */
+    Rssi rssiSpread;
+
+    /**
+     * 1-sided RTT: TX rate of RTT frame.
+     * 2-sided RTT: TX rate of initiator's Ack in response to FTM frame.
+     */
+    WifiRateInfo txRate;
+
+    /**
+     * 1-sided RTT: TX rate of Ack from other side.
+     * 2-sided RTT: TX rate of FTM frame coming from responder.
+     */
+    WifiRateInfo rxRate;
+
+    /**
+     * Round trip time in picoseconds
+     */
+    TimeSpanInPs rtt;
+
+    /**
+     * Rtt standard deviation in picoseconds.
+     */
+    TimeSpanInPs rttSd;
+
+    /**
+     * Difference between max and min rtt times recorded in picoseconds.
+     */
+    TimeSpanInPs rttSpread;
+
+    /**
+     * Distance in mm (optional).
+     */
+    int32_t distanceInMm;
+
+    /**
+     * Standard deviation in mm (optional).
+     */
+    int32_t distanceSdInMm;
+
+    /**
+     * Difference between max and min distance recorded in mm (optional).
+     */
+    int32_t distanceSpreadInMm;
+
+    /**
+     * Time of the measurement (in microseconds since boot).
+     */
+    TimeStampInUs timeStampInUs;
+
+    /**
+     * in ms, actual time taken by the FW to finish one burst
+     * measurement. Applies to 1-sided and 2-sided RTT.
+     */
+    uint32_t burstDurationInMs;
+
+    /**
+     * Number of bursts allowed by the responder. Applies
+     * to 2-sided RTT only.
+     */
+    uint32_t negotiatedBurstNum;
+
+    /**
+     * for 11mc only.
+     */
+    WifiInformationElement lci;
+
+    /**
+     * for 11mc only.
+     */
+    WifiInformationElement lcr;
+};
diff --git a/wifi/hostapd/1.0/vts/functional/Android.bp b/wifi/hostapd/1.0/vts/functional/Android.bp
index 5645019..b53d002 100644
--- a/wifi/hostapd/1.0/vts/functional/Android.bp
+++ b/wifi/hostapd/1.0/vts/functional/Android.bp
@@ -49,5 +49,5 @@
         "libwifi-system",
         "libwifi-system-iface",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
diff --git a/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp b/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp
index 0303b20..4b62b15 100644
--- a/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp
+++ b/wifi/hostapd/1.0/vts/functional/VtsHalWifiHostapdV1_0TargetTest.cpp
@@ -14,36 +14,8 @@
  * limitations under the License.
  */
 
-#include <android-base/logging.h>
-#include <android/hardware/wifi/1.0/IWifi.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 
-#include "hostapd_hidl_test_utils.h"
-
-class WifiHostapdHidlEnvironment_1_0 : public WifiHostapdHidlEnvironment {
-   public:
-    // get the test environment singleton
-    static WifiHostapdHidlEnvironment_1_0* Instance() {
-        static WifiHostapdHidlEnvironment_1_0* instance =
-            new WifiHostapdHidlEnvironment_1_0;
-        return instance;
-    }
-
-    virtual void registerTestServices() override {
-        registerTestService<::android::hardware::wifi::V1_0::IWifi>();
-        registerTestService<android::hardware::wifi::hostapd::V1_0::IHostapd>();
-    }
-
-   private:
-    WifiHostapdHidlEnvironment_1_0() {}
-};
-
-WifiHostapdHidlEnvironment* gEnv = WifiHostapdHidlEnvironment_1_0::Instance();
-
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
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 8ee71fb..5a978ca 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test.cpp
@@ -17,18 +17,22 @@
 #include <android-base/logging.h>
 #include <cutils/properties.h>
 
-#include <VtsHalHidlTargetTestBase.h>
-
+#include <android/hardware/wifi/1.0/IWifi.h>
 #include <android/hardware/wifi/hostapd/1.0/IHostapd.h>
 
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
 #include "hostapd_hidl_call_util.h"
 #include "hostapd_hidl_test_utils.h"
 
 using ::android::sp;
 using ::android::hardware::hidl_vec;
-using ::android::hardware::wifi::hostapd::V1_0::IHostapd;
 using ::android::hardware::wifi::hostapd::V1_0::HostapdStatus;
 using ::android::hardware::wifi::hostapd::V1_0::HostapdStatusCode;
+using ::android::hardware::wifi::hostapd::V1_0::IHostapd;
+using ::android::hardware::wifi::V1_0::IWifi;
 
 namespace {
 constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
@@ -38,16 +42,20 @@
 constexpr int kIfaceInvalidChannel = 567;
 }  // namespace
 
-class HostapdHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class HostapdHidlTest
+    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
    public:
     virtual void SetUp() override {
-        stopSupplicantIfNeeded();
-        startHostapdAndWaitForHidlService();
-        hostapd_ = getHostapd();
+        wifi_instance_name_ = std::get<0>(GetParam());
+        hostapd_instance_name_ = std::get<1>(GetParam());
+        stopSupplicantIfNeeded(wifi_instance_name_);
+        startHostapdAndWaitForHidlService(wifi_instance_name_,
+                                          hostapd_instance_name_);
+        hostapd_ = IHostapd::getService(hostapd_instance_name_);
         ASSERT_NE(hostapd_.get(), nullptr);
     }
 
-    virtual void TearDown() override { stopHostapd(); }
+    virtual void TearDown() override { stopHostapd(wifi_instance_name_); }
 
    protected:
     std::string getPrimaryWlanIfaceName() {
@@ -121,6 +129,8 @@
     }
     // IHostapd object used for all tests in this fixture.
     sp<IHostapd> hostapd_;
+    std::string wifi_instance_name_;
+    std::string hostapd_instance_name_;
 };
 
 /*
@@ -128,17 +138,19 @@
  * Ensures that an instance of the IHostapd proxy object is
  * successfully created.
  */
-TEST(HostapdHidlTestNoFixture, Create) {
-    startHostapdAndWaitForHidlService();
-    EXPECT_NE(nullptr, getHostapd().get());
-    stopHostapd();
+TEST_P(HostapdHidlTest, Create) {
+    stopHostapd(wifi_instance_name_);
+    startHostapdAndWaitForHidlService(wifi_instance_name_,
+                                      hostapd_instance_name_);
+    sp<IHostapd> hostapd = IHostapd::getService(hostapd_instance_name_);
+    EXPECT_NE(nullptr, hostapd.get());
 }
 
 /**
  * Adds an access point with PSK network config & ACS enabled.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddPskAccessPointWithAcs) {
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
     if (!is_1_1(hostapd_)) {
         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
                                   getIfaceParamsWithAcs(), getPskNwParams());
@@ -151,7 +163,7 @@
  * Adds an access point with Open network config & ACS enabled.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddOpenAccessPointWithAcs) {
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
     if (!is_1_1(hostapd_)) {
         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
                                   getIfaceParamsWithAcs(), getOpenNwParams());
@@ -164,7 +176,7 @@
  * Adds an access point with PSK network config & ACS disabled.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
+TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
     if (!is_1_1(hostapd_)) {
         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
                                   getIfaceParamsWithoutAcs(), getPskNwParams());
@@ -176,7 +188,7 @@
  * Adds an access point with Open network config & ACS disabled.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
     if (!is_1_1(hostapd_)) {
         auto status =
             HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithoutAcs(),
@@ -189,7 +201,7 @@
  * Adds & then removes an access point with PSK network config & ACS enabled.
  * Access point creation & removal should pass.
  */
-TEST_F(HostapdHidlTest, RemoveAccessPointWithAcs) {
+TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
     if (!is_1_1(hostapd_)) {
         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
                                   getIfaceParamsWithAcs(), getPskNwParams());
@@ -207,7 +219,7 @@
  * Adds & then removes an access point with PSK network config & ACS disabled.
  * Access point creation & removal should pass.
  */
-TEST_F(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
+TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
     if (!is_1_1(hostapd_)) {
         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
                                   getIfaceParamsWithoutAcs(), getPskNwParams());
@@ -222,7 +234,7 @@
  * Adds an access point with invalid channel.
  * Access point creation should fail.
  */
-TEST_F(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
     if (!is_1_1(hostapd_)) {
         auto status =
             HIDL_INVOKE(hostapd_, addAccessPoint,
@@ -235,7 +247,7 @@
  * Adds an access point with invalid PSK network config.
  * Access point creation should fail.
  */
-TEST_F(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
     if (!is_1_1(hostapd_)) {
         auto status =
             HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithoutAcs(),
@@ -248,6 +260,13 @@
  * Terminate
  * This terminates the service.
  */
-TEST_F(HostapdHidlTest, Terminate) {
-    hostapd_->terminate();
-}
+TEST_P(HostapdHidlTest, Terminate) { hostapd_->terminate(); }
+
+INSTANTIATE_TEST_SUITE_P(
+    PerInstance, HostapdHidlTest,
+    testing::Combine(
+        testing::ValuesIn(
+            android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+        testing::ValuesIn(
+            android::hardware::getAllHalInstanceNames(IHostapd::descriptor))),
+    android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
index 1c499e7..6058fd2 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.cpp
@@ -44,13 +44,11 @@
 using ::android::wifi_system::HostapdManager;
 using ::android::wifi_system::SupplicantManager;
 
-extern WifiHostapdHidlEnvironment* gEnv;
-
 namespace {
 // Helper function to initialize the driver and firmware to AP mode
 // using the vendor HAL HIDL interface.
-void initilializeDriverAndFirmware() {
-    sp<IWifiChip> wifi_chip = getWifiChip();
+void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+    sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
     ChipModeId mode_id;
     EXPECT_TRUE(configureChipToSupportIfaceType(
         wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::AP, &mode_id));
@@ -58,7 +56,9 @@
 
 // Helper function to deinitialize the driver and firmware
 // using the vendor HAL HIDL interface.
-void deInitilializeDriverAndFirmware() { stopWifi(); }
+void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
+    stopWifi(wifi_instance_name);
+}
 }  // namespace
 
 // Utility class to wait for wpa_hostapd's HIDL service registration.
@@ -110,45 +110,42 @@
     std::condition_variable condition_;
 };
 
-void stopSupplicantIfNeeded() {
+void stopSupplicantIfNeeded(const std::string& instance_name) {
     SupplicantManager supplicant_manager;
     if (supplicant_manager.IsSupplicantRunning()) {
         LOG(INFO) << "Supplicant is running, stop supplicant first.";
         ASSERT_TRUE(supplicant_manager.StopSupplicant());
-        deInitilializeDriverAndFirmware();
+        deInitilializeDriverAndFirmware(instance_name);
         ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
     }
 }
 
-void stopHostapd() {
+void stopHostapd(const std::string& instance_name) {
     HostapdManager hostapd_manager;
 
     ASSERT_TRUE(hostapd_manager.StopHostapd());
-    deInitilializeDriverAndFirmware();
+    deInitilializeDriverAndFirmware(instance_name);
 }
 
-void startHostapdAndWaitForHidlService() {
-    initilializeDriverAndFirmware();
+void startHostapdAndWaitForHidlService(
+    const std::string& wifi_instance_name,
+    const std::string& hostapd_instance_name) {
+    initilializeDriverAndFirmware(wifi_instance_name);
 
     android::sp<ServiceNotificationListener> notification_listener =
         new ServiceNotificationListener();
-    string service_name = gEnv->getServiceName<IHostapd>();
     ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
-        service_name));
+        hostapd_instance_name));
 
     HostapdManager hostapd_manager;
     ASSERT_TRUE(hostapd_manager.StartHostapd());
 
-    ASSERT_TRUE(notification_listener->waitForHidlService(200, service_name));
+    ASSERT_TRUE(
+        notification_listener->waitForHidlService(500, hostapd_instance_name));
 }
 
 bool is_1_1(const sp<IHostapd>& hostapd) {
     sp<::android::hardware::wifi::hostapd::V1_1::IHostapd> hostapd_1_1 =
         ::android::hardware::wifi::hostapd::V1_1::IHostapd::castFrom(hostapd);
     return hostapd_1_1.get() != nullptr;
-}
-
-sp<IHostapd> getHostapd() {
-    return ::testing::VtsHalHidlTargetTestBase::getService<IHostapd>(
-        gEnv->getServiceName<IHostapd>());
-}
+}
\ No newline at end of file
diff --git a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
index 9b3df42..5cb4f01 100644
--- a/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
+++ b/wifi/hostapd/1.0/vts/functional/hostapd_hidl_test_utils.h
@@ -20,32 +20,18 @@
 #include <android/hardware/wifi/hostapd/1.0/IHostapd.h>
 #include <android/hardware/wifi/hostapd/1.1/IHostapd.h>
 
-#include <VtsHalHidlTargetTestEnvBase.h>
-
 // Used to stop the android wifi framework before every test.
-void stopWifiFramework();
-void startWifiFramework();
-void stopSupplicantIfNeeded();
-void stopHostapd();
+void stopWifiFramework(const std::string& instance_name);
+void startWifiFramework(const std::string& instance_name);
+void stopSupplicantIfNeeded(const std::string& instance_name);
+void stopHostapd(const std::string& instance_name);
 // Used to configure the chip, driver and start wpa_hostapd before every
 // test.
-void startHostapdAndWaitForHidlService();
+void startHostapdAndWaitForHidlService(
+    const std::string& wifi_instance_name,
+    const std::string& hostapd_instance_name);
 
-// Helper functions to obtain references to the various HIDL interface objects.
-// Note: We only have a single instance of each of these objects currently.
-// These helper functions should be modified to return vectors if we support
-// multiple instances.
-android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd> getHostapd();
 bool is_1_1(const android::sp<android::hardware::wifi::hostapd::V1_0::IHostapd>&
                 hostapd);
 
-class WifiHostapdHidlEnvironment
-    : public ::testing::VtsHalHidlTargetTestEnvBase {
-   public:
-    virtual void HidlSetUp() override { stopHostapd(); }
-    virtual void HidlTearDown() override {
-        startHostapdAndWaitForHidlService();
-    }
-};
-
 #endif /* HOSTAPD_HIDL_TEST_UTILS_H */
diff --git a/wifi/hostapd/1.1/vts/functional/Android.bp b/wifi/hostapd/1.1/vts/functional/Android.bp
index 02ec2e6..c963fe3 100644
--- a/wifi/hostapd/1.1/vts/functional/Android.bp
+++ b/wifi/hostapd/1.1/vts/functional/Android.bp
@@ -14,25 +14,6 @@
 // limitations under the License.
 //
 
-cc_library_static {
-    name: "VtsHalWifiHostapdV1_1TargetTestUtil",
-    defaults: ["VtsHalTargetTestDefaults"],
-    srcs: ["hostapd_hidl_test_utils_1_1.cpp"],
-    export_include_dirs: [
-        "."
-    ],
-    static_libs: [
-        "VtsHalWifiV1_0TargetTestUtil",
-        "VtsHalWifiHostapdV1_0TargetTestUtil",
-        "android.hardware.wifi.hostapd@1.0",
-        "android.hardware.wifi.hostapd@1.1",
-        "android.hardware.wifi@1.0",
-        "libgmock",
-        "libwifi-system",
-        "libwifi-system-iface",
-    ],
-}
-
 cc_test {
     name: "VtsHalWifiHostapdV1_1TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
@@ -43,7 +24,6 @@
     static_libs: [
         "VtsHalWifiV1_0TargetTestUtil",
         "VtsHalWifiHostapdV1_0TargetTestUtil",
-        "VtsHalWifiHostapdV1_1TargetTestUtil",
         "android.hardware.wifi.hostapd@1.0",
         "android.hardware.wifi.hostapd@1.1",
         "android.hardware.wifi@1.0",
@@ -51,6 +31,6 @@
         "libwifi-system",
         "libwifi-system-iface",
     ],
-    test_suites: ["general-tests"],
+    test_suites: ["general-tests", "vts-core"],
 }
 
diff --git a/wifi/hostapd/1.1/vts/functional/VtsHalWifiHostapdV1_1TargetTest.cpp b/wifi/hostapd/1.1/vts/functional/VtsHalWifiHostapdV1_1TargetTest.cpp
index 6916db2..7e0f3cd 100644
--- a/wifi/hostapd/1.1/vts/functional/VtsHalWifiHostapdV1_1TargetTest.cpp
+++ b/wifi/hostapd/1.1/vts/functional/VtsHalWifiHostapdV1_1TargetTest.cpp
@@ -14,38 +14,8 @@
  * limitations under the License.
  */
 
-#include <android-base/logging.h>
-#include <android/hardware/wifi/1.0/IWifi.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
 
-#include "hostapd_hidl_test_utils.h"
-#include "hostapd_hidl_test_utils_1_1.h"
-
-class WifiHostapdHidlEnvironment_1_1 : public WifiHostapdHidlEnvironment {
-   public:
-    // get the test environment singleton
-    static WifiHostapdHidlEnvironment_1_1* Instance() {
-        static WifiHostapdHidlEnvironment_1_1* instance =
-            new WifiHostapdHidlEnvironment_1_1;
-        return instance;
-    }
-
-    virtual void registerTestServices() override {
-        registerTestService<::android::hardware::wifi::V1_0::IWifi>();
-        registerTestService<android::hardware::wifi::hostapd::V1_0::IHostapd>();
-        registerTestService<android::hardware::wifi::hostapd::V1_1::IHostapd>();
-    }
-
-   private:
-    WifiHostapdHidlEnvironment_1_1() {}
-};
-
-WifiHostapdHidlEnvironment* gEnv = WifiHostapdHidlEnvironment_1_1::Instance();
-
-int main(int argc, char** argv) {
-    ::testing::AddGlobalTestEnvironment(gEnv);
-    ::testing::InitGoogleTest(&argc, argv);
-    gEnv->init(&argc, argv);
-    int status = RUN_ALL_TESTS();
-    LOG(INFO) << "Test result = " << status;
-    return status;
-}
+// TODO(b/143892896): Remove this file after wifi_hidl_test_utils.cpp is
+// updated.
+::testing::VtsHalHidlTargetTestEnvBase* gEnv = nullptr;
\ No newline at end of file
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 b053549..1804d8c 100644
--- a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp
+++ b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test.cpp
@@ -17,13 +17,15 @@
 #include <android-base/logging.h>
 #include <cutils/properties.h>
 
-#include <VtsHalHidlTargetTestBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
 
+#include <android/hardware/wifi/1.0/IWifi.h>
 #include <android/hardware/wifi/hostapd/1.1/IHostapd.h>
 
 #include "hostapd_hidl_call_util.h"
 #include "hostapd_hidl_test_utils.h"
-#include "hostapd_hidl_test_utils_1_1.h"
 
 using ::android::sp;
 using ::android::hardware::hidl_string;
@@ -33,6 +35,7 @@
 using ::android::hardware::wifi::hostapd::V1_0::HostapdStatusCode;
 using ::android::hardware::wifi::hostapd::V1_1::IHostapd;
 using ::android::hardware::wifi::hostapd::V1_1::IHostapdCallback;
+using ::android::hardware::wifi::V1_0::IWifi;
 
 namespace {
 constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
@@ -42,16 +45,20 @@
 constexpr int kIfaceInvalidChannel = 567;
 }  // namespace
 
-class HostapdHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class HostapdHidlTest
+    : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
    public:
     virtual void SetUp() override {
-        stopSupplicantIfNeeded();
-        startHostapdAndWaitForHidlService();
-        hostapd_ = getHostapd_1_1();
+        wifi_instance_name_ = std::get<0>(GetParam());
+        hostapd_instance_name_ = std::get<1>(GetParam());
+        stopSupplicantIfNeeded(wifi_instance_name_);
+        startHostapdAndWaitForHidlService(wifi_instance_name_,
+                                          hostapd_instance_name_);
+        hostapd_ = IHostapd::getService(hostapd_instance_name_);
         ASSERT_NE(hostapd_.get(), nullptr);
     }
 
-    virtual void TearDown() override { stopHostapd(); }
+    virtual void TearDown() override { stopHostapd(wifi_instance_name_); }
 
    protected:
     std::string getPrimaryWlanIfaceName() {
@@ -152,6 +159,8 @@
 
     // IHostapd object used for all tests in this fixture.
     sp<IHostapd> hostapd_;
+    std::string wifi_instance_name_;
+    std::string hostapd_instance_name_;
 };
 
 class IfaceCallback : public IHostapdCallback {
@@ -164,7 +173,7 @@
 /*
  * RegisterCallback
  */
-TEST_F(HostapdHidlTest, registerCallback) {
+TEST_P(HostapdHidlTest, registerCallback) {
     hostapd_->registerCallback(
         new IfaceCallback(), [](const HostapdStatus& status) {
             EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -175,7 +184,7 @@
  * Adds an access point with PSK network config & ACS enabled.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddPskAccessPointWithAcs) {
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                               getIfaceParamsWithAcs(), getPskNwParams());
     // TODO: b/140172237, fix this in R.
@@ -186,7 +195,7 @@
  * Adds an access point with PSK network config, ACS enabled & channel Range.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddPskAccessPointWithAcsAndChannelRange) {
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndChannelRange) {
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                     getIfaceParamsWithAcsAndChannelRange(), getPskNwParams());
@@ -198,7 +207,7 @@
  * Adds an access point with invalid channel range.
  * Access point creation should fail.
  */
-TEST_F(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidChannelRange) {
+TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidChannelRange) {
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                               getIfaceParamsWithAcsAndInvalidChannelRange(),
                               getPskNwParams());
@@ -210,7 +219,7 @@
  * Adds an access point with Open network config & ACS enabled.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddOpenAccessPointWithAcs) {
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                               getIfaceParamsWithAcs(), getOpenNwParams());
     // TODO: b/140172237, fix this in R
@@ -221,7 +230,7 @@
  * Adds an access point with PSK network config & ACS disabled.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
+TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                               getIfaceParamsWithoutAcs(), getPskNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -231,7 +240,7 @@
  * Adds an access point with Open network config & ACS disabled.
  * Access point creation should pass.
  */
-TEST_F(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
+TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                               getIfaceParamsWithoutAcs(), getOpenNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -241,7 +250,7 @@
  * Adds & then removes an access point with PSK network config & ACS enabled.
  * Access point creation & removal should pass.
  */
-TEST_F(HostapdHidlTest, RemoveAccessPointWithAcs) {
+TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                               getIfaceParamsWithAcs(), getPskNwParams());
     // TODO: b/140172237, fix this in R
@@ -257,7 +266,7 @@
  * Adds & then removes an access point with PSK network config & ACS disabled.
  * Access point creation & removal should pass.
  */
-TEST_F(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
+TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                               getIfaceParamsWithoutAcs(), getPskNwParams());
     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
@@ -270,7 +279,7 @@
  * Adds an access point with invalid channel.
  * Access point creation should fail.
  */
-TEST_F(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
+TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
                     getIfaceParamsWithInvalidChannel(), getPskNwParams());
@@ -281,9 +290,18 @@
  * Adds an access point with invalid PSK network config.
  * Access point creation should fail.
  */
-TEST_F(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
+TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
     auto status =
         HIDL_INVOKE(hostapd_, addAccessPoint_1_1, getIfaceParamsWithoutAcs(),
                     getInvalidPskNwParams());
     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
 }
+
+INSTANTIATE_TEST_CASE_P(
+    PerInstance, HostapdHidlTest,
+    testing::Combine(
+        testing::ValuesIn(
+            android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
+        testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+            android::hardware::wifi::hostapd::V1_1::IHostapd::descriptor))),
+    android::hardware::PrintInstanceTupleNameToString<>);
diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.cpp b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.cpp
deleted file mode 100644
index 8bb72a1..0000000
--- a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <android-base/logging.h>
-
-#include "hostapd_hidl_test_utils.h"
-#include "hostapd_hidl_test_utils_1_1.h"
-
-using ::android::sp;
-using ::android::hardware::wifi::hostapd::V1_1::IHostapd;
-
-sp<IHostapd> getHostapd_1_1() { return IHostapd::castFrom(getHostapd()); }
diff --git a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.h b/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.h
deleted file mode 100644
index c43ddfa..0000000
--- a/wifi/hostapd/1.1/vts/functional/hostapd_hidl_test_utils_1_1.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef HOSTAPD_HIDL_TEST_UTILS_1_1_H
-#define HOSTAPD_HIDL_TEST_UTILS_1_1_H
-
-#include <android/hardware/wifi/hostapd/1.1/IHostapd.h>
-
-#include <VtsHalHidlTargetTestEnvBase.h>
-
-// Helper functions to obtain references to the various HIDL interface objects.
-// Note: We only have a single instance of each of these objects currently.
-// These helper functions should be modified to return vectors if we support
-// multiple instances.
-android::sp<android::hardware::wifi::hostapd::V1_1::IHostapd> getHostapd_1_1();
-
-#endif /* HOSTAPD_HIDL_TEST_UTILS_1_1_H */
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 47c3056..7bd04dc 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
@@ -175,7 +175,7 @@
     ASSERT_TRUE(supplicant_manager.StartSupplicant());
     ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
 
-    ASSERT_TRUE(notification_listener->waitForHidlService(200, service_name));
+    ASSERT_TRUE(notification_listener->waitForHidlService(500, service_name));
 }
 
 bool is_1_1(const sp<ISupplicant>& supplicant) {
diff --git a/wifi/supplicant/1.3/ISupplicantStaIface.hal b/wifi/supplicant/1.3/ISupplicantStaIface.hal
index cb207d8..bfd8946 100644
--- a/wifi/supplicant/1.3/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaIface.hal
@@ -54,4 +54,26 @@
      */
     getConnectionCapabilities()
         generates (SupplicantStatus status, ConnectionCapabilities capabilities);
+
+    /**
+     * Get wpa driver capabilities.
+     *
+     * @return status Status of the operation, and a bitmap of wpa driver features.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     */
+    getWpaDriverCapabilities() generates (SupplicantStatus status,
+        bitfield<WpaDriverCapabilitiesMask> driverCapabilitiesMask);
+
+    /**
+     * Set MBO cellular data status.
+     *
+     * @param available true means cellular data available, false otherwise.
+     * @return status Status of the operation.
+     *         Possible status codes:
+     *         |SupplicantStatusCode.SUCCESS|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    setMboCellularDataStatus(bool available) generates (SupplicantStatus status);
 };
diff --git a/wifi/supplicant/1.3/types.hal b/wifi/supplicant/1.3/types.hal
index 7874399..4e01ab1 100644
--- a/wifi/supplicant/1.3/types.hal
+++ b/wifi/supplicant/1.3/types.hal
@@ -58,3 +58,17 @@
      */
     WifiTechnology technology;
 };
+
+/**
+ * WPA Driver capability.
+ */
+enum WpaDriverCapabilitiesMask : uint32_t {
+    /**
+     * Multi Band Operation.
+     */
+    MBO = 1 << 0,
+    /**
+     * Optimized Connectivity Experience.
+     */
+    OCE = 1 << 1,
+};
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 62f3228..2cf5881 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
@@ -41,6 +41,7 @@
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface;
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIfaceCallback;
 using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
+using ::android::hardware::wifi::supplicant::V1_3::WpaDriverCapabilitiesMask;
 
 class SupplicantStaIfaceHidlTest : public ::testing::VtsHalHidlTargetTestBase {
    public:
@@ -191,3 +192,38 @@
             EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
         });
 }
+
+/*
+ * GetWpaDriverCapabilities
+ */
+TEST_F(SupplicantStaIfaceHidlTest, GetWpaDriverCapabilities) {
+    sta_iface_->getWpaDriverCapabilities(
+        [&](const SupplicantStatus& status, uint32_t) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+        });
+}
+
+/*
+ * SetMboCellularDataStatus
+ */
+TEST_F(SupplicantStaIfaceHidlTest, SetMboCellularDataStatus) {
+    uint32_t driverCapMask = 0;
+
+    // Get MBO support from the device.
+    sta_iface_->getWpaDriverCapabilities(
+        [&](const SupplicantStatus& status, uint32_t driverCapMaskInternal) {
+            EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+
+            driverCapMask = driverCapMaskInternal;
+        });
+
+    SupplicantStatusCode expectedStatusCode =
+        (driverCapMask & WpaDriverCapabilitiesMask::MBO)
+            ? SupplicantStatusCode::SUCCESS
+            : SupplicantStatusCode::FAILURE_UNKNOWN;
+
+    sta_iface_->setMboCellularDataStatus(
+        true, [expectedStatusCode](const SupplicantStatus& status) {
+            EXPECT_EQ(expectedStatusCode, status.code);
+        });
+}