Merge "vts: Correct the test RSA key format"
diff --git a/audio/7.0/IStreamOutEventCallback.hal b/audio/7.0/IStreamOutEventCallback.hal
index 4de767f..8ef0060 100644
--- a/audio/7.0/IStreamOutEventCallback.hal
+++ b/audio/7.0/IStreamOutEventCallback.hal
@@ -51,6 +51,25 @@
      * "has-atmos", int32
      * "audio-encoding", int32
      *
+     * S (audio HAL 7.0) in addition adds the following keys:
+     * "presentation-id", int32
+     * "program-id", int32
+     * "presentation-content-classifier", int32
+     *    presentation-content-classifier key values can be referenced from
+     *    frameworks/base/media/java/android/media/AudioPresentation.java
+     *    i.e AudioPresentation.ContentClassifier
+     *    It can contain any of the below values
+     *    CONTENT_UNKNOWN   = -1,
+     *    CONTENT_MAIN      =  0,
+     *    CONTENT_MUSIC_AND_EFFECTS = 1,
+     *    CONTENT_VISUALLY_IMPAIRED = 2,
+     *    CONTENT_HEARING_IMPAIRED  = 3,
+     *    CONTENT_DIALOG = 4,
+     *    CONTENT_COMMENTARY = 5,
+     *    CONTENT_EMERGENCY = 6,
+     *    CONTENT_VOICEOVER = 7
+     * "presentation-language", string  // represents ISO 639-2 (three letter code)
+     *
      * Parceling Format:
      * All values are native endian order. [1]
      *
diff --git a/audio/core/all-versions/default/TEST_MAPPING b/audio/core/all-versions/default/TEST_MAPPING
index d53c97a..1e29440 100644
--- a/audio/core/all-versions/default/TEST_MAPPING
+++ b/audio/core/all-versions/default/TEST_MAPPING
@@ -2,6 +2,12 @@
   "presubmit": [
     {
       "name": "android.hardware.audio@7.0-util_tests"
+    },
+    {
+      "name": "HalAudioV6_0GeneratorTest"
+    },
+    {
+      "name": "HalAudioV7_0GeneratorTest"
     }
   ]
 }
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 0ebe4c2..8af4c78 100644
--- a/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/6.0/AudioPrimaryHidlHalTest.cpp
@@ -17,105 +17,6 @@
 // pull in all the <= 5.0 tests
 #include "5.0/AudioPrimaryHidlHalTest.cpp"
 
-#if MAJOR_VERSION <= 6
-static std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(
-        bool oneProfilePerDevice) {
-    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(
-                        std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
-                        std::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.
-                    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(AudioOutputFlag::COMPRESS_OFFLOAD |
-                                                            AudioOutputFlag::DIRECT));
-                    } else {
-                        if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {  // ignore the flag
-                            flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
-                        }
-                        result.emplace_back(device, config, AudioOutputFlag(flags));
-                    }
-                    if (oneProfilePerDevice) break;
-                }
-                if (oneProfilePerDevice) break;
-            }
-            if (oneProfilePerDevice) break;
-        }
-    }
-    return result;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
-    static std::vector<DeviceConfigParameter> parameters =
-            generateOutputDeviceConfigParameters(false);
-    return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
-    static std::vector<DeviceConfigParameter> parameters =
-            generateOutputDeviceConfigParameters(true);
-    return parameters;
-}
-
-static std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(
-        bool oneProfilePerDevice) {
-    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(
-                        std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
-                        std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
-                        profile->getFormat());
-                for (const auto& config : configs) {
-                    result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
-                    if (oneProfilePerDevice) break;
-                }
-                if (oneProfilePerDevice) break;
-            }
-            if (oneProfilePerDevice) break;
-        }
-    }
-    return result;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
-    static std::vector<DeviceConfigParameter> parameters =
-            generateInputDeviceConfigParameters(false);
-    return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
-    static std::vector<DeviceConfigParameter> parameters =
-            generateInputDeviceConfigParameters(true);
-    return parameters;
-}
-#endif  // MAJOR_VERSION <= 6
-
 class SingleConfigOutputStreamTest : public OutputStreamTest {};
 TEST_P(SingleConfigOutputStreamTest, CloseDeviceWithOpenedOutputStreams) {
     doc::test("Verify that a device can't be closed if there are output streams opened");
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.cpp b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
new file mode 100644
index 0000000..6b4dbc1
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/macros.h>
+
+#include "6.0/Generators.h"
+#include "ConfigHelper.h"
+#include "PolicyConfig.h"
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+// Forward declaration for functions that are substituted
+// in generator unit tests.
+const PolicyConfig& getCachedPolicyConfig();
+const std::vector<DeviceParameter>& getDeviceParameters();
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+
+std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
+    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(
+                        std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+                        std::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.
+                    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(AudioOutputFlag::COMPRESS_OFFLOAD |
+                                                            AudioOutputFlag::DIRECT));
+                    } else {
+                        if (flags & AUDIO_OUTPUT_FLAG_PRIMARY) {  // ignore the flag
+                            flags &= ~AUDIO_OUTPUT_FLAG_PRIMARY;
+                        }
+                        result.emplace_back(device, config, AudioOutputFlag(flags));
+                    }
+                    if (oneProfilePerDevice) break;
+                }
+                if (oneProfilePerDevice) break;
+            }
+            if (oneProfilePerDevice) break;
+        }
+    }
+    return result;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters =
+            generateOutputDeviceConfigParameters(false);
+    return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters =
+            generateOutputDeviceConfigParameters(true);
+    return parameters;
+}
+
+std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
+    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(
+                        std::vector<audio_channel_mask_t>(channels.begin(), channels.end()),
+                        std::vector<uint32_t>(sampleRates.begin(), sampleRates.end()),
+                        profile->getFormat());
+                for (const auto& config : configs) {
+                    result.emplace_back(device, config, AudioInputFlag(ioProfile->getFlags()));
+                    if (oneProfilePerDevice) break;
+                }
+                if (oneProfilePerDevice) break;
+            }
+            if (oneProfilePerDevice) break;
+        }
+    }
+    return result;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters =
+            generateInputDeviceConfigParameters(false);
+    return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters =
+            generateInputDeviceConfigParameters(true);
+    return parameters;
+}
diff --git a/audio/core/all-versions/vts/functional/6.0/Generators.h b/audio/core/all-versions/vts/functional/6.0/Generators.h
new file mode 100644
index 0000000..1e87163
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/6.0/Generators.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "AudioTestDefinitions.h"
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
+
+// For unit tests
+std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice);
+std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice);
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index be1ffbb..c1923f1 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -14,277 +14,11 @@
  * limitations under the License.
  */
 
+#include "Generators.h"
+
 // pull in all the <= 6.0 tests
 #include "6.0/AudioPrimaryHidlHalTest.cpp"
 
-static std::vector<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannelMask> channelMasks,
-                                                   std::vector<int64_t> sampleRates,
-                                                   const std::string& format) {
-    std::vector<AudioConfig> configs;
-    configs.reserve(channelMasks.size() * sampleRates.size());
-    for (auto channelMask : channelMasks) {
-        for (auto sampleRate : sampleRates) {
-            AudioConfig config{};
-            config.base.channelMask = toString(channelMask);
-            config.base.sampleRateHz = sampleRate;
-            config.base.format = format;
-            configs.push_back(config);
-        }
-    }
-    return configs;
-}
-
-static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
-        const xsd::MixPorts::MixPort& mixPort) {
-    static const std::vector<AudioInOutFlag> offloadFlags = {
-            toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
-            toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
-    std::vector<AudioInOutFlag> flags;
-    bool isOffload = false;
-    if (mixPort.hasFlags()) {
-        auto xsdFlags = mixPort.getFlags();
-        isOffload = std::find(xsdFlags.begin(), xsdFlags.end(),
-                              xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
-                    xsdFlags.end();
-        if (!isOffload) {
-            for (auto flag : xsdFlags) {
-                if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
-                    flags.push_back(toString(flag));
-                }
-            }
-        } else {
-            flags = offloadFlags;
-        }
-    }
-    return {flags, isOffload};
-}
-
-static AudioOffloadInfo generateOffloadInfo(const AudioConfigBase& base) {
-    return AudioOffloadInfo{
-            .base = base,
-            .streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC),
-            .usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
-            .bitRatePerSecond = 320,
-            .durationMicroseconds = -1,
-            .bitWidth = 16,
-            .bufferSize = 256  // arbitrary value
-    };
-}
-
-static std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(
-        bool oneProfilePerDevice) {
-    std::vector<DeviceConfigParameter> result;
-    for (const auto& device : getDeviceParameters()) {
-        auto module =
-                getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
-        if (!module || !module->getFirstMixPorts()) break;
-        for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
-            if (mixPort.getRole() != xsd::Role::source) continue;  // not an output profile
-            auto [flags, isOffload] = generateOutFlags(mixPort);
-            for (const auto& profile : mixPort.getProfile()) {
-                auto configs = combineAudioConfig(profile.getChannelMasks(),
-                                                  profile.getSamplingRates(), profile.getFormat());
-                for (auto& config : configs) {
-                    // Some combinations of flags declared in the config file require special
-                    // treatment.
-                    if (isOffload) {
-                        config.offloadInfo.info(generateOffloadInfo(config.base));
-                    }
-                    result.emplace_back(device, config, flags);
-                    if (oneProfilePerDevice) break;
-                }
-                if (oneProfilePerDevice) break;
-            }
-            if (oneProfilePerDevice) break;
-        }
-    }
-    return result;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
-    static std::vector<DeviceConfigParameter> parameters =
-            generateOutputDeviceConfigParameters(false);
-    return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
-    static std::vector<DeviceConfigParameter> parameters =
-            generateOutputDeviceConfigParameters(true);
-    return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
-        bool generateInvalidFlags = true) {
-    static std::vector<DeviceConfigParameter> parameters = [&] {
-        std::vector<DeviceConfigParameter> result;
-        for (const auto& device : getDeviceParameters()) {
-            auto module =
-                    getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
-            if (!module || !module->getFirstMixPorts()) break;
-            bool hasRegularConfig = false, hasOffloadConfig = false;
-            for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
-                if (mixPort.getRole() != xsd::Role::source) continue;  // not an output profile
-                auto [validFlags, isOffload] = generateOutFlags(mixPort);
-                if ((!isOffload && hasRegularConfig) || (isOffload && hasOffloadConfig)) continue;
-                for (const auto& profile : mixPort.getProfile()) {
-                    if (!profile.hasFormat() || !profile.hasSamplingRates() ||
-                        !profile.hasChannelMasks())
-                        continue;
-                    AudioConfigBase validBase = {
-                            profile.getFormat(),
-                            static_cast<uint32_t>(profile.getSamplingRates()[0]),
-                            toString(profile.getChannelMasks()[0])};
-                    {
-                        AudioConfig config{.base = validBase};
-                        config.base.channelMask = "random_string";
-                        if (isOffload) {
-                            config.offloadInfo.info(generateOffloadInfo(validBase));
-                        }
-                        result.emplace_back(device, config, validFlags);
-                    }
-                    {
-                        AudioConfig config{.base = validBase};
-                        config.base.format = "random_string";
-                        if (isOffload) {
-                            config.offloadInfo.info(generateOffloadInfo(validBase));
-                        }
-                        result.emplace_back(device, config, validFlags);
-                    }
-                    if (generateInvalidFlags) {
-                        AudioConfig config{.base = validBase};
-                        if (isOffload) {
-                            config.offloadInfo.info(generateOffloadInfo(validBase));
-                        }
-                        std::vector<AudioInOutFlag> flags = {"random_string", ""};
-                        result.emplace_back(device, config, flags);
-                    }
-                    if (isOffload) {
-                        {
-                            AudioConfig config{.base = validBase};
-                            config.offloadInfo.info(generateOffloadInfo(validBase));
-                            config.offloadInfo.info().base.channelMask = "random_string";
-                        }
-                        {
-                            AudioConfig config{.base = validBase};
-                            config.offloadInfo.info(generateOffloadInfo(validBase));
-                            config.offloadInfo.info().base.format = "random_string";
-                        }
-                        {
-                            AudioConfig config{.base = validBase};
-                            config.offloadInfo.info(generateOffloadInfo(validBase));
-                            config.offloadInfo.info().streamType = "random_string";
-                        }
-                        {
-                            AudioConfig config{.base = validBase};
-                            config.offloadInfo.info(generateOffloadInfo(validBase));
-                            config.offloadInfo.info().usage = "random_string";
-                        }
-                        hasOffloadConfig = true;
-                    } else {
-                        hasRegularConfig = true;
-                    }
-                    break;
-                }
-                if (hasOffloadConfig && hasRegularConfig) break;
-            }
-        }
-        return result;
-    }();
-    return parameters;
-}
-
-static std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(
-        bool oneProfilePerDevice) {
-    std::vector<DeviceConfigParameter> result;
-    for (const auto& device : getDeviceParameters()) {
-        auto module =
-                getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
-        if (!module || !module->getFirstMixPorts()) break;
-        for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
-            if (mixPort.getRole() != xsd::Role::sink) continue;  // not an input profile
-            std::vector<AudioInOutFlag> flags;
-            if (mixPort.hasFlags()) {
-                std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
-                               std::back_inserter(flags), [](auto flag) { return toString(flag); });
-            }
-            for (const auto& profile : mixPort.getProfile()) {
-                auto configs = combineAudioConfig(profile.getChannelMasks(),
-                                                  profile.getSamplingRates(), profile.getFormat());
-                for (const auto& config : configs) {
-                    result.emplace_back(device, config, flags);
-                    if (oneProfilePerDevice) break;
-                }
-                if (oneProfilePerDevice) break;
-            }
-            if (oneProfilePerDevice) break;
-        }
-    }
-    return result;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
-    static std::vector<DeviceConfigParameter> parameters =
-            generateInputDeviceConfigParameters(false);
-    return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
-    static std::vector<DeviceConfigParameter> parameters =
-            generateInputDeviceConfigParameters(true);
-    return parameters;
-}
-
-const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
-        bool generateInvalidFlags = true) {
-    static std::vector<DeviceConfigParameter> parameters = [&] {
-        std::vector<DeviceConfigParameter> result;
-        for (const auto& device : getDeviceParameters()) {
-            auto module =
-                    getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
-            if (!module || !module->getFirstMixPorts()) break;
-            bool hasConfig = false;
-            for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
-                if (mixPort.getRole() != xsd::Role::sink) continue;  // not an input profile
-                std::vector<AudioInOutFlag> validFlags;
-                if (mixPort.hasFlags()) {
-                    std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
-                                   std::back_inserter(validFlags),
-                                   [](auto flag) { return toString(flag); });
-                }
-                for (const auto& profile : mixPort.getProfile()) {
-                    if (!profile.hasFormat() || !profile.hasSamplingRates() ||
-                        !profile.hasChannelMasks())
-                        continue;
-                    AudioConfigBase validBase = {
-                            profile.getFormat(),
-                            static_cast<uint32_t>(profile.getSamplingRates()[0]),
-                            toString(profile.getChannelMasks()[0])};
-                    {
-                        AudioConfig config{.base = validBase};
-                        config.base.channelMask = "random_string";
-                        result.emplace_back(device, config, validFlags);
-                    }
-                    {
-                        AudioConfig config{.base = validBase};
-                        config.base.format = "random_string";
-                        result.emplace_back(device, config, validFlags);
-                    }
-                    if (generateInvalidFlags) {
-                        AudioConfig config{.base = validBase};
-                        std::vector<AudioInOutFlag> flags = {"random_string", ""};
-                        result.emplace_back(device, config, flags);
-                    }
-                    hasConfig = true;
-                    break;
-                }
-                if (hasConfig) break;
-            }
-        }
-        return result;
-    }();
-    return parameters;
-}
-
 class InvalidInputConfigNoFlagsTest : public AudioHidlTestWithDeviceConfigParameter {};
 TEST_P(InvalidInputConfigNoFlagsTest, InputBufferSizeTest) {
     doc::test("Verify that invalid config is rejected by IDevice::getInputBufferSize method.");
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.cpp b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
new file mode 100644
index 0000000..eafc813
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/macros.h>
+
+#include "7.0/Generators.h"
+#include "7.0/PolicyConfig.h"
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+#include <android_audio_policy_configuration_V7_0-enums.h>
+#include <android_audio_policy_configuration_V7_0.h>
+
+// Forward declaration for functions that are substituted
+// in generator unit tests.
+const PolicyConfig& getCachedPolicyConfig();
+const std::vector<DeviceParameter>& getDeviceParameters();
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+namespace xsd {
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
+}
+
+static std::vector<AudioConfig> combineAudioConfig(std::vector<xsd::AudioChannelMask> channelMasks,
+                                                   std::vector<int64_t> sampleRates,
+                                                   const std::string& format) {
+    std::vector<AudioConfig> configs;
+    configs.reserve(channelMasks.size() * sampleRates.size());
+    for (auto channelMask : channelMasks) {
+        for (auto sampleRate : sampleRates) {
+            AudioConfig config{};
+            config.base.channelMask = toString(channelMask);
+            config.base.sampleRateHz = sampleRate;
+            config.base.format = format;
+            configs.push_back(config);
+        }
+    }
+    return configs;
+}
+
+static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
+        const xsd::MixPorts::MixPort& mixPort) {
+    static const std::vector<AudioInOutFlag> offloadFlags = {
+            toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
+            toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
+    std::vector<AudioInOutFlag> flags;
+    bool isOffload = false;
+    if (mixPort.hasFlags()) {
+        auto xsdFlags = mixPort.getFlags();
+        isOffload = std::find(xsdFlags.begin(), xsdFlags.end(),
+                              xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
+                    xsdFlags.end();
+        if (!isOffload) {
+            for (auto flag : xsdFlags) {
+                if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
+                    flags.push_back(toString(flag));
+                }
+            }
+        } else {
+            flags = offloadFlags;
+        }
+    }
+    return {flags, isOffload};
+}
+
+static AudioOffloadInfo generateOffloadInfo(const AudioConfigBase& base) {
+    return AudioOffloadInfo{
+            .base = base,
+            .streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC),
+            .usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
+            .bitRatePerSecond = 320,
+            .durationMicroseconds = -1,
+            .bitWidth = 16,
+            .bufferSize = 256  // arbitrary value
+    };
+}
+
+std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice) {
+    std::vector<DeviceConfigParameter> result;
+    for (const auto& device : getDeviceParameters()) {
+        auto module =
+                getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+        if (!module || !module->getFirstMixPorts()) break;
+        for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+            if (mixPort.getRole() != xsd::Role::source) continue;  // not an output profile
+            auto [flags, isOffload] = generateOutFlags(mixPort);
+            for (const auto& profile : mixPort.getProfile()) {
+                auto configs = combineAudioConfig(profile.getChannelMasks(),
+                                                  profile.getSamplingRates(), profile.getFormat());
+                for (auto& config : configs) {
+                    // Some combinations of flags declared in the config file require special
+                    // treatment.
+                    if (isOffload) {
+                        config.offloadInfo.info(generateOffloadInfo(config.base));
+                    }
+                    result.emplace_back(device, config, flags);
+                    if (oneProfilePerDevice) break;
+                }
+                if (oneProfilePerDevice) break;
+            }
+            if (oneProfilePerDevice) break;
+        }
+    }
+    return result;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters =
+            generateOutputDeviceConfigParameters(false);
+    return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters =
+            generateOutputDeviceConfigParameters(true);
+    return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
+        bool generateInvalidFlags) {
+    static std::vector<DeviceConfigParameter> parameters = [&] {
+        std::vector<DeviceConfigParameter> result;
+        for (const auto& device : getDeviceParameters()) {
+            auto module =
+                    getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+            if (!module || !module->getFirstMixPorts()) break;
+            bool hasRegularConfig = false, hasOffloadConfig = false;
+            for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+                if (mixPort.getRole() != xsd::Role::source) continue;  // not an output profile
+                auto [validFlags, isOffload] = generateOutFlags(mixPort);
+                if ((!isOffload && hasRegularConfig) || (isOffload && hasOffloadConfig)) continue;
+                for (const auto& profile : mixPort.getProfile()) {
+                    if (!profile.hasFormat() || !profile.hasSamplingRates() ||
+                        !profile.hasChannelMasks())
+                        continue;
+                    AudioConfigBase validBase = {
+                            profile.getFormat(),
+                            static_cast<uint32_t>(profile.getSamplingRates()[0]),
+                            toString(profile.getChannelMasks()[0])};
+                    {
+                        AudioConfig config{.base = validBase};
+                        config.base.channelMask = "random_string";
+                        if (isOffload) {
+                            config.offloadInfo.info(generateOffloadInfo(validBase));
+                        }
+                        result.emplace_back(device, config, validFlags);
+                    }
+                    {
+                        AudioConfig config{.base = validBase};
+                        config.base.format = "random_string";
+                        if (isOffload) {
+                            config.offloadInfo.info(generateOffloadInfo(validBase));
+                        }
+                        result.emplace_back(device, config, validFlags);
+                    }
+                    if (generateInvalidFlags) {
+                        AudioConfig config{.base = validBase};
+                        if (isOffload) {
+                            config.offloadInfo.info(generateOffloadInfo(validBase));
+                        }
+                        std::vector<AudioInOutFlag> flags = {"random_string", ""};
+                        result.emplace_back(device, config, flags);
+                    }
+                    if (isOffload) {
+                        {
+                            AudioConfig config{.base = validBase};
+                            config.offloadInfo.info(generateOffloadInfo(validBase));
+                            config.offloadInfo.info().base.channelMask = "random_string";
+                            result.emplace_back(device, config, validFlags);
+                        }
+                        {
+                            AudioConfig config{.base = validBase};
+                            config.offloadInfo.info(generateOffloadInfo(validBase));
+                            config.offloadInfo.info().base.format = "random_string";
+                            result.emplace_back(device, config, validFlags);
+                        }
+                        {
+                            AudioConfig config{.base = validBase};
+                            config.offloadInfo.info(generateOffloadInfo(validBase));
+                            config.offloadInfo.info().streamType = "random_string";
+                            result.emplace_back(device, config, validFlags);
+                        }
+                        {
+                            AudioConfig config{.base = validBase};
+                            config.offloadInfo.info(generateOffloadInfo(validBase));
+                            config.offloadInfo.info().usage = "random_string";
+                            result.emplace_back(device, config, validFlags);
+                        }
+                        hasOffloadConfig = true;
+                    } else {
+                        hasRegularConfig = true;
+                    }
+                    break;
+                }
+                if (hasOffloadConfig && hasRegularConfig) break;
+            }
+        }
+        return result;
+    }();
+    return parameters;
+}
+
+std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice) {
+    std::vector<DeviceConfigParameter> result;
+    for (const auto& device : getDeviceParameters()) {
+        auto module =
+                getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+        if (!module || !module->getFirstMixPorts()) break;
+        for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+            if (mixPort.getRole() != xsd::Role::sink) continue;  // not an input profile
+            std::vector<AudioInOutFlag> flags;
+            if (mixPort.hasFlags()) {
+                std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
+                               std::back_inserter(flags), [](auto flag) { return toString(flag); });
+            }
+            for (const auto& profile : mixPort.getProfile()) {
+                auto configs = combineAudioConfig(profile.getChannelMasks(),
+                                                  profile.getSamplingRates(), profile.getFormat());
+                for (const auto& config : configs) {
+                    result.emplace_back(device, config, flags);
+                    if (oneProfilePerDevice) break;
+                }
+                if (oneProfilePerDevice) break;
+            }
+            if (oneProfilePerDevice) break;
+        }
+    }
+    return result;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters =
+            generateInputDeviceConfigParameters(false);
+    return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters() {
+    static std::vector<DeviceConfigParameter> parameters =
+            generateInputDeviceConfigParameters(true);
+    return parameters;
+}
+
+const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
+        bool generateInvalidFlags) {
+    static std::vector<DeviceConfigParameter> parameters = [&] {
+        std::vector<DeviceConfigParameter> result;
+        for (const auto& device : getDeviceParameters()) {
+            auto module =
+                    getCachedPolicyConfig().getModuleFromName(std::get<PARAM_DEVICE_NAME>(device));
+            if (!module || !module->getFirstMixPorts()) break;
+            bool hasConfig = false;
+            for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
+                if (mixPort.getRole() != xsd::Role::sink) continue;  // not an input profile
+                std::vector<AudioInOutFlag> validFlags;
+                if (mixPort.hasFlags()) {
+                    std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
+                                   std::back_inserter(validFlags),
+                                   [](auto flag) { return toString(flag); });
+                }
+                for (const auto& profile : mixPort.getProfile()) {
+                    if (!profile.hasFormat() || !profile.hasSamplingRates() ||
+                        !profile.hasChannelMasks())
+                        continue;
+                    AudioConfigBase validBase = {
+                            profile.getFormat(),
+                            static_cast<uint32_t>(profile.getSamplingRates()[0]),
+                            toString(profile.getChannelMasks()[0])};
+                    {
+                        AudioConfig config{.base = validBase};
+                        config.base.channelMask = "random_string";
+                        result.emplace_back(device, config, validFlags);
+                    }
+                    {
+                        AudioConfig config{.base = validBase};
+                        config.base.format = "random_string";
+                        result.emplace_back(device, config, validFlags);
+                    }
+                    if (generateInvalidFlags) {
+                        AudioConfig config{.base = validBase};
+                        std::vector<AudioInOutFlag> flags = {"random_string", ""};
+                        result.emplace_back(device, config, flags);
+                    }
+                    hasConfig = true;
+                    break;
+                }
+                if (hasConfig) break;
+            }
+        }
+        return result;
+    }();
+    return parameters;
+}
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.h b/audio/core/all-versions/vts/functional/7.0/Generators.h
new file mode 100644
index 0000000..e36cfad
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "AudioTestDefinitions.h"
+
+const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
+const std::vector<DeviceConfigParameter>& getOutputDeviceInvalidConfigParameters(
+        bool generateInvalidFlags = true);
+const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
+const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
+const std::vector<DeviceConfigParameter>& getInputDeviceInvalidConfigParameters(
+        bool generateInvalidFlags = true);
+
+// For unit tests
+std::vector<DeviceConfigParameter> generateOutputDeviceConfigParameters(bool oneProfilePerDevice);
+std::vector<DeviceConfigParameter> generateInputDeviceConfigParameters(bool oneProfilePerDevice);
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
index 7d88642..feb4d4b 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
@@ -16,11 +16,35 @@
 
 #pragma once
 
-// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
-// and thus it doesn't have all '#include' and 'using' directives required
-// for a standalone compilation.
+#include <fcntl.h>
+#include <unistd.h>
 
+#include <optional>
+#include <set>
+#include <string>
+
+#include <gtest/gtest.h>
+#include <system/audio_config.h>
+#include <utils/Errors.h>
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+#include <android_audio_policy_configuration_V7_0-enums.h>
+#include <android_audio_policy_configuration_V7_0.h>
+
+#include "DeviceManager.h"
+
+using ::android::NO_INIT;
+using ::android::OK;
+using ::android::status_t;
+
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
 namespace xsd {
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
 using Module = Modules::Module;
 }
 
@@ -30,20 +54,13 @@
         : mConfigFileName{configFileName},
           mFilePath{findExistingConfigurationFile(mConfigFileName)},
           mConfig{xsd::read(mFilePath.c_str())} {
-        if (mConfig) {
-            mStatus = OK;
-            mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
-            if (mConfig->getFirstModules()) {
-                for (const auto& module : mConfig->getFirstModules()->get_module()) {
-                    if (module.getFirstAttachedDevices()) {
-                        auto attachedDevices = module.getFirstAttachedDevices()->getItem();
-                        if (!attachedDevices.empty()) {
-                            mModulesWithDevicesNames.insert(module.getName());
-                        }
-                    }
-                }
-            }
-        }
+        init();
+    }
+    PolicyConfig(const std::string& configPath, const std::string& configFileName)
+        : mConfigFileName{configFileName},
+          mFilePath{configPath + "/" + mConfigFileName},
+          mConfig{xsd::read(mFilePath.c_str())} {
+        init();
     }
     status_t getStatus() const { return mStatus; }
     std::string getError() const {
@@ -87,6 +104,22 @@
         }
         return std::string{};
     }
+    void init() {
+        if (mConfig) {
+            mStatus = OK;
+            mPrimaryModule = getModuleFromName(DeviceManager::kPrimaryDevice);
+            if (mConfig->getFirstModules()) {
+                for (const auto& module : mConfig->getFirstModules()->get_module()) {
+                    if (module.getFirstAttachedDevices()) {
+                        auto attachedDevices = module.getFirstAttachedDevices()->getItem();
+                        if (!attachedDevices.empty()) {
+                            mModulesWithDevicesNames.insert(module.getName());
+                        }
+                    }
+                }
+            }
+        }
+    }
 
     const std::string mConfigFileName;
     const std::string mFilePath;
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index 4520dc3..91c54dc 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -126,6 +126,7 @@
     defaults: ["VtsHalAudioTargetTest_defaults"],
     srcs: [
         "6.0/AudioPrimaryHidlHalTest.cpp",
+        "6.0/Generators.cpp",
     ],
     static_libs: [
         "libaudiofoundation",
@@ -152,6 +153,7 @@
     defaults: ["VtsHalAudioTargetTest_defaults"],
     srcs: [
         "7.0/AudioPrimaryHidlHalTest.cpp",
+        "7.0/Generators.cpp",
     ],
     generated_headers: ["audio_policy_configuration_V7_0_parser"],
     generated_sources: ["audio_policy_configuration_V7_0_parser"],
@@ -172,3 +174,57 @@
     // TODO(b/146104851): Add auto-gen rules and remove it.
     test_config: "VtsHalAudioV7_0TargetTest.xml",
 }
+
+// Note: the following aren't VTS tests, but rather unit tests
+// to verify correctness of test parameter generator utilities.
+cc_test {
+    name: "HalAudioV6_0GeneratorTest",
+    defaults: ["VtsHalAudioTargetTest_defaults"],
+    srcs: [
+        "6.0/Generators.cpp",
+        "tests/generators_tests.cpp",
+    ],
+    static_libs: [
+        "android.hardware.audio@6.0",
+        "android.hardware.audio.common@6.0",
+        "libaudiofoundation",
+        "libaudiopolicycomponents",
+        "libmedia_helper",
+    ],
+    cflags: [
+        "-DMAJOR_VERSION=6",
+        "-DMINOR_VERSION=0",
+        "-include common/all-versions/VersionMacro.h",
+    ],
+    data: [
+        "tests/apm_config_no_vx.xml",
+        "tests/apm_config_with_vx.xml",
+    ],
+    test_config: "tests/HalAudioV6_0GeneratorTest.xml",
+}
+
+cc_test {
+    name: "HalAudioV7_0GeneratorTest",
+    defaults: ["VtsHalAudioTargetTest_defaults"],
+    srcs: [
+        "7.0/Generators.cpp",
+        "tests/generators_tests.cpp",
+    ],
+    generated_headers: ["audio_policy_configuration_V7_0_parser"],
+    generated_sources: ["audio_policy_configuration_V7_0_parser"],
+    static_libs: [
+        "android.hardware.audio@7.0",
+        "android.hardware.audio.common@7.0",
+        "android.hardware.audio.common@7.0-enums",
+    ],
+    cflags: [
+        "-DMAJOR_VERSION=7",
+        "-DMINOR_VERSION=0",
+        "-include common/all-versions/VersionMacro.h",
+    ],
+    data: [
+        "tests/apm_config_no_vx_7_0.xml",
+        "tests/apm_config_with_vx_7_0.xml",
+    ],
+    test_config: "tests/HalAudioV7_0GeneratorTest.xml",
+}
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 61e99e8..56939fe 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -59,6 +59,7 @@
 #include "utility/ReturnIn.h"
 #include "utility/ValidateXml.h"
 
+#include "AudioTestDefinitions.h"
 /** Provide version specific functions that are used in the generic tests */
 #if MAJOR_VERSION == 2
 #include "2.0/AudioPrimaryHidlHalUtils.h"
@@ -107,7 +108,11 @@
 #include "DeviceManager.h"
 #if MAJOR_VERSION <= 6
 #include "PolicyConfig.h"
+#if MAJOR_VERSION == 6
+#include "6.0/Generators.h"
+#endif
 #elif MAJOR_VERSION >= 7
+#include "7.0/Generators.h"
 #include "7.0/PolicyConfig.h"
 #endif
 
@@ -175,9 +180,6 @@
 //////////////////// Test parameter types and definitions ////////////////////
 //////////////////////////////////////////////////////////////////////////////
 
-enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
-using DeviceParameter = std::tuple<std::string, std::string>;
-
 static inline std::string DeviceParameterToString(
         const ::testing::TestParamInfo<DeviceParameter>& info) {
     const auto& deviceName = std::get<PARAM_DEVICE_NAME>(info.param);
@@ -509,24 +511,6 @@
 // list is empty, this isn't a problem.
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioPatchHidlTest);
 
-// 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, PARAM_FLAGS };
-#if MAJOR_VERSION <= 6
-enum { INDEX_INPUT, INDEX_OUTPUT };
-using DeviceConfigParameter =
-        std::tuple<DeviceParameter, AudioConfig, std::variant<AudioInputFlag, AudioOutputFlag>>;
-#elif MAJOR_VERSION >= 7
-using DeviceConfigParameter = std::tuple<DeviceParameter, AudioConfig, std::vector<AudioInOutFlag>>;
-#endif
-
-#if MAJOR_VERSION >= 6
-const std::vector<DeviceConfigParameter>& getInputDeviceConfigParameters();
-const std::vector<DeviceConfigParameter>& getInputDeviceSingleConfigParameters();
-const std::vector<DeviceConfigParameter>& getOutputDeviceConfigParameters();
-const std::vector<DeviceConfigParameter>& getOutputDeviceSingleConfigParameters();
-#endif
-
 #if MAJOR_VERSION >= 4
 static std::string SanitizeStringForGTestName(const std::string& s) {
     std::string result = s;
diff --git a/audio/core/all-versions/vts/functional/AudioTestDefinitions.h b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
new file mode 100644
index 0000000..5b14a21
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <tuple>
+#include <variant>
+#include <vector>
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
+using DeviceParameter = std::tuple<std::string, std::string>;
+
+// 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, PARAM_FLAGS };
+#if MAJOR_VERSION <= 6
+enum { INDEX_INPUT, INDEX_OUTPUT };
+using DeviceConfigParameter =
+        std::tuple<DeviceParameter, android::hardware::audio::common::CPP_VERSION::AudioConfig,
+                   std::variant<android::hardware::audio::common::CPP_VERSION::AudioInputFlag,
+                                android::hardware::audio::common::CPP_VERSION::AudioOutputFlag>>;
+#elif MAJOR_VERSION >= 7
+using DeviceConfigParameter =
+        std::tuple<DeviceParameter, android::hardware::audio::common::CPP_VERSION::AudioConfig,
+                   std::vector<android::hardware::audio::CPP_VERSION::AudioInOutFlag>>;
+#endif
diff --git a/audio/core/all-versions/vts/functional/ConfigHelper.h b/audio/core/all-versions/vts/functional/ConfigHelper.h
index 1a1dbea..a2bb1ee 100644
--- a/audio/core/all-versions/vts/functional/ConfigHelper.h
+++ b/audio/core/all-versions/vts/functional/ConfigHelper.h
@@ -16,10 +16,21 @@
 
 #pragma once
 
-// Code in this file uses 'getCachedPolicyConfig'
-#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
-#error Must be included from AudioPrimaryHidlTest.h
-#endif
+#include <common/all-versions/VersionUtils.h>
+
+#include "PolicyConfig.h"
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+using ::android::hardware::audio::common::utils::EnumBitfield;
+using ::android::hardware::audio::common::utils::mkEnumBitfield;
+
+// Forward declaration for functions that are substituted
+// in generator unit tests.
+const PolicyConfig& getCachedPolicyConfig();
 
 //////////////////////////////////////////////////////////////////////////////
 //////////////// Required and recommended audio format support ///////////////
@@ -35,7 +46,7 @@
     // FIXME: in the next audio HAL version, test all available devices
     static bool primaryHasMic() {
         auto& policyConfig = getCachedPolicyConfig();
-        if (policyConfig.getStatus() != OK || policyConfig.getPrimaryModule() == nullptr) {
+        if (policyConfig.getStatus() != android::OK || policyConfig.getPrimaryModule() == nullptr) {
             return true;  // Could not get the information, run all tests
         }
         auto getMic = [](auto& devs) {
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
index 6efed79..6db78a7 100644
--- a/audio/core/all-versions/vts/functional/DeviceManager.h
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -16,9 +16,27 @@
 
 #pragma once
 
-// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
-// and thus it doesn't have all '#include' and 'using' directives required
-// for a standalone compilation.
+#include <unistd.h>
+
+#include <map>
+
+#include <android-base/logging.h>
+#include <hwbinder/IPCThreadState.h>
+
+// clang-format off
+#include PATH(android/hardware/audio/FILE_VERSION/IDevice.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IDevicesFactory.h)
+#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
+#include PATH(android/hardware/audio/FILE_VERSION/types.h)
+#include PATH(android/hardware/audio/common/FILE_VERSION/types.h)
+// clang-format on
+
+#include "utility/ReturnIn.h"
+
+using ::android::sp;
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::common::test::utility;
+using namespace ::android::hardware::audio::CPP_VERSION;
 
 template <class Derived, class Key, class Interface>
 class InterfaceManager {
@@ -56,7 +74,7 @@
         //        the remote device has the time to be destroyed.
         //        flushCommand makes sure all local command are sent, thus should reduce
         //        the latency between local and remote destruction.
-        IPCThreadState::self()->flushCommands();
+        ::android::hardware::IPCThreadState::self()->flushCommands();
         usleep(100 * 1000);
     }
 
diff --git a/audio/core/all-versions/vts/functional/PolicyConfig.h b/audio/core/all-versions/vts/functional/PolicyConfig.h
index c9e0c0d..a94041c 100644
--- a/audio/core/all-versions/vts/functional/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/PolicyConfig.h
@@ -16,11 +16,19 @@
 
 #pragma once
 
-// Note: it is assumed that this file is included from AudioPrimaryHidlTest.h
-// and thus it doesn't have all '#include' and 'using' directives required
-// for a standalone compilation.
+#include <set>
+#include <string>
 
+#include <DeviceDescriptor.h>
+#include <HwModule.h>
 #include <Serializer.h>
+#include <gtest/gtest.h>
+#include <system/audio_config.h>
+
+#include "DeviceManager.h"
+
+using ::android::sp;
+using ::android::status_t;
 
 struct PolicyConfigData {
     android::HwModuleCollection hwModules;
@@ -42,28 +50,14 @@
                 break;
             }
         }
-        mStatus = android::deserializeAudioPolicyFile(mFilePath.c_str(), this);
-        if (mStatus == OK) {
-            mPrimaryModule = 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;
-                    }
-                }
-            }
-        }
+        init();
+    }
+    PolicyConfig(const std::string& configPath, const std::string& configFileName)
+        : android::AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
+                                     defaultOutputDevice),
+          mConfigFileName{configFileName},
+          mFilePath{configPath + "/" + mConfigFileName} {
+        init();
     }
     status_t getStatus() const { return mStatus; }
     std::string getError() const {
@@ -88,8 +82,33 @@
     }
 
   private:
+    void init() {
+        mStatus = android::deserializeAudioPolicyFileForVts(mFilePath.c_str(), this);
+        if (mStatus == android::OK) {
+            mPrimaryModule = 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;
+                    }
+                }
+            }
+        }
+    }
+
     const std::string mConfigFileName;
-    status_t mStatus = NO_INIT;
+    status_t mStatus = android::NO_INIT;
     std::string mFilePath;
     sp<const android::HwModule> mPrimaryModule = nullptr;
     std::set<std::string> mModulesWithDevicesNames;
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
new file mode 100644
index 0000000..0c85a05
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV6_0GeneratorTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs HalAudioV6_0GeneratorTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="apm_config_no_vx.xml->/data/local/tmp/apm_config_no_vx.xml" />
+        <option name="push" value="apm_config_with_vx.xml->/data/local/tmp/apm_config_with_vx.xml" />
+        <option name="push" value="HalAudioV6_0GeneratorTest->/data/local/tmp/HalAudioV6_0GeneratorTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="HalAudioV6_0GeneratorTest" />
+    </test>
+</configuration>
diff --git a/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
new file mode 100644
index 0000000..2e79455
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/HalAudioV7_0GeneratorTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs HalAudioV7_0GeneratorTest.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="apm_config_no_vx_7_0.xml->/data/local/tmp/apm_config_no_vx.xml" />
+        <option name="push" value="apm_config_with_vx_7_0.xml->/data/local/tmp/apm_config_with_vx.xml" />
+        <option name="push" value="HalAudioV7_0GeneratorTest->/data/local/tmp/HalAudioV7_0GeneratorTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="HalAudioV7_0GeneratorTest" />
+    </test>
+</configuration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_no_vx.xml b/audio/core/all-versions/vts/functional/tests/apm_config_no_vx.xml
new file mode 100644
index 0000000..61972b2
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_no_vx.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <globalConfiguration speaker_drc_enabled="true"/>
+    <modules>
+        <module name="primary" halVersion="3.0">
+            <attachedDevices>
+                <item>Speaker</item>
+                <item>Built-In Mic</item>
+            </attachedDevices>
+            <defaultOutputDevice>Speaker</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="primary input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                    <gains>
+                        <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+                              minValueMB="-8400"
+                              maxValueMB="4000"
+                              defaultValueMB="0"
+                              stepValueMB="100"/>
+                    </gains>
+                </devicePort>
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="Speaker" sources="primary output"/>
+                <route type="mix" sink="primary input" sources="Built-In Mic"/>
+            </routes>
+        </module>
+    </modules>
+    <volumes/>
+    <surroundSound>
+      <formats>
+        <format name="AUDIO_FORMAT_AC3" />
+        <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+      </formats>
+    </surroundSound>
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_no_vx_7_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_no_vx_7_0.xml
new file mode 100644
index 0000000..abcdb12
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_no_vx_7_0.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <globalConfiguration speaker_drc_enabled="true"/>
+    <modules>
+        <module name="primary" halVersion="3.0">
+            <attachedDevices>
+                <item>Speaker</item>
+                <item>Built-In Mic</item>
+            </attachedDevices>
+            <defaultOutputDevice>Speaker</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="primary input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                    <gains>
+                        <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+                              minValueMB="-8400"
+                              maxValueMB="4000"
+                              defaultValueMB="0"
+                              stepValueMB="100"/>
+                    </gains>
+                </devicePort>
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="Speaker" sources="primary output"/>
+                <route type="mix" sink="primary input" sources="Built-In Mic"/>
+            </routes>
+        </module>
+    </modules>
+    <volumes/>
+    <surroundSound>
+      <formats>
+        <format name="AUDIO_FORMAT_AC3" />
+        <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+      </formats>
+    </surroundSound>
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_with_vx.xml b/audio/core/all-versions/vts/functional/tests/apm_config_with_vx.xml
new file mode 100644
index 0000000..aabb52e
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_with_vx.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <globalConfiguration speaker_drc_enabled="true"/>
+    <modules>
+        <module name="primary" halVersion="3.0">
+            <attachedDevices>
+                <item>Speaker</item>
+                <item>Built-In Mic</item>
+            </attachedDevices>
+            <defaultOutputDevice>Speaker</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="primary input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                    <profile name="" format="VX_GOOGLE_B_FORMAT"
+                             samplingRates="192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                    <gains>
+                        <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+                              minValueMB="-8400"
+                              maxValueMB="4000"
+                              defaultValueMB="0"
+                              stepValueMB="100"/>
+                    </gains>
+                </devicePort>
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                    <profile name="" format="VX_GOOGLE_B_FORMAT"
+                             samplingRates="192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="Ambient Mic" type="VX_GOOGLE_AUDIO_DEVICE_AMBIENT_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="Speaker" sources="primary output"/>
+                <route type="mix" sink="primary input" sources="Built-In Mic,Ambient Mic"/>
+            </routes>
+        </module>
+    </modules>
+    <volumes/>
+    <surroundSound>
+      <formats>
+        <format name="AUDIO_FORMAT_AC3" />
+        <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+        <format name="VX_GOOGLE_B_FORMAT" />
+        <format name="AUDIO_FORMAT_AC4" subformats="VX_GOOGLE_B_FORMAT" />
+      </formats>
+    </surroundSound>
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/apm_config_with_vx_7_0.xml b/audio/core/all-versions/vts/functional/tests/apm_config_with_vx_7_0.xml
new file mode 100644
index 0000000..8dd5f45
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/apm_config_with_vx_7_0.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
+    <globalConfiguration speaker_drc_enabled="true"/>
+    <modules>
+        <module name="primary" halVersion="3.0">
+            <attachedDevices>
+                <item>Speaker</item>
+                <item>Built-In Mic</item>
+            </attachedDevices>
+            <defaultOutputDevice>Speaker</defaultOutputDevice>
+            <mixPorts>
+                <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                </mixPort>
+                <mixPort name="primary input" role="sink">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                    <profile name="" format="VX_GOOGLE_B_FORMAT"
+                             samplingRates="192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </mixPort>
+            </mixPorts>
+            <devicePorts>
+                <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address="">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
+                    <gains>
+                        <gain name="gain_1" mode="AUDIO_GAIN_MODE_JOINT"
+                              minValueMB="-8400"
+                              maxValueMB="4000"
+                              defaultValueMB="0"
+                              stepValueMB="100"/>
+                    </gains>
+                </devicePort>
+                <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                    <profile name="" format="VX_GOOGLE_B_FORMAT"
+                             samplingRates="192000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+                <devicePort tagName="Ambient Mic" type="VX_GOOGLE_AUDIO_DEVICE_AMBIENT_MIC" role="source">
+                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
+                             samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
+                             channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
+                </devicePort>
+            </devicePorts>
+            <routes>
+                <route type="mix" sink="Speaker" sources="primary output"/>
+                <route type="mix" sink="primary input" sources="Built-In Mic,Ambient Mic"/>
+            </routes>
+        </module>
+    </modules>
+    <volumes/>
+    <surroundSound>
+      <formats>
+        <format name="AUDIO_FORMAT_AC3" />
+        <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
+        <format name="VX_GOOGLE_B_FORMAT" />
+        <format name="AUDIO_FORMAT_AC4" subformats="VX_GOOGLE_B_FORMAT" />
+      </formats>
+    </surroundSound>
+</audioPolicyConfiguration>
diff --git a/audio/core/all-versions/vts/functional/tests/generators_tests.cpp b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
new file mode 100644
index 0000000..583ff01
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/tests/generators_tests.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/macros.h>
+#include <gtest/gtest.h>
+#define LOG_TAG "Generators_Test"
+#include <log/log.h>
+
+#if MAJOR_VERSION == 6
+#include <system/audio.h>
+#include "6.0/Generators.h"
+#include "PolicyConfig.h"
+#elif MAJOR_VERSION == 7
+#include "7.0/Generators.h"
+#include "7.0/PolicyConfig.h"
+#endif
+
+using namespace android;
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+#if MAJOR_VERSION == 7
+namespace xsd {
+using namespace ::android::audio::policy::configuration::CPP_VERSION;
+}
+#endif
+
+// Stringify the argument.
+#define QUOTE(x) #x
+#define STRINGIFY(x) QUOTE(x)
+
+struct PolicyConfigManager {
+    static PolicyConfigManager& getInstance() {
+        static PolicyConfigManager instance;
+        return instance;
+    }
+    bool init(const std::string& filePath, const std::string& fileName) {
+        mConfig = std::make_unique<PolicyConfig>(filePath, fileName);
+        mDeviceParameters.clear();
+        if (mConfig->getStatus() == OK) {
+            const auto devices = mConfig->getModulesWithDevicesNames();
+            mDeviceParameters.reserve(devices.size());
+            for (const auto& deviceName : devices) {
+                mDeviceParameters.emplace_back(
+                        "android.hardware.audio.IDevicesFactory@" STRINGIFY(FILE_VERSION),
+                        deviceName);
+            }
+            return true;
+        } else {
+            ALOGE("%s", mConfig->getError().c_str());
+            return false;
+        }
+    }
+    const PolicyConfig& getConfig() { return *mConfig; }
+    const std::vector<DeviceParameter>& getDeviceParameters() { return mDeviceParameters; }
+
+  private:
+    std::unique_ptr<PolicyConfig> mConfig;
+    std::vector<DeviceParameter> mDeviceParameters;
+};
+
+// Test implementations
+const PolicyConfig& getCachedPolicyConfig() {
+    return PolicyConfigManager::getInstance().getConfig();
+}
+
+const std::vector<DeviceParameter>& getDeviceParameters() {
+    return PolicyConfigManager::getInstance().getDeviceParameters();
+}
+
+static const std::string kDataDir = "/data/local/tmp";
+
+class GeneratorsTest : public ::testing::TestWithParam<std::string> {
+  public:
+    static void validateConfig(const AudioConfig& config) {
+#if MAJOR_VERSION == 6
+        ASSERT_TRUE(audio_is_valid_format(static_cast<audio_format_t>(config.format)))
+                << "Audio format is invalid " << ::testing::PrintToString(config.format);
+        ASSERT_TRUE(
+                audio_channel_mask_is_valid(static_cast<audio_channel_mask_t>(config.channelMask)))
+                << "Audio channel mask is invalid " << ::testing::PrintToString(config.channelMask);
+#elif MAJOR_VERSION == 7
+        ASSERT_FALSE(xsd::isUnknownAudioFormat(config.base.format))
+                << "Audio format is invalid " << ::testing::PrintToString(config.base.format);
+        ASSERT_FALSE(xsd::isUnknownAudioChannelMask(config.base.channelMask))
+                << "Audio channel mask is invalid "
+                << ::testing::PrintToString(config.base.channelMask);
+#endif
+    }
+    static void validateDeviceConfigs(const std::vector<DeviceConfigParameter>& params) {
+        for (const auto& param : params) {
+            ASSERT_NO_FATAL_FAILURE(validateConfig(std::get<PARAM_CONFIG>(param)));
+        }
+    }
+};
+
+TEST_P(GeneratorsTest, ValidateConfigs) {
+    ASSERT_TRUE(PolicyConfigManager::getInstance().init(kDataDir, GetParam()));
+    EXPECT_NE(nullptr, getCachedPolicyConfig().getPrimaryModule());
+    EXPECT_FALSE(getCachedPolicyConfig().getModulesWithDevicesNames().empty());
+    const auto allOutConfigs = generateOutputDeviceConfigParameters(false /*oneProfilePerDevice*/);
+    EXPECT_FALSE(allOutConfigs.empty());
+    EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(allOutConfigs));
+    const auto singleOutConfig = generateOutputDeviceConfigParameters(true /*oneProfilePerDevice*/);
+    EXPECT_FALSE(singleOutConfig.empty());
+    EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(singleOutConfig));
+    const auto allInConfigs = generateInputDeviceConfigParameters(false /*oneProfilePerDevice*/);
+    EXPECT_FALSE(allInConfigs.empty());
+    EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(allInConfigs));
+    const auto singleInConfig = generateInputDeviceConfigParameters(true /*oneProfilePerDevice*/);
+    EXPECT_FALSE(singleInConfig.empty());
+    EXPECT_NO_FATAL_FAILURE(validateDeviceConfigs(singleInConfig));
+}
+
+// Target file names are the same for all versions, see 'HalAudioVx_0GeneratorTest.xml' test configs
+INSTANTIATE_TEST_SUITE_P(Generators, GeneratorsTest,
+                         ::testing::Values("apm_config_no_vx.xml", "apm_config_with_vx.xml"));
diff --git a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
index 687c70c..c09b265 100644
--- a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
+++ b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
@@ -34,11 +34,19 @@
         authsecret = IAuthSecret::getService(GetParam());
         ASSERT_NE(authsecret, nullptr);
 
+        // Notify LSS to generate PIN code '1234' and corresponding secret.
+        (void)system("cmd lock_settings set-pin 1234");
+
         // All tests must enroll the correct secret first as this cannot be changed
         // without a factory reset and the order of tests could change.
         authsecret->primaryUserCredential(CORRECT_SECRET);
     }
 
+    static void TearDownTestSuite() {
+        // clean up PIN code after testing
+        (void)system("cmd lock_settings clear --old 1234");
+    }
+
     sp<IAuthSecret> authsecret;
     hidl_vec<uint8_t> CORRECT_SECRET{61, 93, 124, 240, 5, 0, 7, 201, 9, 129, 11, 12, 0, 14, 0, 16};
     hidl_vec<uint8_t> WRONG_SECRET{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
diff --git a/automotive/audiocontrol/1.0/default/Android.bp b/automotive/audiocontrol/1.0/default/Android.bp
index 3cae4f1..7180a70 100644
--- a/automotive/audiocontrol/1.0/default/Android.bp
+++ b/automotive/audiocontrol/1.0/default/Android.bp
@@ -28,7 +28,7 @@
     relative_install_path: "hw",
     srcs: [
         "AudioControl.cpp",
-        "service.cpp"
+        "service.cpp",
     ],
     init_rc: ["android.hardware.automotive.audiocontrol@1.0-service.rc"],
 
@@ -40,3 +40,16 @@
     ],
     vintf_fragments: ["audiocontrol_manifest.xml"],
 }
+
+filegroup {
+    name: "audiocontrolV1.0_source",
+    srcs: [
+        "AudioControl.cpp",
+    ],
+}
+
+cc_library_headers {
+    name: "audiocontrolV1.0_header",
+    host_supported: true,
+    export_include_dirs: ["."],
+}
diff --git a/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
new file mode 100644
index 0000000..78f5b52
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/test/fuzzer/Android.bp
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_fuzz {
+    name: "audiocontrolV1.0_fuzzer",
+    host_supported: true,
+    srcs: [
+        "audiocontrolV1.0_fuzzer.cpp",
+        ":audiocontrolV1.0_source",
+    ],
+    header_libs: [
+        "audiocontrolV1.0_header",
+    ],
+    shared_libs: [
+        "android.hardware.automotive.audiocontrol@1.0",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 533764,
+    },
+}
diff --git a/automotive/audiocontrol/1.0/default/test/fuzzer/audiocontrolV1.0_fuzzer.cpp b/automotive/audiocontrol/1.0/default/test/fuzzer/audiocontrolV1.0_fuzzer.cpp
new file mode 100644
index 0000000..268df08
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/test/fuzzer/audiocontrolV1.0_fuzzer.cpp
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <AudioControl.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+using ::android::sp;
+using ::android::hardware::automotive::audiocontrol::V1_0::ContextNumber;
+using ::android::hardware::automotive::audiocontrol::V1_0::implementation::AudioControl;
+
+namespace android::hardware::automotive::audiocontrol::V1_0::implementation::fuzzer {
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    if (size < 1) {
+        return 0;
+    }
+    if (sp<AudioControl> audioControl = new AudioControl(); audioControl != nullptr) {
+        FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
+        ContextNumber contextNumber = static_cast<ContextNumber>(fdp.ConsumeIntegral<uint32_t>());
+        audioControl->getBusForContext(contextNumber);
+        audioControl->setBalanceTowardRight(fdp.ConsumeFloatingPoint<float>());
+        audioControl->setFadeTowardFront(fdp.ConsumeFloatingPoint<float>());
+    }
+    return 0;
+}
+}  // namespace android::hardware::automotive::audiocontrol::V1_0::implementation::fuzzer
diff --git a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
index 8b68fd6..f1c8f9f 100644
--- a/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
+++ b/automotive/evs/1.1/vts/functional/VtsHalEvsV1_1TargetTest.cpp
@@ -72,6 +72,8 @@
 using ::android::hardware::automotive::evs::V1_0::DisplayDesc;
 using ::android::hardware::automotive::evs::V1_0::DisplayState;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::frameworks::automotive::display::V1_0::HwDisplayConfig;
+using ::android::frameworks::automotive::display::V1_0::HwDisplayState;
 using IEvsCamera_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsCamera;
 using IEvsCamera_1_1 = ::android::hardware::automotive::evs::V1_1::IEvsCamera;
 using IEvsDisplay_1_0 = ::android::hardware::automotive::evs::V1_0::IEvsDisplay;
@@ -303,11 +305,22 @@
             const auto id = 0xFFFFFFFF; // meaningless id
             hidl_vec<uint8_t> values;
             auto err = pCam->setExtendedInfo_1_1(id, values);
-            ASSERT_NE(EvsResult::INVALID_ARG, err);
+            if (isLogicalCam) {
+                // Logical camera device does not support setExtendedInfo
+                // method.
+                ASSERT_EQ(EvsResult::INVALID_ARG, err);
+            } else {
+                ASSERT_NE(EvsResult::INVALID_ARG, err);
+            }
 
-            pCam->getExtendedInfo_1_1(id, [](const auto& result, const auto& data) {
-                ASSERT_NE(EvsResult::INVALID_ARG, result);
-                ASSERT_EQ(0, data.size());
+
+            pCam->getExtendedInfo_1_1(id, [&isLogicalCam](const auto& result, const auto& data) {
+                if (isLogicalCam) {
+                    ASSERT_EQ(EvsResult::INVALID_ARG, result);
+                } else {
+                    ASSERT_NE(EvsResult::INVALID_ARG, result);
+                    ASSERT_EQ(0, data.size());
+                }
             });
 
             // Explicitly close the camera so resources are released right away
@@ -605,7 +618,10 @@
     LOG(INFO) << "Display " << targetDisplayId << " is alreay in use.";
 
     // Get the display descriptor
-    pDisplay->getDisplayInfo_1_1([](const auto& config, const auto& state) {
+    pDisplay->getDisplayInfo_1_1([](const HwDisplayConfig& config, const HwDisplayState& state) {
+        ASSERT_GT(config.size(), 0);
+        ASSERT_GT(state.size(), 0);
+
         android::DisplayConfig* pConfig = (android::DisplayConfig*)config.data();
         const auto width = pConfig->resolution.getWidth();
         const auto height = pConfig->resolution.getHeight();
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index d092f7a..f24b1f5 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -146,7 +146,6 @@
     local_include_dirs: ["common/include/vhal_v2_0"],
     export_include_dirs: ["impl"],
     srcs: [
-        "impl/vhal_v2_0/EmulatedUserHal.cpp",
         "impl/vhal_v2_0/GeneratorHub.cpp",
         "impl/vhal_v2_0/JsonFakeValueGenerator.cpp",
         "impl/vhal_v2_0/LinearFakeValueGenerator.cpp",
@@ -222,3 +221,29 @@
         "android.hardware.automotive.vehicle@2.0-libproto-native",
     ],
 }
+
+cc_fuzz {
+    name: "vehicleManager_fuzzer",
+    vendor: true,
+    defaults: ["vhal_v2_0_target_defaults"],
+    whole_static_libs: ["android.hardware.automotive.vehicle@2.0-manager-lib"],
+    srcs: [
+        "tests/fuzzer/VehicleManager_fuzzer.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libbinder_ndk",
+    ],
+    header_libs: ["libbase_headers"],
+    local_include_dirs: [
+        "common/include",
+        "tests",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 533764,
+    },
+}
diff --git a/automotive/vehicle/2.0/default/VehicleService.cpp b/automotive/vehicle/2.0/default/VehicleService.cpp
index 47133fd..ef29560 100644
--- a/automotive/vehicle/2.0/default/VehicleService.cpp
+++ b/automotive/vehicle/2.0/default/VehicleService.cpp
@@ -34,7 +34,7 @@
 
 int main(int /* argc */, char* /* argv */ []) {
     auto store = std::make_unique<VehiclePropertyStore>();
-    auto connector = impl::makeEmulatedPassthroughConnector();
+    auto connector = std::make_unique<impl::EmulatedVehicleConnector>();
     auto userHal = connector->getEmulatedUserHal();
     auto hal = std::make_unique<impl::EmulatedVehicleHal>(store.get(), connector.get(), userHal);
     auto emulator = std::make_unique<impl::VehicleEmulator>(hal.get());
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index cf18404..dec2d8c 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -417,7 +417,7 @@
                          .minSampleRate = 1.0f,
                          .maxSampleRate = 2.0f,
                  },
-         .initialValue = {.floatValues = {100.0f}}},  // units in meters
+         .initialValue = {.floatValues = {50000.0f}}},  // units in meters
 
         {.config =
                  {
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
index 7f9362f..ed3f4a2 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.cpp
@@ -35,13 +35,33 @@
 
 namespace impl {
 
-class EmulatedPassthroughConnector : public PassthroughConnector {
-  public:
-    bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
-};
+EmulatedUserHal* EmulatedVehicleConnector::getEmulatedUserHal() {
+    return &mEmulatedUserHal;
+}
 
-bool EmulatedPassthroughConnector::onDump(const hidl_handle& handle,
-                                          const hidl_vec<hidl_string>& options) {
+StatusCode EmulatedVehicleConnector::onSetProperty(const VehiclePropValue& value,
+                                                   bool updateStatus) {
+    if (mEmulatedUserHal.isSupported(value.prop)) {
+        LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal";
+
+        const auto& ret = mEmulatedUserHal.onSetProperty(value);
+        if (!ret.ok()) {
+            LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message();
+            return StatusCode(ret.error().code());
+        }
+        auto updatedValue = ret.value().get();
+        if (updatedValue != nullptr) {
+            LOG(INFO) << "onSetProperty(): updating property returned by HAL: "
+                      << toString(*updatedValue);
+            onPropertyValueFromCar(*updatedValue, updateStatus);
+        }
+        return StatusCode::OK;
+    }
+    return this->VehicleHalServer::onSetProperty(value, updateStatus);
+}
+
+bool EmulatedVehicleConnector::onDump(const hidl_handle& handle,
+                                      const hidl_vec<hidl_string>& options) {
     int fd = handle->data[0];
 
     if (options.size() > 0) {
@@ -68,10 +88,6 @@
     return true;
 }
 
-PassthroughConnectorPtr makeEmulatedPassthroughConnector() {
-    return std::make_unique<EmulatedPassthroughConnector>();
-}
-
 }  // namespace impl
 
 }  // namespace V2_0
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
index 57cbb8b..4c6c661 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/EmulatedVehicleConnector.h
@@ -19,6 +19,7 @@
 
 #include <vhal_v2_0/VehicleConnector.h>
 
+#include "EmulatedUserHal.h"
 #include "VehicleHalClient.h"
 #include "VehicleHalServer.h"
 
@@ -30,10 +31,20 @@
 
 namespace impl {
 
-using PassthroughConnector = IPassThroughConnector<VehicleHalClient, VehicleHalServer>;
-using PassthroughConnectorPtr = std::unique_ptr<PassthroughConnector>;
+class EmulatedVehicleConnector : public IPassThroughConnector<VehicleHalClient, VehicleHalServer> {
+  public:
+    EmulatedVehicleConnector() {}
 
-PassthroughConnectorPtr makeEmulatedPassthroughConnector();
+    EmulatedUserHal* getEmulatedUserHal();
+
+    // Methods from VehicleHalServer
+    StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;
+
+    bool onDump(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
+
+  private:
+    EmulatedUserHal mEmulatedUserHal;
+};
 
 }  // namespace impl
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
index 890eb33..b62918f 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/JsonFakeValueGenerator.cpp
@@ -96,11 +96,12 @@
 std::vector<VehiclePropValue> JsonFakeValueGenerator::parseFakeValueJson(std::istream& is) {
     std::vector<VehiclePropValue> fakeVhalEvents;
 
-    Json::Reader reader;
+    Json::CharReaderBuilder builder;
     Json::Value rawEvents;
-    if (!reader.parse(is, rawEvents)) {
+    std::string errorMessage;
+    if (!Json::parseFromStream(builder, is, &rawEvents, &errorMessage)) {
         ALOGE("%s: Failed to parse fake data JSON file. Error: %s", __func__,
-              reader.getFormattedErrorMessages().c_str());
+              errorMessage.c_str());
         return fakeVhalEvents;
     }
 
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
index 36f2534..0ee1835 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.cpp
@@ -41,10 +41,6 @@
     return mValuePool;
 }
 
-EmulatedUserHal* VehicleHalServer::getEmulatedUserHal() {
-    return &mEmulatedUserHal;
-}
-
 void VehicleHalServer::setValuePool(VehiclePropValuePool* valuePool) {
     if (!valuePool) {
         LOG(WARNING) << __func__ << ": Setting value pool to nullptr!";
@@ -185,22 +181,6 @@
 }
 
 StatusCode VehicleHalServer::onSetProperty(const VehiclePropValue& value, bool updateStatus) {
-    if (mEmulatedUserHal.isSupported(value.prop)) {
-        LOG(INFO) << "onSetProperty(): property " << value.prop << " will be handled by UserHal";
-
-        const auto& ret = mEmulatedUserHal.onSetProperty(value);
-        if (!ret.ok()) {
-            LOG(ERROR) << "onSetProperty(): HAL returned error: " << ret.error().message();
-            return StatusCode(ret.error().code());
-        }
-        auto updatedValue = ret.value().get();
-        if (updatedValue != nullptr) {
-            LOG(INFO) << "onSetProperty(): updating property returned by HAL: "
-                      << toString(*updatedValue);
-            onPropertyValueFromCar(*updatedValue, updateStatus);
-        }
-        return StatusCode::OK;
-    }
     LOG(DEBUG) << "onSetProperty(" << value.prop << ")";
 
     // Some properties need to be treated non-trivially
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
index fca78bc..117eadb 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/VehicleHalServer.h
@@ -19,7 +19,6 @@
 #include <vhal_v2_0/VehicleObjectPool.h>
 #include <vhal_v2_0/VehicleServer.h>
 
-#include "EmulatedUserHal.h"
 #include "GeneratorHub.h"
 
 namespace android::hardware::automotive::vehicle::V2_0::impl {
@@ -38,8 +37,6 @@
     // Set the Property Value Pool used in this server
     void setValuePool(VehiclePropValuePool* valuePool);
 
-    EmulatedUserHal* getEmulatedUserHal();
-
   private:
     using VehiclePropValuePtr = recyclable_ptr<VehiclePropValue>;
 
@@ -56,11 +53,6 @@
     VehiclePropValuePtr createHwInputKeyProp(VehicleHwKeyInputAction action, int32_t keyCode,
                                              int32_t targetDisplay);
 
-    // data members
-
-  protected:
-    EmulatedUserHal mEmulatedUserHal;
-
   private:
     GeneratorHub mGeneratorHub{
             std::bind(&VehicleHalServer::onFakeValueGenerated, this, std::placeholders::_1)};
diff --git a/automotive/vehicle/2.0/default/tests/fuzzer/README.md b/automotive/vehicle/2.0/default/tests/fuzzer/README.md
new file mode 100644
index 0000000..3fa0d3f
--- /dev/null
+++ b/automotive/vehicle/2.0/default/tests/fuzzer/README.md
@@ -0,0 +1,66 @@
+# Fuzzer for android.hardware.automotive.vehicle@2.0-manager-lib
+
+## Plugin Design Considerations
+The fuzzer plugin for android.hardware.automotive.vehicle@2.0-manager-lib is
+designed based on the understanding of the library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+Vehicle Manager supports the following parameters:
+1. Vehicle Property (parameter name: `vehicleProp`)
+2. Diagnostic Integer Sensor Index (parameter name: `diagnosticIntIndex`)
+3. Diagnostic Float Sensor Index (parameter name: `diagnosticFloatIndex`)
+4. Availability Message Type (parameter name: `availabilityMsgType`)
+5. Subscription Message Type (parameter name: `subscriptionMsgType`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `vehicleProp` | 0.`VehicleProperty::INVALID` 1.`VehicleProperty::HVAC_FAN_SPEED` 2.`VehicleProperty::INFO_MAKE` 3.`VehicleProperty::DISPLAY_BRIGHTNESS`  4.`VehicleProperty::INFO_FUEL_CAPACITY` 5.`VehicleProperty::HVAC_SEAT_TEMPERATURE`| Value obtained from FuzzedDataProvider |
+| `diagnosticIntIndex`   | 0.`DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS` 1.`DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON` 2.`DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT` 3.`DiagnosticIntegerSensorIndex::FUEL_TYPE`  | Value obtained from FuzzedDataProvider |
+| `diagnosticFloatIndex`   | 0.`DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD` 1.`DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1` 2.`DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1` 3.`DiagnosticFloatSensorIndex::THROTTLE_POSITION`  | Value obtained from FuzzedDataProvider |
+| `availabilityMsgType`   | 0.`VmsMessageType::AVAILABILITY_CHANGE` 1.`VmsMessageType::AVAILABILITY_RESPONSE` | Value obtained from FuzzedDataProvider |
+| `subscriptionMsgType`   | 0.`VmsMessageType::SUBSCRIPTIONS_CHANGE` 1.`VmsMessageType::SUBSCRIPTIONS_RESPONSE` | Value obtained from FuzzedDataProvider |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+## Build
+
+This describes steps to build vehicleManager_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) vehicleManager_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR
+```
+  $ adb shell mkdir /data/local/tmp/CORPUS_DIR
+```
+
+##### Some Additional steps needed to run the vehicleManager_fuzzer successfully on device
+
+1. Push the following libraries from /vendor/lib/ and /vendor/lib64/ folders of your workspace to the device's /vendor/lib/ and /vendor/lib64/ :
+```
+1.1  android.hardware.automotive.vehicle@2.0.so
+1.2  carwatchdog_aidl_interface-V2-ndk_platform.so
+```
+2. Now, reboot the device using command
+```
+  $ adb reboot
+```
+
+##### To run the fuzzer on device
+```
+  $ adb sync data
+  $ adb shell LD_LIBRARY_PATH=/vendor/lib64 /data/fuzz/${TARGET_ARCH}/vehicleManager_fuzzer/vendor/vehicleManager_fuzzer /data/local/tmp/CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp
new file mode 100644
index 0000000..796c08f
--- /dev/null
+++ b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.cpp
@@ -0,0 +1,433 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "VehicleManager_fuzzer.h"
+#include <utils/SystemClock.h>
+#include <vhal_v2_0/Obd2SensorStore.h>
+#include <vhal_v2_0/WatchdogClient.h>
+
+namespace android::hardware::automotive::vehicle::V2_0::fuzzer {
+
+using ::aidl::android::automotive::watchdog::TimeoutLength;
+using ::android::elapsedRealtimeNano;
+using ::android::Looper;
+using ::android::sp;
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::automotive::vehicle::V2_0::DiagnosticFloatSensorIndex;
+using ::android::hardware::automotive::vehicle::V2_0::DiagnosticIntegerSensorIndex;
+using ::android::hardware::automotive::vehicle::V2_0::kCustomComplexProperty;
+using ::android::hardware::automotive::vehicle::V2_0::kVehicleProperties;
+using ::android::hardware::automotive::vehicle::V2_0::MockedVehicleCallback;
+using ::android::hardware::automotive::vehicle::V2_0::Obd2SensorStore;
+using ::android::hardware::automotive::vehicle::V2_0::recyclable_ptr;
+using ::android::hardware::automotive::vehicle::V2_0::StatusCode;
+using ::android::hardware::automotive::vehicle::V2_0::SubscribeFlags;
+using ::android::hardware::automotive::vehicle::V2_0::SubscribeOptions;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleAreaConfig;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleHal;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleHalManager;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropConfig;
+using ::android::hardware::automotive::vehicle::V2_0::VehicleProperty;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyAccess;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyChangeMode;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyStore;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropertyType;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValue;
+using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValuePool;
+using ::android::hardware::automotive::vehicle::V2_0::VmsMessageType;
+using ::android::hardware::automotive::vehicle::V2_0::WatchdogClient;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createAvailabilityRequest;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createBaseVmsMessage;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createPublisherIdRequest;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createStartSessionMessage;
+using ::android::hardware::automotive::vehicle::V2_0::vms::createSubscriptionsRequest;
+using ::android::hardware::automotive::vehicle::V2_0::vms::getAvailableLayers;
+using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForAvailabilityState;
+using ::android::hardware::automotive::vehicle::V2_0::vms::getSequenceNumberForSubscriptionsState;
+using ::android::hardware::automotive::vehicle::V2_0::vms::hasServiceNewlyStarted;
+using ::android::hardware::automotive::vehicle::V2_0::vms::isAvailabilitySequenceNumberNewer;
+using ::android::hardware::automotive::vehicle::V2_0::vms::isSequenceNumberNewer;
+using ::android::hardware::automotive::vehicle::V2_0::vms::isValidVmsMessage;
+using ::android::hardware::automotive::vehicle::V2_0::vms::parseData;
+using ::android::hardware::automotive::vehicle::V2_0::vms::parseMessageType;
+using ::android::hardware::automotive::vehicle::V2_0::vms::parsePublisherIdResponse;
+using ::android::hardware::automotive::vehicle::V2_0::vms::parseStartSessionMessage;
+using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayer;
+using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerAndPublisher;
+using ::android::hardware::automotive::vehicle::V2_0::vms::VmsLayerOffering;
+using ::android::hardware::automotive::vehicle::V2_0::vms::VmsOffers;
+
+constexpr const char kCarMake[] = "Default Car";
+constexpr VehicleProperty kVehicleProp[] = {VehicleProperty::INVALID,
+                                            VehicleProperty::HVAC_FAN_SPEED,
+                                            VehicleProperty::INFO_MAKE,
+                                            VehicleProperty::DISPLAY_BRIGHTNESS,
+                                            VehicleProperty::INFO_FUEL_CAPACITY,
+                                            VehicleProperty::HVAC_SEAT_TEMPERATURE};
+constexpr DiagnosticIntegerSensorIndex kDiagnosticIntIndex[] = {
+        DiagnosticIntegerSensorIndex::FUEL_SYSTEM_STATUS,
+        DiagnosticIntegerSensorIndex::MALFUNCTION_INDICATOR_LIGHT_ON,
+        DiagnosticIntegerSensorIndex::NUM_OXYGEN_SENSORS_PRESENT,
+        DiagnosticIntegerSensorIndex::FUEL_TYPE};
+constexpr DiagnosticFloatSensorIndex kDiagnosticFloatIndex[] = {
+        DiagnosticFloatSensorIndex::CALCULATED_ENGINE_LOAD,
+        DiagnosticFloatSensorIndex::SHORT_TERM_FUEL_TRIM_BANK1,
+        DiagnosticFloatSensorIndex::LONG_TERM_FUEL_TRIM_BANK1,
+        DiagnosticFloatSensorIndex::THROTTLE_POSITION};
+constexpr size_t kVehiclePropArrayLength = std::size(kVehicleProp);
+constexpr size_t kIntSensorArrayLength = std::size(kDiagnosticIntIndex);
+constexpr size_t kFloatSensorArrayLength = std::size(kDiagnosticFloatIndex);
+constexpr VmsMessageType kAvailabilityMessageType[] = {VmsMessageType::AVAILABILITY_CHANGE,
+                                                       VmsMessageType::AVAILABILITY_RESPONSE};
+constexpr VmsMessageType kSubscriptionMessageType[] = {VmsMessageType::SUBSCRIPTIONS_CHANGE,
+                                                       VmsMessageType::SUBSCRIPTIONS_RESPONSE};
+
+MockedVehicleHal::VehiclePropValuePtr MockedVehicleHal::get(
+        const VehiclePropValue& requestedPropValue, StatusCode* outStatus) {
+    VehiclePropValuePtr pValue = nullptr;
+    if (outStatus == nullptr) {
+        return pValue;
+    }
+    auto property = static_cast<VehicleProperty>(requestedPropValue.prop);
+    int32_t areaId = requestedPropValue.areaId;
+    *outStatus = StatusCode::OK;
+
+    switch (property) {
+        case VehicleProperty::INFO_MAKE:
+            pValue = getValuePool()->obtainString(kCarMake);
+            break;
+        case VehicleProperty::INFO_FUEL_CAPACITY:
+            if (mFuelCapacityAttemptsLeft-- > 0) {
+                *outStatus = StatusCode::TRY_AGAIN;
+            } else {
+                pValue = getValuePool()->obtainFloat(42.42);
+            }
+            break;
+        default:
+            if (requestedPropValue.prop == kCustomComplexProperty) {
+                pValue = getValuePool()->obtainComplex();
+                pValue->value.int32Values = hidl_vec<int32_t>{10, 20};
+                pValue->value.int64Values = hidl_vec<int64_t>{30, 40};
+                pValue->value.floatValues = hidl_vec<float_t>{1.1, 2.2};
+                pValue->value.bytes = hidl_vec<uint8_t>{1, 2, 3};
+                pValue->value.stringValue = kCarMake;
+                break;
+            }
+            auto key = makeKey(toInt(property), areaId);
+            pValue = getValuePool()->obtain(mValues[key]);
+    }
+
+    if (*outStatus == StatusCode::OK && pValue.get() != nullptr) {
+        pValue->prop = toInt(property);
+        pValue->areaId = areaId;
+        pValue->timestamp = elapsedRealtimeNano();
+    }
+
+    return pValue;
+}
+
+void VehicleHalManagerFuzzer::process(const uint8_t* data, size_t size) {
+    mFuzzedDataProvider = new FuzzedDataProvider(data, size);
+    invokeDebug();
+    invokePropConfigs();
+    invokeSubscribe();
+    invokeSetAndGetValues();
+    invokeObd2SensorStore();
+    invokeVmsUtils();
+    invokeVehiclePropStore();
+    invokeWatchDogClient();
+}
+
+void VehicleHalManagerFuzzer::invokeDebug() {
+    hidl_string debugOption = mFuzzedDataProvider->PickValueInArray(
+            {"--help", "--list", "--get", "--set", "", "invalid"});
+    hidl_handle fd = {};
+    fd.setTo(native_handle_create(/*numFds=*/1, /*numInts=*/0), /*shouldOwn=*/true);
+
+    mManager->debug(fd, {});
+    mManager->debug(fd, {debugOption});
+}
+
+void VehicleHalManagerFuzzer::invokePropConfigs() {
+    int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+    int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+
+    hidl_vec<int32_t> properties = {vehicleProp1, vehicleProp2};
+
+    mManager->getPropConfigs(properties,
+                             []([[maybe_unused]] StatusCode status,
+                                [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
+
+    mManager->getPropConfigs({toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength])},
+                             []([[maybe_unused]] StatusCode status,
+                                [[maybe_unused]] const hidl_vec<VehiclePropConfig>& c) {});
+
+    mManager->getAllPropConfigs(
+            []([[maybe_unused]] const hidl_vec<VehiclePropConfig>& propConfigs) {});
+}
+
+void VehicleHalManagerFuzzer::invokeSubscribe() {
+    int32_t vehicleProp1 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+    int32_t vehicleProp2 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+    int32_t vehicleProp3 = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+
+    const auto prop1 = toInt(kVehicleProp[abs(vehicleProp1) % kVehiclePropArrayLength]);
+    sp<MockedVehicleCallback> cb = new MockedVehicleCallback();
+
+    hidl_vec<SubscribeOptions> options = {
+            SubscribeOptions{.propId = prop1, .flags = SubscribeFlags::EVENTS_FROM_CAR}};
+
+    mManager->subscribe(cb, options);
+
+    auto unsubscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
+    unsubscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
+
+    mHal->sendPropEvent(std::move(unsubscribedValue));
+    cb->getReceivedEvents();
+    cb->waitForExpectedEvents(0);
+
+    auto subscribedValue = mObjectPool->obtain(VehiclePropertyType::INT32);
+    subscribedValue->prop = toInt(kVehicleProp[abs(vehicleProp2) % kVehiclePropArrayLength]);
+    subscribedValue->value.int32Values[0] = INT32_MAX;
+
+    cb->reset();
+    VehiclePropValue actualValue(*subscribedValue.get());
+    mHal->sendPropEvent(std::move(subscribedValue));
+    cb->waitForExpectedEvents(1);
+    mManager->unsubscribe(cb, prop1);
+
+    sp<MockedVehicleCallback> cb2 = new MockedVehicleCallback();
+
+    hidl_vec<SubscribeOptions> options2 = {
+            SubscribeOptions{
+                    .propId = toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
+                    .flags = SubscribeFlags::EVENTS_FROM_CAR},
+    };
+
+    mManager->subscribe(cb2, options2);
+
+    mHal->sendHalError(StatusCode::TRY_AGAIN,
+                       toInt(kVehicleProp[abs(vehicleProp3) % kVehiclePropArrayLength]),
+                       /*areaId=*/0);
+}
+
+void VehicleHalManagerFuzzer::invokeSetAndGetValues() {
+    uint32_t vehicleProp1 =
+            mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
+    uint32_t vehicleProp2 =
+            mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
+    uint32_t vehicleProp3 =
+            mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kVehiclePropArrayLength - 1);
+
+    invokeGet(kCustomComplexProperty, 0);
+    invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
+    invokeGet(toInt(kVehicleProp[vehicleProp1]), 0);
+
+    auto expectedValue = mObjectPool->obtainInt32(mFuzzedDataProvider->ConsumeIntegral<int32_t>());
+    mObjectPool->obtainInt64(mFuzzedDataProvider->ConsumeIntegral<int64_t>());
+    mObjectPool->obtainFloat(mFuzzedDataProvider->ConsumeFloatingPoint<float>());
+    mObjectPool->obtainBoolean(mFuzzedDataProvider->ConsumeBool());
+    expectedValue->prop = toInt(kVehicleProp[vehicleProp2]);
+    expectedValue->areaId = 0;
+
+    mManager->set(*expectedValue.get());
+    invokeGet(toInt(kVehicleProp[vehicleProp2]), 0);
+    expectedValue->prop = toInt(kVehicleProp[vehicleProp3]);
+    mManager->set(*expectedValue.get());
+    expectedValue->prop = toInt(VehicleProperty::INVALID);
+    mManager->set(*expectedValue.get());
+}
+
+void VehicleHalManagerFuzzer::invokeObd2SensorStore() {
+    uint32_t diagnosticIntIndex =
+            mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kIntSensorArrayLength - 1);
+    int32_t diagnosticIntValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+    uint32_t diagnosticFloatIndex =
+            mFuzzedDataProvider->ConsumeIntegralInRange<uint32_t>(0, kFloatSensorArrayLength - 1);
+    float diagnosticFloatValue = mFuzzedDataProvider->ConsumeFloatingPoint<float>();
+
+    std::unique_ptr<Obd2SensorStore> sensorStore(
+            new Obd2SensorStore(kIntSensorArrayLength, kFloatSensorArrayLength));
+    if (sensorStore) {
+        sensorStore->setIntegerSensor(kDiagnosticIntIndex[diagnosticIntIndex], diagnosticIntValue);
+        sensorStore->setFloatSensor(kDiagnosticFloatIndex[diagnosticFloatIndex],
+                                    diagnosticFloatValue);
+        sensorStore->getIntegerSensors();
+        sensorStore->getFloatSensors();
+        sensorStore->getSensorsBitmask();
+        static std::vector<std::string> sampleDtcs = {"P0070",
+                                                      "P0102"
+                                                      "P0123"};
+        for (auto&& dtc : sampleDtcs) {
+            auto freezeFrame = createVehiclePropValue(VehiclePropertyType::MIXED, 0);
+            sensorStore->fillPropValue(dtc, freezeFrame.get());
+            freezeFrame->prop = static_cast<int>(VehicleProperty::OBD2_FREEZE_FRAME);
+        }
+    }
+}
+
+void VehicleHalManagerFuzzer::invokeVmsUtils() {
+    bool availabilityMsgType = mFuzzedDataProvider->ConsumeBool();
+    bool subscriptionMsgType = mFuzzedDataProvider->ConsumeBool();
+    int32_t intValue = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+
+    VmsLayer layer(1, 0, 2);
+    auto message = createSubscribeMessage(layer);
+    isValidVmsMessage(*message);
+    message = createUnsubscribeMessage(layer);
+
+    VmsOffers offers = {intValue, {VmsLayerOffering(VmsLayer(1, 0, 2))}};
+    message = createOfferingMessage(offers);
+    std::vector<VmsLayer> dependencies = {VmsLayer(2, 0, 2), VmsLayer(3, 0, 3)};
+    std::vector<VmsLayerOffering> offering = {VmsLayerOffering(layer, dependencies)};
+    offers = {intValue, offering};
+    message = createOfferingMessage(offers);
+
+    message = createAvailabilityRequest();
+    message = createSubscriptionsRequest();
+
+    std::string bytes = "placeholder";
+    const VmsLayerAndPublisher layer_and_publisher(VmsLayer(2, 0, 1), intValue);
+    message = createDataMessageWithLayerPublisherInfo(layer_and_publisher, bytes);
+    parseData(*message);
+    createSubscribeToPublisherMessage(layer_and_publisher);
+    createUnsubscribeToPublisherMessage(layer_and_publisher);
+
+    std::string pub_bytes = "pub_id";
+    message = createPublisherIdRequest(pub_bytes);
+    message = createBaseVmsMessage(2);
+    message->value.int32Values =
+            hidl_vec<int32_t>{toInt(VmsMessageType::PUBLISHER_ID_RESPONSE), intValue};
+    parsePublisherIdResponse(*message);
+
+    message->value.int32Values =
+            hidl_vec<int32_t>{toInt(kSubscriptionMessageType[subscriptionMsgType]), intValue};
+    getSequenceNumberForSubscriptionsState(*message);
+
+    message->value.int32Values = hidl_vec<int32_t>{toInt(kSubscriptionMessageType[0]), intValue};
+    isSequenceNumberNewer(*message, intValue + 1);
+    invokeGetSubscribedLayers(kSubscriptionMessageType[subscriptionMsgType]);
+
+    message->value.int32Values =
+            hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), 0};
+    hasServiceNewlyStarted(*message);
+    message = createStartSessionMessage(intValue, intValue + 1);
+    parseMessageType(*message);
+
+    message->value.int32Values =
+            hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
+    isAvailabilitySequenceNumberNewer(*message, intValue + 1);
+
+    message->value.int32Values =
+            hidl_vec<int32_t>{toInt(kAvailabilityMessageType[availabilityMsgType]), intValue};
+    getSequenceNumberForAvailabilityState(*message);
+    message = createBaseVmsMessage(3);
+    int new_service_id;
+    message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::START_SESSION), 0, -1};
+    parseStartSessionMessage(*message, -1, 0, &new_service_id);
+}
+
+void VehicleHalManagerFuzzer::invokeGet(int32_t property, int32_t areaId) {
+    VehiclePropValue requestedValue{};
+    requestedValue.prop = property;
+    requestedValue.areaId = areaId;
+    mActualValue = VehiclePropValue{};  // reset previous values
+
+    StatusCode refStatus;
+    VehiclePropValue refValue;
+    mManager->get(requestedValue,
+                  [&refStatus, &refValue](StatusCode status, const VehiclePropValue& value) {
+                      refStatus = status;
+                      refValue = value;
+                  });
+
+    mActualValue = refValue;
+    mActualStatusCode = refStatus;
+}
+
+void VehicleHalManagerFuzzer::invokeGetSubscribedLayers(VmsMessageType type) {
+    VmsOffers offers = {123,
+                        {VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
+                         VmsLayerOffering(VmsLayer(2, 0, 1))}};
+    auto message = createBaseVmsMessage(16);
+    message->value.int32Values = hidl_vec<int32_t>{toInt(type),
+                                                   1234,  // sequence number
+                                                   2,     // number of layers
+                                                   1,     // number of associated layers
+                                                   1,     // layer 1
+                                                   0,           1,
+                                                   4,  // layer 2
+                                                   1,           1,
+                                                   2,  // associated layer
+                                                   0,           1,
+                                                   2,    // number of publisher IDs
+                                                   111,  // publisher IDs
+                                                   123};
+    isValidVmsMessage(*message);
+    getSubscribedLayers(*message, offers);
+    getAvailableLayers(*message);
+}
+
+void VehicleHalManagerFuzzer::invokeVehiclePropStore() {
+    bool shouldWriteStatus = mFuzzedDataProvider->ConsumeBool();
+    int32_t vehicleProp = mFuzzedDataProvider->ConsumeIntegral<int32_t>();
+    auto store = std::make_unique<VehiclePropertyStore>();
+    VehiclePropConfig config{
+            .prop = vehicleProp,
+            .access = VehiclePropertyAccess::READ,
+            .changeMode = VehiclePropertyChangeMode::STATIC,
+            .areaConfigs = {VehicleAreaConfig{.areaId = (0)}},
+    };
+    store->registerProperty(config);
+    VehiclePropValue propValue{};
+    propValue.prop = vehicleProp;
+    propValue.areaId = 0;
+    store->writeValue(propValue, shouldWriteStatus);
+    store->readAllValues();
+    store->getAllConfigs();
+    store->getConfigOrNull(vehicleProp);
+    store->readValuesForProperty(vehicleProp);
+    store->readValueOrNull(propValue);
+    store->readValueOrNull(propValue.prop, propValue.areaId, 0);
+    store->removeValuesForProperty(vehicleProp);
+    store->removeValue(propValue);
+    store->getConfigOrDie(vehicleProp);
+}
+
+void VehicleHalManagerFuzzer::invokeWatchDogClient() {
+    auto service = new VehicleHalManager(mHal.get());
+    sp<Looper> looper(Looper::prepare(/*opts=*/mFuzzedDataProvider->ConsumeBool()));
+    if (auto watchdogClient = ndk::SharedRefBase::make<WatchdogClient>(looper, service);
+        watchdogClient->initialize()) {
+        watchdogClient->checkIfAlive(-1, TimeoutLength::TIMEOUT_NORMAL);
+        watchdogClient->prepareProcessTermination();
+    }
+    delete service;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    VehicleHalManagerFuzzer vmFuzzer;
+    vmFuzzer.process(data, size);
+    return 0;
+}
+
+}  // namespace android::hardware::automotive::vehicle::V2_0::fuzzer
diff --git a/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h
new file mode 100644
index 0000000..e9335d3
--- /dev/null
+++ b/automotive/vehicle/2.0/default/tests/fuzzer/VehicleManager_fuzzer.h
@@ -0,0 +1,124 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#ifndef __VEHICLE_MANAGER_FUZZER_H__
+#define __VEHICLE_MANAGER_FUZZER_H__
+
+#include <vhal_v2_0/VehicleHalManager.h>
+#include <vhal_v2_0/VehiclePropertyStore.h>
+#include <vhal_v2_0/VmsUtils.h>
+
+#include <VehicleHalTestUtils.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android::hardware::automotive::vehicle::V2_0::fuzzer {
+
+constexpr int kRetriableAttempts = 3;
+
+class MockedVehicleHal : public VehicleHal {
+  public:
+    MockedVehicleHal()
+        : mFuelCapacityAttemptsLeft(kRetriableAttempts),
+          mMirrorFoldAttemptsLeft(kRetriableAttempts) {
+        mConfigs.assign(std::begin(kVehicleProperties), std::end(kVehicleProperties));
+    }
+
+    std::vector<VehiclePropConfig> listProperties() override { return mConfigs; }
+
+    VehiclePropValuePtr get(const VehiclePropValue& requestedPropValue,
+                            StatusCode* outStatus) override;
+
+    StatusCode set(const VehiclePropValue& propValue) override {
+        if (toInt(VehicleProperty::MIRROR_FOLD) == propValue.prop &&
+            mMirrorFoldAttemptsLeft-- > 0) {
+            return StatusCode::TRY_AGAIN;
+        }
+
+        mValues[makeKey(propValue)] = propValue;
+        return StatusCode::OK;
+    }
+
+    StatusCode subscribe(int32_t /* property */, float /* sampleRate */) override {
+        return StatusCode::OK;
+    }
+
+    StatusCode unsubscribe(int32_t /* property */) override { return StatusCode::OK; }
+
+    void sendPropEvent(recyclable_ptr<VehiclePropValue> value) { doHalEvent(std::move(value)); }
+
+    void sendHalError(StatusCode error, int32_t property, int32_t areaId) {
+        doHalPropertySetError(error, property, areaId);
+    }
+
+  private:
+    int64_t makeKey(const VehiclePropValue& v) const { return makeKey(v.prop, v.areaId); }
+
+    int64_t makeKey(int32_t prop, int32_t area) const {
+        return (static_cast<int64_t>(prop) << 32) | area;
+    }
+
+  private:
+    std::vector<VehiclePropConfig> mConfigs;
+    std::unordered_map<int64_t, VehiclePropValue> mValues;
+    int mFuelCapacityAttemptsLeft;
+    int mMirrorFoldAttemptsLeft;
+};
+
+class VehicleHalManagerFuzzer {
+  public:
+    VehicleHalManagerFuzzer() {
+        mHal.reset(new MockedVehicleHal);
+        mManager.reset(new VehicleHalManager(mHal.get()));
+        mObjectPool = mHal->getValuePool();
+    }
+    ~VehicleHalManagerFuzzer() {
+        mManager.reset(nullptr);
+        mHal.reset(nullptr);
+        mObjectPool = nullptr;
+        if (mFuzzedDataProvider) {
+            delete mFuzzedDataProvider;
+        }
+    }
+    void process(const uint8_t* data, size_t size);
+
+  private:
+    FuzzedDataProvider* mFuzzedDataProvider = nullptr;
+    VehiclePropValue mActualValue = VehiclePropValue{};
+    StatusCode mActualStatusCode = StatusCode::OK;
+
+    VehiclePropValuePool* mObjectPool = nullptr;
+    std::unique_ptr<MockedVehicleHal> mHal;
+    std::unique_ptr<VehicleHalManager> mManager;
+
+    void invokeDebug();
+    void invokePropConfigs();
+    void invokeSubscribe();
+    void invokeSetAndGetValues();
+    void invokeObd2SensorStore();
+    void invokeVmsUtils();
+    void invokeVehiclePropStore();
+    void invokeWatchDogClient();
+    void invokeGetSubscribedLayers(VmsMessageType type);
+    void invokeGet(int32_t property, int32_t areaId);
+};
+
+}  // namespace android::hardware::automotive::vehicle::V2_0::fuzzer
+
+#endif  // __VEHICLE_MANAGER_FUZZER_H__
diff --git a/bluetooth/audio/2.0/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.0/default/BluetoothAudioProvidersFactory.cpp
index df89cc8..0e5b7e4 100644
--- a/bluetooth/audio/2.0/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.0/default/BluetoothAudioProvidersFactory.cpp
@@ -75,7 +75,7 @@
         android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
     if (db_codec_capabilities.size()) {
       audio_capabilities.resize(db_codec_capabilities.size());
-      for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+      for (std::size_t i = 0; i < db_codec_capabilities.size(); ++i) {
         audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
       }
     }
diff --git a/bluetooth/audio/utils/OWNERS b/bluetooth/audio/utils/OWNERS
new file mode 100644
index 0000000..a35dde2
--- /dev/null
+++ b/bluetooth/audio/utils/OWNERS
@@ -0,0 +1,3 @@
+include platform/system/bt:/OWNERS
+
+cheneyni@google.com
\ No newline at end of file
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
index 50119bf..2f3ddaf 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession.cpp
@@ -43,7 +43,10 @@
 AudioConfiguration BluetoothAudioSession::invalidOffloadAudioConfiguration = {};
 
 static constexpr int kFmqSendTimeoutMs = 1000;  // 1000 ms timeout for sending
+static constexpr int kFmqReceiveTimeoutMs =
+    1000;                                       // 1000 ms timeout for receiving
 static constexpr int kWritePollMs = 1;          // polled non-blocking interval
+static constexpr int kReadPollMs = 1;           // polled non-blocking interval
 
 static inline timespec timespec_convert_from_hal(const TimeSpec& TS) {
   return {.tv_sec = static_cast<long>(TS.tvSec),
@@ -402,6 +405,39 @@
   return totalWritten;
 }
 
+// The control function reads stream from FMQ
+size_t BluetoothAudioSession::InReadPcmData(void* buffer, size_t bytes) {
+  if (buffer == nullptr || !bytes) return 0;
+  size_t totalRead = 0;
+  int ms_timeout = kFmqReceiveTimeoutMs;
+  do {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    if (!IsSessionReady()) break;
+    size_t availableToRead = mDataMQ->availableToRead();
+    if (availableToRead) {
+      if (availableToRead > (bytes - totalRead)) {
+        availableToRead = bytes - totalRead;
+      }
+      if (!mDataMQ->read(static_cast<uint8_t*>(buffer) + totalRead,
+                         availableToRead)) {
+        ALOGE("FMQ datapath reading %zu/%zu failed", totalRead, bytes);
+        return totalRead;
+      }
+      totalRead += availableToRead;
+    } else if (ms_timeout >= kReadPollMs) {
+      lock.unlock();
+      usleep(kReadPollMs * 1000);
+      ms_timeout -= kReadPollMs;
+      continue;
+    } else {
+      ALOGD("in data %zu/%zu overflow %d ms", totalRead, bytes,
+            (kFmqReceiveTimeoutMs - ms_timeout));
+      return totalRead;
+    }
+  } while (totalRead < bytes);
+  return totalRead;
+}
+
 std::unique_ptr<BluetoothAudioSessionInstance>
     BluetoothAudioSessionInstance::instance_ptr =
         std::unique_ptr<BluetoothAudioSessionInstance>(
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession.h b/bluetooth/audio/utils/session/BluetoothAudioSession.h
index 838d1cc..83e20ad 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession.h
@@ -79,6 +79,8 @@
 };
 
 class BluetoothAudioSession {
+  friend class BluetoothAudioSession_2_1;
+
  private:
   // using recursive_mutex to allow hwbinder to re-enter agian.
   std::recursive_mutex mutex_;
@@ -153,6 +155,8 @@
 
   // The control function writes stream to FMQ
   size_t OutWritePcmData(const void* buffer, size_t bytes);
+  // The control function read stream from FMQ
+  size_t InReadPcmData(void* buffer, size_t bytes);
 
   static constexpr PcmParameters kInvalidPcmParameters = {
       .sampleRate = SampleRate::RATE_UNKNOWN,
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
index 86af468..4d7be21 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_1.h
@@ -25,6 +25,8 @@
 class BluetoothAudioSessionControl_2_1 {
   using SessionType_2_1 =
       ::android::hardware::bluetooth::audio::V2_1::SessionType;
+  using AudioConfiguration_2_1 =
+      ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
 
  public:
   // The control API helps to check if session is ready or not
@@ -65,18 +67,17 @@
 
   // The control API for the bluetooth_audio module to get current
   // AudioConfiguration
-  static const AudioConfiguration& GetAudioConfig(
+  static const AudioConfiguration_2_1 GetAudioConfig(
       const SessionType_2_1& session_type) {
     std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
         BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
     if (session_ptr != nullptr) {
-      // TODO: map 2.1 to 2.0 audio config inside GetAudioConfig?
-      return session_ptr->GetAudioSession()->GetAudioConfig();
+      return session_ptr->GetAudioConfig();
     } else if (session_type ==
                SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
-      return BluetoothAudioSession::kInvalidOffloadAudioConfiguration;
+      return BluetoothAudioSession_2_1::kInvalidOffloadAudioConfiguration;
     } else {
-      return BluetoothAudioSession::kInvalidSoftwareAudioConfiguration;
+      return BluetoothAudioSession_2_1::kInvalidSoftwareAudioConfiguration;
     }
   }
 
@@ -141,6 +142,17 @@
     }
     return 0;
   }
+
+  // The control API reads stream from FMQ
+  static size_t InReadPcmData(const SessionType_2_1& session_type, void* buffer,
+                              size_t bytes) {
+    std::shared_ptr<BluetoothAudioSession_2_1> session_ptr =
+        BluetoothAudioSessionInstance_2_1::GetSessionInstance(session_type);
+    if (session_ptr != nullptr) {
+      return session_ptr->GetAudioSession()->InReadPcmData(buffer, bytes);
+    }
+    return 0;
+  }
 };
 
 }  // namespace audio
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
index 9e1baf4..9d91196 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.cpp
@@ -29,6 +29,11 @@
 using SessionType_2_0 =
     ::android::hardware::bluetooth::audio::V2_0::SessionType;
 
+::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+    BluetoothAudioSession_2_1::invalidSoftwareAudioConfiguration = {};
+::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+    BluetoothAudioSession_2_1::invalidOffloadAudioConfiguration = {};
+
 namespace {
 bool is_2_0_session_type(
     const ::android::hardware::bluetooth::audio::V2_1::SessionType&
@@ -60,6 +65,71 @@
   return audio_session;
 }
 
+// The control function is for the bluetooth_audio module to get the current
+// AudioConfiguration
+const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+BluetoothAudioSession_2_1::GetAudioConfig() {
+  std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+  if (audio_session->IsSessionReady()) {
+    // If session is unknown it means it should be 2.0 type
+    if (session_type_2_1_ != SessionType_2_1::UNKNOWN)
+      return audio_config_2_1_;
+
+    ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration toConf;
+    const AudioConfiguration fromConf = GetAudioSession()->GetAudioConfig();
+    // pcmConfig only differs between 2.0 and 2.1 in AudioConfiguration
+    if (fromConf.getDiscriminator() ==
+        AudioConfiguration::hidl_discriminator::codecConfig) {
+      toConf.codecConfig() = fromConf.codecConfig();
+    } else {
+      toConf.pcmConfig() = {
+          .sampleRate = static_cast<
+              ::android::hardware::bluetooth::audio::V2_1::SampleRate>(
+              fromConf.pcmConfig().sampleRate),
+          .channelMode = fromConf.pcmConfig().channelMode,
+          .bitsPerSample = fromConf.pcmConfig().bitsPerSample,
+          .dataIntervalUs = 0};
+    }
+    return toConf;
+  } else if (session_type_2_1_ ==
+             SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+    return kInvalidOffloadAudioConfiguration;
+  } else {
+    return kInvalidSoftwareAudioConfiguration;
+  }
+}
+
+bool BluetoothAudioSession_2_1::UpdateAudioConfig(
+    const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+        audio_config) {
+  bool is_software_session =
+      (session_type_2_1_ == SessionType_2_1::A2DP_SOFTWARE_ENCODING_DATAPATH ||
+       session_type_2_1_ ==
+           SessionType_2_1::HEARING_AID_SOFTWARE_ENCODING_DATAPATH ||
+       session_type_2_1_ ==
+           SessionType_2_1::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH ||
+       session_type_2_1_ ==
+           SessionType_2_1::LE_AUDIO_SOFTWARE_DECODED_DATAPATH);
+  bool is_offload_session =
+      (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH);
+  auto audio_config_discriminator = audio_config.getDiscriminator();
+  bool is_software_audio_config =
+      (is_software_session &&
+       audio_config_discriminator ==
+           ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
+               hidl_discriminator::pcmConfig);
+  bool is_offload_audio_config =
+      (is_offload_session &&
+       audio_config_discriminator ==
+           ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration::
+               hidl_discriminator::codecConfig);
+  if (!is_software_audio_config && !is_offload_audio_config) {
+    return false;
+  }
+  audio_config_2_1_ = audio_config;
+  return true;
+}
+
 // The report function is used to report that the Bluetooth stack has started
 // this session without any failure, and will invoke session_changed_cb_ to
 // notify those registered bluetooth_audio outputs
@@ -86,7 +156,27 @@
 
     audio_session->OnSessionStarted(stack_iface, dataMQ, config);
   } else {
-    LOG(FATAL) << " Not implemented yet!!";
+    std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+    if (stack_iface == nullptr) {
+      LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << ", IBluetoothAudioPort Invalid";
+    } else if (!UpdateAudioConfig(audio_config)) {
+      LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << ", AudioConfiguration=" << toString(audio_config)
+                 << " Invalid";
+    } else if (!audio_session->UpdateDataPath(dataMQ)) {
+      LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                 << " DataMQ Invalid";
+      audio_config_2_1_ =
+          (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH
+               ? kInvalidOffloadAudioConfiguration
+               : kInvalidSoftwareAudioConfiguration);
+    } else {
+      audio_session->stack_iface_ = stack_iface;
+      LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+                << ", AudioConfiguration=" << toString(audio_config);
+      audio_session->ReportSessionStatus();
+    };
   }
 }
 
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
index 0e9c12b..5a35153 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_1.h
@@ -40,6 +40,11 @@
       const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
           audio_config);
 
+  static ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+      invalidSoftwareAudioConfiguration;
+  static ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
+      invalidOffloadAudioConfiguration;
+
  public:
   BluetoothAudioSession_2_1(
       const ::android::hardware::bluetooth::audio::V2_1::SessionType&
@@ -58,8 +63,15 @@
 
   // The control function is for the bluetooth_audio module to get the current
   // AudioConfiguration
-  const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration&
+  const ::android::hardware::bluetooth::audio::V2_1::AudioConfiguration
   GetAudioConfig();
+
+  static constexpr ::android::hardware::bluetooth::audio::V2_1::
+      AudioConfiguration& kInvalidSoftwareAudioConfiguration =
+          invalidSoftwareAudioConfiguration;
+  static constexpr ::android::hardware::bluetooth::audio::V2_1::
+      AudioConfiguration& kInvalidOffloadAudioConfiguration =
+          invalidOffloadAudioConfiguration;
 };
 
 class BluetoothAudioSessionInstance_2_1 {
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index ce50f25..5ba7a76 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -486,6 +486,50 @@
 }
 
 /**
+ * Test tuning with DAB selector.
+ *
+ * Verifies that:
+ *  - if DAB selector is not supported, the method returns NOT_SUPPORTED;
+ *  - if it is supported, the method succeeds;
+ *  - after a successful tune call, onCurrentProgramInfoChanged callback is
+ *    invoked carrying a proper selector;
+ *  - program changes exactly to what was requested.
+ */
+TEST_F(BroadcastRadioHalTest, DabTune) {
+    ASSERT_TRUE(openSession());
+
+    ProgramSelector sel = {};
+    uint64_t freq = 178352;
+    sel.primaryId = make_identifier(IdentifierType::DAB_FREQUENCY,freq);
+
+    std::this_thread::sleep_for(gTuneWorkaround);
+
+    // try tuning
+    ProgramInfo infoCb = {};
+    EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChanged_,
+                        InfoHasId(utils::make_identifier(IdentifierType::DAB_FREQUENCY, freq)))
+        .Times(AnyNumber())
+        .WillOnce(DoAll(SaveArg<0>(&infoCb), testing::Return(ByMove(Void()))));
+    auto result = mSession->tune(sel);
+
+    // expect a failure if it's not supported
+    if (!utils::isSupported(mProperties, sel)) {
+        EXPECT_EQ(Result::NOT_SUPPORTED, result);
+        return;
+    }
+
+    // expect a callback if it succeeds
+    EXPECT_EQ(Result::OK, result);
+    EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChanged_, timeout::tune);
+
+    LOG(DEBUG) << "current program info: " << toString(infoCb);
+
+    // it should tune exactly to what was requested
+    auto freqs = utils::getAllIds(infoCb.selector, IdentifierType::DAB_FREQUENCY);
+    EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq));
+}
+
+/**
  * Test tuning with empty program selector.
  *
  * Verifies that:
@@ -516,6 +560,12 @@
 
     EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChanged_, _).Times(AnyNumber());
     auto result = mSession->scan(true /* up */, true /* skip subchannel */);
+
+    if (result == Result::NOT_SUPPORTED) {
+        printSkipped("seek not supported");
+        return;
+    }
+
     EXPECT_EQ(Result::OK, result);
     EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChanged_, timeout::tune);
 
@@ -565,6 +615,12 @@
 
     for (int i = 0; i < 10; i++) {
         auto result = mSession->scan(true /* up */, true /* skip subchannel */);
+
+        if (result == Result::NOT_SUPPORTED) {
+            printSkipped("cancel is skipped because of seek not supported");
+            return;
+        }
+
         ASSERT_EQ(Result::OK, result);
 
         auto cancelResult = mSession->cancel();
diff --git a/common/aidl/Android.bp b/common/aidl/Android.bp
index 127b6c0..912bfdc 100644
--- a/common/aidl/Android.bp
+++ b/common/aidl/Android.bp
@@ -31,6 +31,7 @@
             apex_available: [
                 "//apex_available:platform",
                 "com.android.media.swcodec",
+                "com.android.neuralnetworks",
             ],
             min_sdk_version: "29",
         },
diff --git a/compatibility_matrices/build/vintf_compatibility_matrix.go b/compatibility_matrices/build/vintf_compatibility_matrix.go
index 2772ba3..f1bd0ae 100644
--- a/compatibility_matrices/build/vintf_compatibility_matrix.go
+++ b/compatibility_matrices/build/vintf_compatibility_matrix.go
@@ -41,7 +41,7 @@
 	}, "inputs")
 
 	xmllintXsd = pctx.AndroidStaticRule("xmllint-xsd", blueprint.RuleParams{
-		Command:     `$XmlLintCmd --schema $xsd $in > /dev/null && touch -a $out`,
+		Command:     `$XmlLintCmd --quiet --schema $xsd $in > /dev/null && touch -a $out`,
 		CommandDeps: []string{"$XmlLintCmd"},
 		Restat:      true,
 	}, "xsd")
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 96a3692..8e175f0 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -256,6 +256,13 @@
     </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.identity</name>
+        <!--
+          b/178458001: identity V2 is introduced in R, but Android R VINTF does not support AIDL
+          versions. Hence, we only specify identity V2 in compatibility_matrix.5.xml in Android S+
+          branches. In Android R branches, the matrix implicitly specifies V1.
+          SingleManifestTest.ManifestAidlHalsServed has an exemption for this.
+        -->
+        <version>1-2</version>
         <interface>
             <name>IIdentityCredentialStore</name>
             <instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 6631d8a..30af25f 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -368,14 +368,6 @@
         </interface>
     </hal>
     <hal format="hidl" optional="true">
-        <name>android.hardware.memtrack</name>
-        <version>1.0</version>
-        <interface>
-            <name>IMemtrack</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
         <name>android.hardware.neuralnetworks</name>
         <version>1.0-3</version>
         <interface>
diff --git a/current.txt b/current.txt
index 29a837f..c90c7dd 100644
--- a/current.txt
+++ b/current.txt
@@ -776,7 +776,7 @@
 dabe23dde7c9e3ad65c61def7392f186d7efe7f4216f9b6f9cf0863745b1a9f4 android.hardware.keymaster@4.1::IKeymasterDevice
 cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice
 f729ee6a5f136b25d79ea6895d24700fce413df555baaecf2c39e4440d15d043 android.hardware.neuralnetworks@1.0::types
-c6ae443608502339aec4256feef48e7b2d36f7477ca5361cc95cd27a8ed9c612 android.hardware.neuralnetworks@1.2::types
+ba84f3a750b1cc43ac51074e8b8e22df924f3e6d9068fac50d95bcf57b2b1d61 android.hardware.neuralnetworks@1.2::types
 9fe5a4093043c2b5da4e9491aed1646c388a5d3059b8fd77d5b6a9807e6d3a3e android.hardware.neuralnetworks@1.3::types
 e8c86c69c438da8d1549856c1bb3e2d1b8da52722f8235ff49a30f2cce91742c android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback
 b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardware.renderscript@1.0::types
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index 9477997..c8ee0dd 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -253,14 +253,17 @@
         }
     }
 
-    // Feed the auth token to secure hardware.
-    if (!hwProxy_->setAuthToken(authToken.challenge, authToken.userId, authToken.authenticatorId,
-                                int(authToken.authenticatorType), authToken.timestamp.milliSeconds,
-                                authToken.mac, verificationToken_.challenge,
-                                verificationToken_.timestamp.milliSeconds,
-                                int(verificationToken_.securityLevel), verificationToken_.mac)) {
-        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
-                IIdentityCredentialStore::STATUS_INVALID_DATA, "Invalid Auth Token"));
+    // Feed the auth token to secure hardware only if they're valid.
+    if (authToken.timestamp.milliSeconds != 0) {
+        if (!hwProxy_->setAuthToken(
+                    authToken.challenge, authToken.userId, authToken.authenticatorId,
+                    int(authToken.authenticatorType), authToken.timestamp.milliSeconds,
+                    authToken.mac, verificationToken_.challenge,
+                    verificationToken_.timestamp.milliSeconds,
+                    int(verificationToken_.securityLevel), verificationToken_.mac)) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA, "Invalid Auth Token"));
+        }
     }
 
     // We'll be feeding ACPs interleaved with certificates from the reader
diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c
index 5e9a280..9e033b3 100644
--- a/identity/aidl/default/libeic/EicPresentation.c
+++ b/identity/aidl/default/libeic/EicPresentation.c
@@ -336,6 +336,18 @@
                                  int verificationTokenSecurityLevel,
                                  const uint8_t* verificationTokenMac,
                                  size_t verificationTokenMacSize) {
+    // It doesn't make sense to accept any tokens if eicPresentationCreateAuthChallenge()
+    // was never called.
+    if (ctx->authChallenge == 0) {
+        eicDebug("Trying validate tokens when no auth-challenge was previously generated");
+        return false;
+    }
+    // At least the verification-token must have the same challenge as what was generated.
+    if (verificationTokenChallenge != ctx->authChallenge) {
+        eicDebug("Challenge in verification token does not match the challenge "
+                 "previously generated");
+        return false;
+    }
     if (!eicOpsValidateAuthToken(
                 challenge, secureUserId, authenticatorId, hardwareAuthenticatorType, timeStamp, mac,
                 macSize, verificationTokenChallenge, verificationTokenTimestamp,
@@ -360,18 +372,9 @@
         return false;
     }
 
+    // Only ACP with auth-on-every-presentation - those with timeout == 0 - need the
+    // challenge to match...
     if (timeoutMillis == 0) {
-        if (ctx->authTokenChallenge == 0) {
-            eicDebug("No challenge in authToken");
-            return false;
-        }
-
-        // If we didn't create a challenge, too bad but user auth with
-        // timeoutMillis set to 0 needs it.
-        if (ctx->authChallenge == 0) {
-            eicDebug("No challenge was created for this session");
-            return false;
-        }
         if (ctx->authTokenChallenge != ctx->authChallenge) {
             eicDebug("Challenge in authToken (%" PRIu64
                      ") doesn't match the challenge "
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
index 6418028..aba89c1 100644
--- a/identity/support/src/IdentityCredentialSupport.cpp
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -928,7 +928,7 @@
 
     // translate certificate format from keymaster_cert_chain_t to vector<vector<uint8_t>>.
     vector<vector<uint8_t>> attestationCertificate;
-    for (int i = 0; i < cert_chain_out.entry_count; i++) {
+    for (std::size_t i = 0; i < cert_chain_out.entry_count; i++) {
         attestationCertificate.insert(
                 attestationCertificate.end(),
                 vector<uint8_t>(
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index b32298e..e0d60fc 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -2567,7 +2567,8 @@
     string message = "Hello World!";
     auto params = AuthorizationSetBuilder().Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
     string ciphertext1 = EncryptMessage(message, params);
-    EXPECT_EQ(2048U / 8, ciphertext1.size());
+    // Die here on failure because we try to modify ciphertext1 below
+    ASSERT_EQ(2048U / 8, ciphertext1.size()) << "Failed to encrypt the message";
 
     string ciphertext2 = EncryptMessage(message, params);
     EXPECT_EQ(2048U / 8, ciphertext2.size());
diff --git a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
index 18587ee..e78d4d7 100644
--- a/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
+++ b/memtrack/aidl/android/hardware/memtrack/IMemtrack.aidl
@@ -30,6 +30,22 @@
  * GL, graphics, etc. All memory sizes must be in real memory usage,
  * accounting for stride, bit depth, rounding up to page size, etc.
  *
+ * The following getMemory() categories are important for memory accounting in
+ * `dumpsys meminfo` and should be reported as described below:
+ *
+ * - MemtrackType::GRAPHICS and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
+ *     This should report the PSS of all DMA buffers mapped by the process
+ *     with the specified PID. This PSS can be calculated using ReadDmaBufPss()
+ *     form libdmabufinfo.
+ *
+ * - MemtrackType::GL and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
+ *     This category should report all GPU private allocations for the specified
+ *     PID that are not accounted in /proc/<pid>/smaps.
+ *
+ * - MemtrackType::OTHER and MemtrackRecord::FLAG_SMAPS_UNACCOUNTED
+ *     Any other memory not accounted for in /proc/<pid>/smaps if any, otherwise
+ *     this should return 0.
+ *
  * Constructor for the interface should be used to perform memtrack management
  * setup actions and must be called once before any calls to getMemory().
  */
@@ -76,7 +92,10 @@
      * This information is used to identify GPU devices for GPU specific
      * memory accounting (e.g. DMA buffer usage).
      *
+     * The device name(s) provided in getGpuDeviceInfo() must match the
+     * device name in the corresponding device(s) sysfs entry.
+     *
      * @return vector of DeviceInfo populated for all GPU devices.
      */
-     DeviceInfo[] getGpuDeviceInfo();
+    DeviceInfo[] getGpuDeviceInfo();
 }
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 7cec49e..e3cee93 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -4711,14 +4711,14 @@
     // HAL equivalent of unknown type and a 1.2 HAL implementation must belong
     // to one of the categories below.
     /** The device does not fall into any category below. */
-    OTHER             = 1,
+    OTHER = 1,
     /** The device runs NNAPI models on single or multi-core CPU. */
-    CPU               = 2,
+    CPU = 2,
     /** The device can run NNAPI models and also accelerate graphics APIs such
-      * as OpenGL ES and Vulkan. */
-    GPU               = 3,
+     * as OpenGL ES and Vulkan. */
+    GPU = 3,
     /** Dedicated accelerator for Machine Learning workloads. */
-    ACCELERATOR       = 4,
+    ACCELERATOR = 4,
 };
 
 /**
@@ -5054,7 +5054,7 @@
  * Specifies whether or not to measure timing information during execution.
  */
 enum MeasureTiming : int32_t {
-    NO  = 0,
+    NO = 0,
     YES = 1,
 };
 
diff --git a/neuralnetworks/1.2/types.t b/neuralnetworks/1.2/types.t
index 21d88ac..054d516 100644
--- a/neuralnetworks/1.2/types.t
+++ b/neuralnetworks/1.2/types.t
@@ -107,14 +107,14 @@
     // HAL equivalent of unknown type and a 1.2 HAL implementation must belong
     // to one of the categories below.
     /** The device does not fall into any category below. */
-    OTHER             = 1,
+    OTHER = 1,
     /** The device runs NNAPI models on single or multi-core CPU. */
-    CPU               = 2,
+    CPU = 2,
     /** The device can run NNAPI models and also accelerate graphics APIs such
-      * as OpenGL ES and Vulkan. */
-    GPU               = 3,
+     * as OpenGL ES and Vulkan. */
+    GPU = 3,
     /** Dedicated accelerator for Machine Learning workloads. */
-    ACCELERATOR       = 4,
+    ACCELERATOR = 4,
 };
 
 /**
@@ -450,7 +450,7 @@
  * Specifies whether or not to measure timing information during execution.
  */
 enum MeasureTiming : int32_t {
-    NO  = 0,
+    NO = 0,
     YES = 1,
 };
 
diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING
index de84624..5d168d2 100644
--- a/neuralnetworks/TEST_MAPPING
+++ b/neuralnetworks/TEST_MAPPING
@@ -60,6 +60,17 @@
           "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
         }
       ]
+    },
+    {
+      "name": "VtsHalNeuralnetworksTargetTest",
+      "options": [
+        {
+          // Do not use any sample driver except sample-all in order to reduce
+          // testing time. The other sample drivers (fast-float, quant, etc.)
+          // are subsets of sample-all.
+          "include-filter": "-*sample_float_fast*:*sample_float_slow*:*sample_minimal*:*sample_quant*"
+        }
+      ]
     }
   ]
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/FencedExecutionResult.aidl
similarity index 82%
rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
rename to neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/FencedExecutionResult.aidl
index 2706623..7952b34 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterArray.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/FencedExecutionResult.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2020 The Android Open Source Project
+ * Copyright (C) 2021 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -12,7 +12,8 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
- *////////////////////////////////////////////////////////////////////////////////
+ */
+///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -30,8 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.security.keymint;
+package android.hardware.neuralnetworks;
 @VintfStability
-parcelable KeyParameterArray {
-  android.hardware.security.keymint.KeyParameter[] params;
+parcelable FencedExecutionResult {
+  android.hardware.neuralnetworks.IFencedExecutionCallback callback;
+  @nullable ParcelFileDescriptor syncFence;
 }
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
index 3ca1550..1f7cbe0 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -34,7 +34,7 @@
 @VintfStability
 interface IPreparedModel {
   android.hardware.neuralnetworks.ExecutionResult executeSynchronously(in android.hardware.neuralnetworks.Request request, in boolean measureTiming, in long deadline, in long loopTimeoutDuration);
-  android.hardware.neuralnetworks.IFencedExecutionCallback executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadline, in long loopTimeoutDuration, in long duration, out @nullable ParcelFileDescriptor syncFence);
+  android.hardware.neuralnetworks.FencedExecutionResult executeFenced(in android.hardware.neuralnetworks.Request request, in ParcelFileDescriptor[] waitFor, in boolean measureTiming, in long deadline, in long loopTimeoutDuration, in long duration);
   const long DEFAULT_LOOP_TIMEOUT_DURATION_NS = 2000000000;
   const long MAXIMUM_LOOP_TIMEOUT_DURATION_NS = 15000000000;
 }
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/FencedExecutionResult.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/FencedExecutionResult.aidl
new file mode 100644
index 0000000..ba3be31
--- /dev/null
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/FencedExecutionResult.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.neuralnetworks;
+
+import android.hardware.neuralnetworks.IFencedExecutionCallback;
+
+/**
+ * A result from running an asynchronous execution of a prepared model.
+ */
+@VintfStability
+parcelable FencedExecutionResult {
+    /**
+     * IFencedExecutionCallback can be used to query information like duration and error
+     * status when the execution is completed.
+     */
+    IFencedExecutionCallback callback;
+    /**
+     * The sync fence that will be signaled when the task is completed. The
+     * sync fence will be set to error if a critical error, e.g. hardware
+     * failure or kernel panic, occurs when doing execution.
+     */
+    @nullable ParcelFileDescriptor syncFence;
+}
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
index 2414a4a..0240e3c 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/IPreparedModel.aidl
@@ -19,7 +19,7 @@
 import android.hardware.common.NativeHandle;
 import android.hardware.neuralnetworks.ErrorStatus;
 import android.hardware.neuralnetworks.ExecutionResult;
-import android.hardware.neuralnetworks.IFencedExecutionCallback;
+import android.hardware.neuralnetworks.FencedExecutionResult;
 import android.hardware.neuralnetworks.Request;
 
 /**
@@ -152,11 +152,8 @@
      *                 complete after all sync fences in waitFor are signaled. If the execution
      *                 cannot be finished within the duration, the execution may be aborted. Passing
      *                 -1 means the duration is omitted. Other negative values are invalid.
-     * @param out syncFence The sync fence that will be signaled when the task is completed. The
-     *                      sync fence will be set to error if a critical error, e.g. hardware
-     *                      failure or kernel panic, occurs when doing execution.
-     * @return The IFencedExecutionCallback can be used to query information like duration and error
-     *     status when the execution is completed.
+     * @return The FencedExecutionResult parcelable, containing IFencedExecutionCallback and the
+     *         sync fence.
      * @throws ServiceSpecificException with one of the following ErrorStatus values:
      *     - DEVICE_UNAVAILABLE if driver is offline or busy
      *     - GENERAL_FAILURE if there is an unspecified error
@@ -166,7 +163,7 @@
      *       deadline
      *     - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
      */
-    IFencedExecutionCallback executeFenced(in Request request, in ParcelFileDescriptor[] waitFor,
+    FencedExecutionResult executeFenced(in Request request, in ParcelFileDescriptor[] waitFor,
             in boolean measureTiming, in long deadline, in long loopTimeoutDuration,
-            in long duration, out @nullable ParcelFileDescriptor syncFence);
+            in long duration);
 }
diff --git a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
index 4beb828..4eb704b 100644
--- a/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/aidl/vts/functional/GeneratedTestHarness.cpp
@@ -571,33 +571,32 @@
         case Executor::FENCED: {
             SCOPED_TRACE("fenced");
             ErrorStatus result = ErrorStatus::NONE;
-            ndk::ScopedFileDescriptor syncFenceFd;
-            std::shared_ptr<IFencedExecutionCallback> fencedCallback;
+            FencedExecutionResult executionResult;
             auto ret = preparedModel->executeFenced(request, {}, testConfig.measureTiming,
                                                     kNoDeadline, loopTimeoutDuration, kNoDuration,
-                                                    &syncFenceFd, &fencedCallback);
+                                                    &executionResult);
             ASSERT_TRUE(ret.isOk() || ret.getExceptionCode() == EX_SERVICE_SPECIFIC)
                     << ret.getDescription();
             if (!ret.isOk()) {
                 result = static_cast<ErrorStatus>(ret.getServiceSpecificError());
                 executionStatus = result;
-            } else if (syncFenceFd.get() != -1) {
+            } else if (executionResult.syncFence.get() != -1) {
                 std::vector<ndk::ScopedFileDescriptor> waitFor;
-                auto dupFd = dup(syncFenceFd.get());
+                auto dupFd = dup(executionResult.syncFence.get());
                 ASSERT_NE(dupFd, -1);
                 waitFor.emplace_back(dupFd);
                 // If a sync fence is returned, try start another run waiting for the sync fence.
                 ret = preparedModel->executeFenced(request, waitFor, testConfig.measureTiming,
                                                    kNoDeadline, loopTimeoutDuration, kNoDuration,
-                                                   &syncFenceFd, &fencedCallback);
+                                                   &executionResult);
                 ASSERT_TRUE(ret.isOk());
-                waitForSyncFence(syncFenceFd.get());
+                waitForSyncFence(executionResult.syncFence.get());
             }
             if (result == ErrorStatus::NONE) {
-                ASSERT_NE(fencedCallback, nullptr);
+                ASSERT_NE(executionResult.callback, nullptr);
                 Timing timingFenced;
-                auto ret =
-                        fencedCallback->getExecutionInfo(&timing, &timingFenced, &executionStatus);
+                auto ret = executionResult.callback->getExecutionInfo(&timing, &timingFenced,
+                                                                      &executionStatus);
                 ASSERT_TRUE(ret.isOk());
             }
             break;
diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
index a37a0ca..1929750 100644
--- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
@@ -198,8 +198,8 @@
                 static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
     }
     ndk::ScopedAStatus executeFenced(const Request&, const std::vector<ndk::ScopedFileDescriptor>&,
-                                     bool, int64_t, int64_t, int64_t, ndk::ScopedFileDescriptor*,
-                                     std::shared_ptr<IFencedExecutionCallback>*) override {
+                                     bool, int64_t, int64_t, int64_t,
+                                     FencedExecutionResult*) override {
         return ndk::ScopedAStatus::fromServiceSpecificError(
                 static_cast<int32_t>(ErrorStatus::GENERAL_FAILURE));
     }
@@ -893,25 +893,24 @@
 
     ErrorStatus executeFenced(const std::shared_ptr<IPreparedModel>& preparedModel,
                               const Request& request) {
-        ndk::ScopedFileDescriptor syncFence;
-        std::shared_ptr<IFencedExecutionCallback> fencedCallback;
+        FencedExecutionResult executionResult;
         const auto ret = preparedModel->executeFenced(request, {}, false, kNoDeadline,
                                                       kOmittedTimeoutDuration, kNoDuration,
-                                                      &syncFence, &fencedCallback);
+                                                      &executionResult);
         if (!ret.isOk()) {
             EXPECT_EQ(ret.getExceptionCode(), EX_SERVICE_SPECIFIC);
             return static_cast<ErrorStatus>(ret.getServiceSpecificError());
         }
-        if (syncFence.get() != -1) {
-            waitForSyncFence(syncFence.get());
+        if (executionResult.syncFence.get() != -1) {
+            waitForSyncFence(executionResult.syncFence.get());
         }
-        EXPECT_NE(fencedCallback, nullptr);
+        EXPECT_NE(executionResult.callback, nullptr);
 
         ErrorStatus executionStatus = ErrorStatus::GENERAL_FAILURE;
         Timing time = kNoTiming;
         Timing timeFenced = kNoTiming;
         const auto retExecutionInfo =
-                fencedCallback->getExecutionInfo(&time, &timeFenced, &executionStatus);
+                executionResult.callback->getExecutionInfo(&time, &timeFenced, &executionStatus);
         EXPECT_TRUE(retExecutionInfo.isOk());
         EXPECT_EQ(time, kNoTiming);
         return executionStatus;
diff --git a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
index db8f429..3be4c1b 100644
--- a/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/aidl/vts/functional/ValidateRequest.cpp
@@ -68,11 +68,10 @@
     // fenced
     {
         SCOPED_TRACE(message + " [executeFenced]");
-        ndk::ScopedFileDescriptor syncFence;
-        std::shared_ptr<IFencedExecutionCallback> callback;
+        FencedExecutionResult executionResult;
         const auto executeStatus = preparedModel->executeFenced(request, {}, false, kNoDeadline,
                                                                 kOmittedTimeoutDuration,
-                                                                kNoDuration, &syncFence, &callback);
+                                                                kNoDuration, &executionResult);
         ASSERT_FALSE(executeStatus.isOk());
         ASSERT_EQ(executeStatus.getExceptionCode(), EX_SERVICE_SPECIFIC);
         ASSERT_EQ(static_cast<ErrorStatus>(executeStatus.getServiceSpecificError()),
diff --git a/neuralnetworks/utils/adapter/Android.bp b/neuralnetworks/utils/adapter/Android.bp
index e8dc3e7..d073106 100644
--- a/neuralnetworks/utils/adapter/Android.bp
+++ b/neuralnetworks/utils/adapter/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
 cc_library_static {
     name: "neuralnetworks_utils_hal_adapter",
     defaults: ["neuralnetworks_utils_defaults"],
diff --git a/power/stats/aidl/OWNERS b/power/stats/aidl/OWNERS
new file mode 100644
index 0000000..b290b49
--- /dev/null
+++ b/power/stats/aidl/OWNERS
@@ -0,0 +1,3 @@
+bsschwar@google.com
+krossmo@google.com
+tstrudel@google.com
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index 3867842..9e92d93 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -26,46 +26,56 @@
 cc_test {
     name: "VtsHalRadioV1_0TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
-    srcs: ["radio_hidl_hal_cell_broadcast.cpp",
-           "radio_hidl_hal_data.cpp",
-           "radio_hidl_hal_icc.cpp",
-           "radio_hidl_hal_ims.cpp",
-           "radio_hidl_hal_misc.cpp",
-           "radio_hidl_hal_sms.cpp",
-           "radio_hidl_hal_stk.cpp",
-           "radio_hidl_hal_test.cpp",
-           "radio_hidl_hal_voice.cpp",
-           "radio_indication.cpp",
-           "radio_response.cpp",
-           "VtsHalRadioV1_0TargetTest.cpp",
-           "vts_test_util.cpp"],
+    srcs: [
+        "radio_hidl_hal_cell_broadcast.cpp",
+        "radio_hidl_hal_data.cpp",
+        "radio_hidl_hal_icc.cpp",
+        "radio_hidl_hal_ims.cpp",
+        "radio_hidl_hal_misc.cpp",
+        "radio_hidl_hal_sms.cpp",
+        "radio_hidl_hal_stk.cpp",
+        "radio_hidl_hal_test.cpp",
+        "radio_hidl_hal_voice.cpp",
+        "radio_indication.cpp",
+        "radio_response.cpp",
+        "VtsHalRadioV1_0TargetTest.cpp",
+        "vts_test_util.cpp",
+    ],
     static_libs: [
         "android.hardware.radio@1.0",
     ],
     test_config: "vts_hal_radio_target_test.xml",
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
 
 cc_test {
     name: "VtsHalSapV1_0TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
-    srcs: ["sap_callback.cpp",
-           "sap_hidl_hal_api.cpp",
-           "sap_hidl_hal_test.cpp",
-           "VtsHalSapV1_0TargetTest.cpp",
-           "vts_test_util.cpp"],
+    srcs: [
+        "sap_callback.cpp",
+        "sap_hidl_hal_api.cpp",
+        "sap_hidl_hal_test.cpp",
+        "VtsHalSapV1_0TargetTest.cpp",
+        "vts_test_util.cpp",
+    ],
     static_libs: [
         "android.hardware.radio@1.0",
     ],
     test_config: "vts_hal_sap_target_test.xml",
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
 
 cc_library_static {
     name: "RadioVtsTestUtilBase",
     defaults: ["VtsHalTargetTestDefaults"],
-    srcs : [
-        "vts_test_util.cpp"
+    srcs: [
+        "vts_test_util.cpp",
     ],
     shared_libs: [
         "android.hardware.radio@1.0",
diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp
index c576fe8..3ada6ff 100644
--- a/radio/1.1/vts/functional/Android.bp
+++ b/radio/1.1/vts/functional/Android.bp
@@ -26,11 +26,13 @@
 cc_test {
     name: "VtsHalRadioV1_1TargetTest",
     defaults: ["VtsHalTargetTestDefaults"],
-    srcs: ["radio_hidl_hal_api.cpp",
-           "radio_hidl_hal_test.cpp",
-           "radio_indication.cpp",
-           "radio_response.cpp",
-           "VtsHalRadioV1_1TargetTest.cpp"],
+    srcs: [
+        "radio_hidl_hal_api.cpp",
+        "radio_hidl_hal_test.cpp",
+        "radio_indication.cpp",
+        "radio_response.cpp",
+        "VtsHalRadioV1_1TargetTest.cpp",
+    ],
     static_libs: [
         "RadioVtsTestUtilBase",
         "android.hardware.radio@1.1",
@@ -39,5 +41,8 @@
     header_libs: [
         "radio.util.header@1.0",
     ],
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
diff --git a/radio/1.2/vts/functional/Android.bp b/radio/1.2/vts/functional/Android.bp
index cb42cc7..1447ade 100644
--- a/radio/1.2/vts/functional/Android.bp
+++ b/radio/1.2/vts/functional/Android.bp
@@ -43,5 +43,8 @@
         "android.hardware.radio.config@1.1",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
diff --git a/radio/1.3/vts/functional/Android.bp b/radio/1.3/vts/functional/Android.bp
index 516e904..d96d391 100644
--- a/radio/1.3/vts/functional/Android.bp
+++ b/radio/1.3/vts/functional/Android.bp
@@ -41,5 +41,8 @@
         "android.hardware.radio@1.0",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal
index 393716b..a830816 100644
--- a/radio/1.4/types.hal
+++ b/radio/1.4/types.hal
@@ -1847,9 +1847,9 @@
     /**
      * SS reference signal received quality, multipled by -1.
      *
-     * Reference: 3GPP TS 38.215.
+     * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10.
      *
-     * Range [3, 20], INT_MAX means invalid/unreported.
+     * Range [-20 dB, 43 dB], INT_MAX means invalid/unreported.
      */
     int32_t ssRsrq;
 
diff --git a/radio/1.4/vts/functional/Android.bp b/radio/1.4/vts/functional/Android.bp
index 681e716..167dec8 100644
--- a/radio/1.4/vts/functional/Android.bp
+++ b/radio/1.4/vts/functional/Android.bp
@@ -44,5 +44,8 @@
         "android.hardware.radio.config@1.1",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests", "vts"]
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
index b061bd5..c1f3f03 100644
--- a/radio/1.5/types.hal
+++ b/radio/1.5/types.hal
@@ -107,9 +107,9 @@
     SSRSRP = 6,
     /**
      * 5G SS reference signal received quality.
-     * Range: -20 dB to -3 dB.
+     * Range: -43 dB to 20 dB.
      * Used RAN: NGRAN
-     * Reference: 3GPP TS 38.215.
+     * Reference: 3GPP TS 38.215, 3GPP TS 38.133 section 10
      */
     SSRSRQ = 7,
     /**
diff --git a/radio/1.5/vts/functional/Android.bp b/radio/1.5/vts/functional/Android.bp
index c04edcf..4549d3c 100644
--- a/radio/1.5/vts/functional/Android.bp
+++ b/radio/1.5/vts/functional/Android.bp
@@ -45,5 +45,8 @@
         "android.hardware.radio.config@1.1",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests", "vts"]
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index c83de29..411a09e 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -103,6 +103,12 @@
      *   - Support simultaneous data call contexts up to DataRegStateResult.maxDataCalls specified
      *     in the response of getDataRegistrationState.
      *
+     * The differences relative to the 1.5 version of the API are:
+     *   - The addition of new parameters pduSessionId, sliceInfo, trafficDescriptor, and
+     *     matchAllRuleAllowed.
+     *   - If an existing data call should be used for the request, that must be indicated in the
+     *     response by setting SetupDataCallResult::cid to the context id of that call.
+     *
      * @param serial Serial number of request.
      * @param accessNetwork The access network to setup the data call. If the data connection cannot
      *     be established on the specified access network then it should be responded with an error.
@@ -122,7 +128,20 @@
      *     Reference: 3GPP TS 24.007 section 11.2.3.1b
      * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from
      *     EPDG to 5G.  It is valid only when accessNetwork is AccessNetwork:NGRAN.  If the slice
-     *     passed from EPDG is rejected, then the data failure cause must be DataCallFailCause:SLICE_REJECTED.
+     *     passed from EPDG is rejected, then the data failure cause must be
+     *     DataCallFailCause:SLICE_REJECTED.
+     * @param trafficDescriptor TrafficDescriptor for which data connection needs to be
+     *     established. It is used for URSP traffic matching as described in TS 24.526
+     *     Section 4.2.2. It includes an optional DNN which, if present, must be used for traffic
+     *     matching -- it does not specify the end point to be used for the data call. The end
+     *     point is specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end
+     *     point if one is not specified through URSP rules.
+     * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this
+     *     request is allowed. If false, this request must not use the match-all URSP rule and if
+     *     a non-match-all rule is not found (or if URSP rules are not available) it should return
+     *     failure with cause DataCallFailCause:MATCH_ALL_RULE_NOT_ALLOWED. This is needed as some
+     *     requests need to have a hard failure if the intention cannot be met, for example, a
+     *     zero-rating slice.
      *
      * Response function is IRadioResponse.setupDataCallResponse_1_6()
      *
@@ -131,7 +150,8 @@
     oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork,
             DataProfileInfo dataProfileInfo, bool roamingAllowed,
             DataRequestReason reason, vec<LinkAddress> addresses, vec<string> dnses,
-            int32_t pduSessionId, OptionalSliceInfo sliceInfo);
+            int32_t pduSessionId, OptionalSliceInfo sliceInfo,
+            OptionalTrafficDescriptor trafficDescriptor, bool matchAllRuleAllowed);
 
     /**
      * Send an SMS message
@@ -496,4 +516,33 @@
      * Response function is IRadioResponse.getCurrentCallsResponse_1_6()
      */
     oneway getCurrentCalls_1_6(int32_t serial);
+
+    /**
+     * Request to get the current slicing configuration including URSP rules and
+     * NSSAIs (configured, allowed and rejected).
+     * URSP stands for UE route selection policy and is defined in 3GPP TS 24.526
+     * Section 4.2.
+     * An NSSAI is a collection of network slices. Each network slice is identified by
+     * an S-NSSAI and is represented by the struct SliceInfo. NSSAI and S-NSSAI
+     * are defined in 3GPP TS 24.501.
+     *
+     * Response function is IRadioResponse.getSlicingConfigResponse()
+     */
+    oneway getSlicingConfig(int32_t serial);
+
+    /**
+     * Provide Carrier specific information to the modem that must be used to
+     * encrypt the IMSI and IMPI. Sent by the framework during boot, carrier
+     * switch and everytime the framework receives a new certificate.
+     *
+     * @param serial Serial number of request.
+     * @param imsiEncryptionInfo ImsiEncryptionInfo as defined in types.hal.
+     *
+     * Response callback is
+     * IRadioResponse.setCarrierInfoForImsiEncryptionResponse()
+     *
+     * Note this API is the same as the 1.1 version except using the 1.6 ImsiEncryptionInfo
+     * as the input param.
+     */
+    oneway setCarrierInfoForImsiEncryption_1_6(int32_t serial, @1.6::ImsiEncryptionInfo imsiEncryptionInfo);
 };
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index a1ad207..a4744e1 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -26,6 +26,7 @@
 import @1.6::RadioResponseInfo;
 import @1.6::SetupDataCallResult;
 import @1.6::SignalStrength;
+import @1.6::SlicingConfig;
 
 /**
  * Interface declaring response functions to solicited radio requests.
@@ -417,4 +418,17 @@
      *   RadioError:CANCELLED
      */
     oneway getCurrentCallsResponse_1_6(RadioResponseInfo info, vec<Call> calls);
+
+    /**
+     * @param info Response info struct containing response type, serial no. and error
+     * @param slicingConfig Current slicing configuration
+     *
+     * Valid errors returned:
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:MODEM_ERR
+     */
+    oneway getSlicingConfigResponse(RadioResponseInfo info,
+            SlicingConfig slicingConfig);
 };
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 875d40a..3e49cfd 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -27,6 +27,7 @@
 import @1.1::GeranBands;
 import @1.1::ScanStatus;
 import @1.1::UtranBands;
+import @1.1::ImsiEncryptionInfo;
 import @1.2::Call;
 import @1.2::CellInfoCdma;
 import @1.2::CellConnectionStatus;
@@ -273,7 +274,8 @@
 /**
  * Overwritten from @1.5::SetupDataCallResult in order to change the suggestedRetryTime
  * to 64-bit value. In the future, this must be extended instead of overwritten.
- * Also added defaultQos, qosSessions, and handoverFailureMode in this version.
+ * Also added defaultQos, qosSessions, handoverFailureMode, pduSessionId, sliceInfo,
+ * and traffic descriptors in this version.
  */
 struct SetupDataCallResult {
     /** Data call fail cause. DataCallFailCause.NONE if no error. */
@@ -365,6 +367,13 @@
      * AccessNetwork:NGRAN.
      */
     OptionalSliceInfo sliceInfo;
+
+    /**
+     * TrafficDescriptors for which this data call must be used. It only includes
+     * the TDs for which a data call has been requested so far; it is not an
+     * exhaustive list.
+     */
+    vec<TrafficDescriptor> trafficDescriptors;
 };
 
 /**
@@ -696,8 +705,10 @@
     RegState regState;
 
     /**
-     * Indicates the available voice radio technology, valid values as
-     * defined by RadioTechnology.
+     * Indicates the available voice radio technology, valid values as defined by RadioTechnology,
+     * except LTE_CA, which is no longer a valid value on 1.5 or above. When the device is on
+     * carrier aggregation, vendor RIL service should properly report multiple PhysicalChannelConfig
+     * elements through IRadio::currentPhysicalChannelConfigs_1_6.
      */
     RadioTechnology rat;
 
@@ -897,4 +908,229 @@
      * Data call fail due to the slice not being allowed for the data call.
      */
     SLICE_REJECTED = 0x8CC,
+
+    /**
+     * No matching rule available for the request, and match-all rule is not allowed for it.
+     */
+    MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD,
+
+    /**
+     * If connection failed for all matching URSP rules.
+     */
+    ALL_MATCHING_RULES_FAILED = 0x8CE,
+};
+
+/**
+ * This safe_union represents an optional DNN. DNN stands for Data Network Name
+ * and represents an APN as defined in 3GPP TS 23.003.
+ */
+safe_union OptionalDnn {
+    Monostate noinit;
+    string value;
+};
+
+/**
+ * This safe_union represents an optional OsAppId.
+ */
+safe_union OptionalOsAppId {
+    Monostate noinit;
+    OsAppId value;
+};
+
+/**
+ * This safe_union represents an optional TrafficDescriptor.
+ */
+safe_union OptionalTrafficDescriptor {
+    Monostate noinit;
+    TrafficDescriptor value;
+};
+
+/**
+ * This struct represents a traffic descriptor. A valid struct must have at least
+ * one of the optional values present. This is based on the definition of traffic
+ * descriptor in TS 24.526 Section 5.2.
+ */
+struct TrafficDescriptor {
+    /**
+     * DNN stands for Data Network Name and represents an APN as defined in
+     * 3GPP TS 23.003.
+     */
+    OptionalDnn dnn;
+    /**
+     * Indicates the OsId + OsAppId (used as category in Android).
+     */
+    OptionalOsAppId osAppId;
+};
+
+/**
+ * This struct represents the OsId + OsAppId as defined in TS 24.526 Section 5.2
+ */
+struct OsAppId {
+    /**
+     * Byte array representing OsId + OsAppId. The minimum length of the array is
+     * 18 and maximum length is 272 (16 bytes for OsId + 1 byte for OsAppId length
+     * + up to 255 bytes for OsAppId).
+     */
+    vec<uint8_t> osAppId;
+};
+
+/**
+ * This struct represents the current slicing configuration.
+ */
+struct SlicingConfig {
+    /**
+     * This vector contains the current URSP rules. Empty vector represents that no
+     * rules are configured.
+     */
+    vec<UrspRule> urspRules;
+    /**
+     * Struct containing all NSSAIs (list of slice info).
+     */
+    Nssais nssais;
+};
+
+/**
+ * This struct represents a single URSP rule as defined in 3GPP TS 24.526.
+ */
+struct UrspRule {
+    /**
+     * Precedence value in the range of 0 to 255. Higher value has lower
+     * precedence.
+     */
+    uint8_t precedence;
+    /**
+     * Used as a matcher for network requests.
+     */
+    vec<TrafficDescriptor> trafficDescriptors;
+    /**
+     * List of routes (connection parameters) that must be used for requests
+     * matching a trafficDescriptor.
+     */
+    vec<RouteSelectionDescriptor> routeSelectionDescriptor;
+};
+
+
+/**
+ * This struct represents a single route selection descriptor as defined in
+ * 3GPP TS 24.526.
+ */
+struct RouteSelectionDescriptor {
+    /**
+     * Precedence value in the range of 0 to 255. Higher value has lower
+     * precedence.
+     */
+    uint8_t precedence;
+    /**
+     * Parameters defining this RouteSelectionDescriptor. The length of the vector
+     * must be >= 1.
+     */
+    vec<RouteSelectionDescriptorParams> routeSelectionDescriptorParams;
+};
+
+/**
+ * This struct represents a route selection descriptor. A valid struct must have
+ * at least one of the vectors non-empty.
+ */
+struct RouteSelectionDescriptorParams {
+    /**
+     * Valid values are IP, IPV6 and IPV4V6.
+     */
+    OptionalPdpProtocolType sessionType;
+    OptionalSscMode sscMode;
+    /**
+     * There can be 0 or more SliceInfo specified in a route descriptor.
+     */
+    vec<SliceInfo> sliceInfo;
+    /**
+     * DNN stands for Data Network Name and represents an APN as defined in
+     * 3GPP TS 23.003. There can be 0 or more DNNs specified in a route
+     * descriptor.
+     */
+    vec<string> dnn;
+};
+
+/**
+ * This safe_union represents an optional PdpProtocolType.
+ */
+safe_union OptionalPdpProtocolType {
+    Monostate noinit;
+    PdpProtocolType value;
+};
+
+/**
+ * This safe_union represents an optional SscMode.
+ */
+safe_union OptionalSscMode {
+    Monostate noinit;
+    SscMode value;
+};
+
+/**
+ * This struct contains all NSSAIs (lists of slices).
+ */
+struct Nssais {
+    /**
+     * These are all the slices configured by the network. This includes allowed
+     * and rejected slices, as well as slices that are neither allowed nor rejected
+     * yet. Empty vector indicates that no slices are configured, and in that case
+     * allowed and rejected vectors must be empty as well.
+     */
+    vec<SliceInfo> configured;
+    /**
+     * These are all the slices that the UE is allowed to use. All these slices
+     * must be configured as well. Empty vector indicates that no slices are
+     * allowed yet.
+     */
+    vec<SliceInfo> allowed;
+    /**
+     * These are all the slices that the UE is not allowed to use. All these slices
+     * must be configured as well. Empty vector indicates that no slices are
+     * rejected yet.
+     */
+    vec<RejectedSliceInfo> rejected;
+    /**
+     * Default configured NSSAI
+     */
+    vec<SliceInfo> defaultConfigured;
+};
+
+/**
+ * This struct represents a network slice rejected by the network. It contains a
+ * rejectionCause corresponding to a rejected network slice.
+ */
+struct RejectedSliceInfo {
+    SliceInfo sliceInfo;
+    SliceRejectionCause rejectionCause;
+};
+
+enum SliceRejectionCause : int32_t {
+    NOT_AVAILABLE_IN_PLMN,
+    NOT_AVAILABLE_IN_REG_AREA,
+};
+
+/**
+ * Enum representing session and service continuity mode as defined in
+ * 3GPP TS 23.501.
+ */
+enum SscMode : int32_t {
+    MODE_1 = 1,
+    MODE_2 = 2,
+    MODE_3 = 3,
+};
+
+/**
+ * Public key type from carrier certificate.
+ */
+enum PublicKeyType : int32_t {
+    EPDG    = 1,                   // Key type to be used for ePDG
+    WLAN    = 2,                   // Key type to be used for WLAN
+};
+
+/**
+ * Carrier specific Information sent by the carrier,
+ * which will be used to encrypt the IMSI and IMPI.
+ */
+struct ImsiEncryptionInfo {
+    @1.1::ImsiEncryptionInfo base;
+    PublicKeyType keyType;         // Public key type
 };
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 44900b8..e82c01a 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -59,9 +59,15 @@
     ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo;
     memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo));
 
+    ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor;
+    memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor));
+
+    bool matchAllRuleAllowed = true;
+
     Return<void> res =
             radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed,
-                                          reason, addresses, dnses, -1, optionalSliceInfo);
+                                          reason, addresses, dnses, -1, optionalSliceInfo,
+                                          optionalTrafficDescriptor, matchAllRuleAllowed);
     ASSERT_OK(res);
 
     EXPECT_EQ(std::cv_status::no_timeout, wait());
@@ -82,6 +88,93 @@
     }
 }
 
+TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6_osAppId) {
+    serial = GetRandomSerialNumber();
+
+    ::android::hardware::radio::V1_5::AccessNetwork accessNetwork =
+            ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN;
+
+    android::hardware::radio::V1_5::DataProfileInfo dataProfileInfo;
+    memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+    dataProfileInfo.profileId = DataProfileId::DEFAULT;
+    dataProfileInfo.apn = hidl_string("internet");
+    dataProfileInfo.protocol = PdpProtocolType::IP;
+    dataProfileInfo.roamingProtocol = PdpProtocolType::IP;
+    dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+    dataProfileInfo.user = hidl_string("username");
+    dataProfileInfo.password = hidl_string("password");
+    dataProfileInfo.type = DataProfileInfoType::THREE_GPP;
+    dataProfileInfo.maxConnsTime = 300;
+    dataProfileInfo.maxConns = 20;
+    dataProfileInfo.waitTime = 0;
+    dataProfileInfo.enabled = true;
+    dataProfileInfo.supportedApnTypesBitmap = 320;
+    dataProfileInfo.bearerBitmap = 161543;
+    dataProfileInfo.mtuV4 = 0;
+    dataProfileInfo.mtuV6 = 0;
+    dataProfileInfo.preferred = true;
+    dataProfileInfo.persistent = false;
+
+    bool roamingAllowed = false;
+
+    std::vector<::android::hardware::radio::V1_5::LinkAddress> addresses = {};
+    std::vector<hidl_string> dnses = {};
+
+    ::android::hardware::radio::V1_2::DataRequestReason reason =
+            ::android::hardware::radio::V1_2::DataRequestReason::NORMAL;
+
+    ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo;
+    memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo));
+
+    ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor;
+    memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor));
+
+    ::android::hardware::radio::V1_6::TrafficDescriptor trafficDescriptor;
+    ::android::hardware::radio::V1_6::OsAppId osAppId;
+    osAppId.osAppId = 1;
+    trafficDescriptor.osAppId.value(osAppId);
+    optionalTrafficDescriptor.value(trafficDescriptor);
+
+    bool matchAllRuleAllowed = true;
+
+    Return<void> res =
+            radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed,
+                                          reason, addresses, dnses, -1, optionalSliceInfo,
+                                          optionalTrafficDescriptor, matchAllRuleAllowed);
+    ASSERT_OK(res);
+
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+    if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_v1_6->rspInfo.error,
+                {::android::hardware::radio::V1_6::RadioError::SIM_ABSENT,
+                 ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+                 ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+    } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_v1_6->rspInfo.error,
+                {::android::hardware::radio::V1_6::RadioError::NONE,
+                 ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE,
+                 ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+        EXPECT_EQ(optionalTrafficDescriptor.value().osAppId.value().osAppId,
+                radioRsp_v1_6->setupDataCallResult.trafficDescriptors[0].osAppId.value().osAppId);
+    }
+}
+
+/*
+ * Test IRadio.getSlicingConfig() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, getSlicingConfig) {
+    serial = GetRandomSerialNumber();
+    radio_v1_6->getSlicingConfig(serial);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+    EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
+}
+
 /*
  * Test IRadio_1_6.sendSms() for the response returned.
  */
@@ -583,3 +676,29 @@
     EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
     EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error);
 }
+
+/*
+ * Test IRadio.setCarrierInfoForImsiEncryption_1_6() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, setCarrierInfoForImsiEncryption_1_6) {
+    serial = GetRandomSerialNumber();
+    ::android::hardware::radio::V1_6::ImsiEncryptionInfo imsiInfo;
+    imsiInfo.base.mcc = "310";
+    imsiInfo.base.mnc = "004";
+    imsiInfo.base.carrierKey = (std::vector<uint8_t>){1, 2, 3, 4, 5, 6};
+    imsiInfo.base.keyIdentifier = "Test";
+    imsiInfo.base.expirationTime = 20180101;
+    imsiInfo.keyType = PublicKeyType::EPDG;
+
+    radio_v1_6->setCarrierInfoForImsiEncryption_1_6(serial, imsiInfo);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+
+    if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+        ASSERT_TRUE(CheckAnyOfErrors(
+                radioRsp_v1_6->rspInfo.error,
+                {::android::hardware::radio::V1_6::RadioError::NONE,
+                 ::android::hardware::radio::V1_6::RadioError::REQUEST_NOT_SUPPORTED}));
+    }
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index b94cd96..f3eaed6 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -89,6 +89,7 @@
 
     // Data
     ::android::hardware::radio::V1_4::DataRegStateResult dataRegResp;
+    ::android::hardware::radio::V1_6::SetupDataCallResult setupDataCallResult;
 
     // SimLock status
     ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp;
@@ -827,6 +828,10 @@
     Return<void> getCurrentCallsResponse_1_6(
             const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
             const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls);
+
+    Return<void> getSlicingConfigResponse(
+            const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+            const ::android::hardware::radio::V1_6::SlicingConfig& slicingConfig);
 };
 
 /* Callback class for radio indication */
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index feb9e03..8c8d698 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -1053,11 +1053,13 @@
 
 Return<void> RadioResponse_v1_6::setupDataCallResponse_1_6(
         const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
-        const android::hardware::radio::V1_6::SetupDataCallResult& /* dcResponse */) {
+        const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse) {
     rspInfo = info;
+    setupDataCallResult = dcResponse;
     parent_v1_6.notify(info.serial);
     return Void();
 }
+
 Return<void> RadioResponse_v1_6::setNrDualConnectivityStateResponse(
         const ::android::hardware::radio::V1_6::RadioResponseInfo& info) {
     rspInfo = info;
@@ -1220,3 +1222,11 @@
     parent_v1_6.notify(info.serial);
     return Void();
 }
+
+Return<void> RadioResponse_v1_6::getSlicingConfigResponse(
+        const ::android::hardware::radio::V1_6::RadioResponseInfo& info,
+        const ::android::hardware::radio::V1_6::SlicingConfig& /*slicingConfig*/) {
+    rspInfo = info;
+    parent_v1_6.notify(info.serial);
+    return Void();
+}
diff --git a/radio/config/1.0/vts/functional/Android.bp b/radio/config/1.0/vts/functional/Android.bp
index ef11d7e..36aecff 100644
--- a/radio/config/1.0/vts/functional/Android.bp
+++ b/radio/config/1.0/vts/functional/Android.bp
@@ -38,5 +38,8 @@
         "android.hardware.radio.config@1.0",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
diff --git a/radio/config/1.1/vts/functional/Android.bp b/radio/config/1.1/vts/functional/Android.bp
index 3635f83..9037b79 100644
--- a/radio/config/1.1/vts/functional/Android.bp
+++ b/radio/config/1.1/vts/functional/Android.bp
@@ -38,5 +38,8 @@
         "android.hardware.radio.config@1.1",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
diff --git a/radio/config/1.2/vts/functional/Android.bp b/radio/config/1.2/vts/functional/Android.bp
index e7cc155..1a15d3f 100644
--- a/radio/config/1.2/vts/functional/Android.bp
+++ b/radio/config/1.2/vts/functional/Android.bp
@@ -40,5 +40,8 @@
         "android.hardware.radio.config@1.2",
     ],
     header_libs: ["radio.util.header@1.0"],
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
 }
diff --git a/radio/config/1.3/types.hal b/radio/config/1.3/types.hal
index ba964bf..8915970 100644
--- a/radio/config/1.3/types.hal
+++ b/radio/config/1.3/types.hal
@@ -21,8 +21,14 @@
  */
 struct HalDeviceCapabilities {
   /**
-   * True indicates that the modem is missing features within the current
-   * version of the Radio HAL.
+   * True indicates that the modem does NOT support the following features:
+   * <ul>
+   * <li>Providing either
+   * android.hardware.radio@1.6::LinkCapacityEstimate:secondaryDownlinkCapacityKbps
+   * or android.hardware.radio@1.6::LinkCapacityEstimate:secondaryUplinkCapacityKbps
+   * when given from android.hardware.radio@1.6::RadioIndication:currentLinkCapacityEstimate
+   * </li>
+   * </ul>
    */
   bool modemReducedFeatureSet1;
 };
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
deleted file mode 100644
index 34f2749..0000000
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ByteArray.aidl
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *////////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-//     the interface (from the latest frozen version), the build system will
-//     prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.hardware.security.keymint;
-@VintfStability
-parcelable ByteArray {
-  byte[] data;
-}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
index 3faba48..2eb6e35 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/ErrorCode.aidl
@@ -115,6 +115,7 @@
   MISSING_NOT_AFTER = -81,
   MISSING_ISSUER_SUBJECT = -82,
   INVALID_ISSUER_SUBJECT = -83,
+  BOOT_LEVEL_EXCEEDED = -84,
   UNIMPLEMENTED = -100,
   VERSION_MISMATCH = -101,
   UNKNOWN_ERROR = -1000,
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
index bd304f1..30fe6dc 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/HardwareAuthToken.aidl
@@ -36,7 +36,7 @@
   long challenge;
   long userId;
   long authenticatorId;
-  android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType;
+  android.hardware.security.keymint.HardwareAuthenticatorType authenticatorType = android.hardware.security.keymint.HardwareAuthenticatorType.NONE;
   android.hardware.security.secureclock.Timestamp timestamp;
   byte[] mac;
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
index d3c6910..7150c44 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -45,5 +45,6 @@
   android.hardware.security.keymint.BeginResult begin(in android.hardware.security.keymint.KeyPurpose purpose, in byte[] keyBlob, in android.hardware.security.keymint.KeyParameter[] params, in android.hardware.security.keymint.HardwareAuthToken authToken);
   void deviceLocked(in boolean passwordOnly, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken);
   void earlyBootEnded();
+  byte[] performOperation(in byte[] request);
   const int AUTH_TOKEN_MAC_LENGTH = 32;
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
index a9b9a05..80ed526 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -33,7 +33,8 @@
 package android.hardware.security.keymint;
 @VintfStability
 interface IKeyMintOperation {
-  int update(in @nullable android.hardware.security.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken inAuthToken, in @nullable android.hardware.security.secureclock.TimeStampToken inTimeStampToken, out @nullable android.hardware.security.keymint.KeyParameterArray outParams, out @nullable android.hardware.security.keymint.ByteArray output);
-  byte[] finish(in @nullable android.hardware.security.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable byte[] inSignature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken inTimeStampToken, out @nullable android.hardware.security.keymint.KeyParameterArray outParams);
+  void updateAad(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken);
+  byte[] update(in byte[] input, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timeStampToken);
+  byte[] finish(in @nullable byte[] input, in @nullable byte[] signature, in @nullable android.hardware.security.keymint.HardwareAuthToken authToken, in @nullable android.hardware.security.secureclock.TimeStampToken timestampToken, in @nullable byte[] confirmationToken);
   void abort();
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
index b430da9..994bd4c 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyCharacteristics.aidl
@@ -33,6 +33,6 @@
 package android.hardware.security.keymint;
 @VintfStability
 parcelable KeyCharacteristics {
-  android.hardware.security.keymint.SecurityLevel securityLevel;
+  android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE;
   android.hardware.security.keymint.KeyParameter[] authorizations;
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index d06312a..7747c59 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -34,7 +34,7 @@
 @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
 parcelable KeyMintHardwareInfo {
   int versionNumber;
-  android.hardware.security.keymint.SecurityLevel securityLevel;
+  android.hardware.security.keymint.SecurityLevel securityLevel = android.hardware.security.keymint.SecurityLevel.SOFTWARE;
   @utf8InCpp String keyMintName;
   @utf8InCpp String keyMintAuthorName;
   boolean timestampTokenRequired;
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
index f534952..21b083c 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl
@@ -33,6 +33,6 @@
 package android.hardware.security.keymint;
 @RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability
 parcelable KeyParameter {
-  android.hardware.security.keymint.Tag tag;
+  android.hardware.security.keymint.Tag tag = android.hardware.security.keymint.Tag.INVALID;
   android.hardware.security.keymint.KeyParameterValue value;
 }
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
index 03982e3..2469d27 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/Tag.aidl
@@ -98,4 +98,5 @@
   CERTIFICATE_SUBJECT = -1879047185,
   CERTIFICATE_NOT_BEFORE = 1610613744,
   CERTIFICATE_NOT_AFTER = 1610613745,
+  MAX_BOOT_LEVEL = 805307378,
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ByteArray.aidl b/security/keymint/aidl/android/hardware/security/keymint/ByteArray.aidl
deleted file mode 100644
index c3b402e..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/ByteArray.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.keymint;
-
-/**
- * This is used to contain a byte[], to make out parameters of byte arrays
- * more convenient for callers.
- */
-@VintfStability
-parcelable ByteArray {
-    byte[] data;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl b/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
index 5765130..95b38f2 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/ErrorCode.aidl
@@ -105,6 +105,7 @@
     MISSING_NOT_AFTER = -81,
     MISSING_ISSUER_SUBJECT = -82,
     INVALID_ISSUER_SUBJECT = -83,
+    BOOT_LEVEL_EXCEEDED = -84,
 
     UNIMPLEMENTED = -100,
     VERSION_MISMATCH = -101,
diff --git a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
index 417a0b1..57150d5 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/HardwareAuthToken.aidl
@@ -16,17 +16,17 @@
 
 package android.hardware.security.keymint;
 
-import android.hardware.security.secureclock.Timestamp;
 import android.hardware.security.keymint.HardwareAuthenticatorType;
+import android.hardware.security.secureclock.Timestamp;
 
 /**
  * HardwareAuthToken is used to prove successful user authentication, to unlock the use of a key.
  *
  * HardwareAuthTokens are produced by other secure environment applications, notably GateKeeper and
- * biometric authenticators, in response to successful user authentication events.  These tokens are passed to
- * begin(), update(), and finish() to prove that authentication occurred.  See those methods for
- * more details.  It is up to the caller to determine which of the generated auth tokens is
- * appropriate for a given key operation.
+ * biometric authenticators, in response to successful user authentication events.  These tokens are
+ * passed to begin(), update(), and finish() to prove that authentication occurred.  See those
+ * methods for more details.  It is up to the caller to determine which of the generated auth tokens
+ * is appropriate for a given key operation.
  */
 @VintfStability
 @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
@@ -55,7 +55,7 @@
      * authenticatorType describes the type of authentication that took place, e.g. password or
      * fingerprint.
      */
-    HardwareAuthenticatorType authenticatorType;
+    HardwareAuthenticatorType authenticatorType = HardwareAuthenticatorType.NONE;
 
     /**
      * timestamp indicates when the user authentication took place, in milliseconds since some
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 13e98af..384416e 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -18,7 +18,6 @@
 
 import android.hardware.security.keymint.AttestationKey;
 import android.hardware.security.keymint.BeginResult;
-import android.hardware.security.keymint.ByteArray;
 import android.hardware.security.keymint.HardwareAuthToken;
 import android.hardware.security.keymint.IKeyMintOperation;
 import android.hardware.security.keymint.KeyCreationResult;
@@ -761,4 +760,18 @@
      * an EARLY_BOOT_ONLY key after this method is called must fail with Error::INVALID_KEY_BLOB.
      */
     void earlyBootEnded();
+
+    /**
+     * Called by the client to perform a KeyMint operation.
+     *
+     *  This method is added primarily as a placeholder.  Details will be fleshed before the KeyMint
+     *  V1 interface is frozen.  Until then, implementations must return ErrorCode::UNIMPLEMENTED.
+     *
+     * @param request is an encrypted buffer containing a description of the operation the client
+     *        wishes to perform.  Structure, content and encryption are TBD.
+     *
+     * @return an encrypted buffer containing the result of the operation.  Structure, content and
+     *         encryption are TBD.
+     */
+    byte[] performOperation(in byte[] request);
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
index 8c49602..1c2511b 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintOperation.aidl
@@ -16,15 +16,75 @@
 
 package android.hardware.security.keymint;
 
-import android.hardware.security.keymint.ByteArray;
 import android.hardware.security.keymint.HardwareAuthToken;
 import android.hardware.security.keymint.KeyParameter;
-import android.hardware.security.keymint.KeyParameterArray;
 import android.hardware.security.secureclock.TimeStampToken;
 
 @VintfStability
 interface IKeyMintOperation {
     /**
+     * Provides additional authentication data (AAD) to a cryptographic operation begun with
+     * begin(), provided in the input argument.  This method only applies to AEAD modes.  This
+     * method may be called multiple times, supplying the AAD in chunks, but may not be called after
+     * update() is called.  If updateAad() is called after update(), it must return
+     * ErrorCode::INVALID_TAG.
+     *
+     * If operation is in an invalid state (was aborted or had an error) update() must return
+     * ErrorCode::INVALID_OPERATION_HANDLE.
+     *
+     * If this method returns an error code other than ErrorCode::OK, the operation is aborted and
+     * the operation handle must be invalidated.  Any future use of the handle, with this method,
+     * finish, or abort, must return ErrorCode::INVALID_OPERATION_HANDLE.
+     *
+     * == Authorization Enforcement ==
+     *
+     * Key authorization enforcement is performed primarily in begin().  The one exception is the
+     * case where the key has:
+     *
+     * o One or more Tag::USER_SECURE_IDs, and
+     *
+     * o Does not have a Tag::AUTH_TIMEOUT
+     *
+     * In this case, the key requires an authorization per operation, and the update method must
+     * receive a non-null and valid HardwareAuthToken.  For the auth token to be valid, all of the
+     * following has to be true:
+     *
+     *   o The HMAC field must validate correctly.
+     *
+     *   o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
+     *     the secure ID values in the token.
+     *
+     *   o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
+     *
+     *   o The challenge field in the auth token must contain the operationHandle
+     *
+     *   If any of these conditions are not met, update() must return
+     *   ErrorCode::KEY_USER_NOT_AUTHENTICATED.
+     *
+     * The caller must provide the auth token on every call to updateAad(), update() and finish().
+     *
+     *
+     * For GCM encryption, the AEAD tag must be appended to the ciphertext by finish().  During
+     * decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
+     * be the AEAD tag.  Since a given invocation of update cannot know if it's the last invocation,
+     * it must process all but the tag length and buffer the possible tag data for processing during
+     * finish().
+     *
+     * @param input Additional Authentication Data to be processed.
+     *
+     * @param authToken Authentication token. Can be nullable if not provided.
+     *
+     * @param timeStampToken timestamp token, certifies the freshness of an auth token in case
+     *        the security domain of this KeyMint instance has a different clock than the
+     *        authenticator issuing the auth token.
+     *
+     * @return error Returns ErrorCode encountered in keymint as service specific errors. See the
+     *         ErrorCode enum in ErrorCode.aidl.
+     */
+    void updateAad(in byte[] input, in @nullable HardwareAuthToken authToken,
+            in @nullable TimeStampToken timeStampToken);
+
+    /**
      * Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
      * with begin().
      *
@@ -96,53 +156,28 @@
      *
      * -- AES keys --
      *
-     * AES GCM mode supports "associated authentication data," provided via the Tag::ASSOCIATED_DATA
-     * tag in the inParams argument.  The associated data may be provided in repeated calls
-     * (important if the data is too large to send in a single block) but must always precede data
-     * to be encrypted or decrypted.  An update call may receive both associated data and data to
-     * encrypt/decrypt, but subsequent updates must not include associated data.  If the caller
-     * provides associated data to an update call after a call that includes data to
-     * encrypt/decrypt, update() must return ErrorCode::INVALID_TAG.
-     *
      * For GCM encryption, the AEAD tag must be appended to the ciphertext by finish().  During
      * decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
      * be the AEAD tag.  Since a given invocation of update cannot know if it's the last invocation,
      * it must process all but the tag length and buffer the possible tag data for processing during
      * finish().
      *
-     * TODO: update() needs to be refactored b/168665179.
-     *
-     * @param inParams Additional parameters for the operation.  For AEAD modes, this is used to
-     *        specify Tag::ADDITIONAL_DATA.  Note that additional data may be provided in multiple
-     *        calls to update(), but only until input data has been provided.
-     *
      * @param input Data to be processed.  Note that update() may or may not consume all of the data
      *        provided.  See return value.
      *
-     * @param inTimeStampToken timestamp token, certifies the freshness of an auth token in case
-     *        the security domain of this KeyMint instance has a different clock than the
-     *        authenticator issuing the auth token.
+     * @param authToken Authentication token. Can be nullable if not provided.
+     *
+     * @param timeStampToken certifies the freshness of an auth token in case the security domain of
+     *        this KeyMint instance has a different clock than the authenticator issuing the auth
+     *        token.
      *
      * @return error Returns ErrorCode encountered in keymint as service specific errors. See the
      *         ErrorCode enum in ErrorCode.aidl.
      *
-     * @return int Amount of data that was consumed by update().  If this is less than the
-     *         amount provided, the caller may provide the remainder in a subsequent call to
-     *         update() or finish().  Every call to update must consume at least one byte, unless
-     *         the input is empty, and implementations should consume as much data as reasonably
-     *         possible for each call.
-     *
-     * @return outParams returns the updated key parameters from the blob, if needed.
-     * operation.
-     *
-     * @return out variable output The output data, if any.
+     * @return byte[] The output data, if any.
      */
-    int update(in @nullable KeyParameterArray inParams,
-               in @nullable byte[] input,
-               in @nullable HardwareAuthToken inAuthToken,
-               in @nullable TimeStampToken inTimeStampToken,
-               out @nullable KeyParameterArray outParams,
-               out @nullable ByteArray output);
+    byte[] update(in byte[] input, in @nullable HardwareAuthToken authToken,
+            in @nullable TimeStampToken timeStampToken);
 
     /**
      * Finalizes a cryptographic operation begun with begin() and invalidates operation.
@@ -229,8 +264,7 @@
      *
      * TODO: update() will need to be refactored into 2 function. b/168665179.
      *
-     * @param inParams Additional parameters for the operation.  For AEAD modes, this is used to
-     *        specify Tag::ADDITIONAL_DATA, but only if no input data was provided to update().
+     * @param inParams Additional parameters for the operation.
      *
      * @param input Data to be processed, per the parameters established in the call to begin().
      *        finish() must consume all provided data or return ErrorCode::INVALID_INPUT_LENGTH.
@@ -240,19 +274,21 @@
      *
      * @param authToken Authentication token. Can be nullable if not provided.
      *
-     * @param inTimeStampToken timestamp token, certifies the freshness of an auth token in case
-     *        the security domain of this KeyMint instance has a different clock than the
-     *        authenticator issuing the auth token.
+     * @param timestampToken certifies the freshness of an auth token in case the security domain of
+     *        this KeyMint instance has a different clock than the authenticator issuing the auth
+     *        token.
      *
-     * @return outParams Any output parameters generated by finish().
+     * @param confirmationToken is the confirmation token required by keys with
+     * Tag::TRUSTED_CONFIRMATION_REQUIRED.
      *
      * @return The output data, if any.
+     *
+     * @return outParams Any output parameters generated by finish().
      */
-    byte[] finish(in @nullable KeyParameterArray inParams, in @nullable byte[] input,
-                in @nullable byte[] inSignature,
-                in @nullable HardwareAuthToken authToken,
-                in @nullable TimeStampToken inTimeStampToken,
-                out @nullable KeyParameterArray outParams);
+    byte[] finish(in @nullable byte[] input, in @nullable byte[] signature,
+            in @nullable HardwareAuthToken authToken,
+            in @nullable TimeStampToken timestampToken,
+            in @nullable byte[] confirmationToken);
 
     /**
      * Aborts a cryptographic operation begun with begin(), freeing all internal resources. If an
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
index edd4d8f..3a32e4d 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyCharacteristics.aidl
@@ -31,6 +31,6 @@
  */
 @VintfStability
 parcelable KeyCharacteristics {
-    SecurityLevel securityLevel;
+    SecurityLevel securityLevel = SecurityLevel.SOFTWARE;
     KeyParameter[] authorizations;
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
index 2fcaf4c..ae0d152 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyMintHardwareInfo.aidl
@@ -34,7 +34,7 @@
 
     /* securityLevel is the security level of the IKeyMintDevice implementation accessed
      * through this aidl package.  */
-    SecurityLevel securityLevel;
+    SecurityLevel securityLevel = SecurityLevel.SOFTWARE;
 
     /* keyMintName is the name of the IKeyMintDevice implementation.  */
     @utf8InCpp String keyMintName;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl
index f3ed96b..bf6c9b2 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl
@@ -16,8 +16,8 @@
 
 package android.hardware.security.keymint;
 
-import android.hardware.security.keymint.Tag;
 import android.hardware.security.keymint.KeyParameterValue;
+import android.hardware.security.keymint.Tag;
 
 /**
  * Identifies the key authorization parameters to be used with keyMint.  This is usually
@@ -26,6 +26,6 @@
 @VintfStability
 @RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true)
 parcelable KeyParameter {
-    Tag tag;
+    Tag tag = Tag.INVALID;
     KeyParameterValue value;
 }
diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterArray.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterArray.aidl
deleted file mode 100644
index acab435..0000000
--- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterArray.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.security.keymint;
-
-import android.hardware.security.keymint.KeyParameter;
-
-/**
- * Identifies the key authorization parameters to be used with keyMint.  This is usually
- * provided as an array of KeyParameters to IKeyMintDevice or Operation.
- */
-@VintfStability
-parcelable KeyParameterArray {
-    /**
-     * Identify list of key parameters corresponding to a particular key blob.
-     */
-    KeyParameter[] params;
-}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
index c63859c..ecbde8c 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/SecurityLevel.aidl
@@ -44,13 +44,15 @@
 
     /**
      * The TRUSTED_ENVIRONMENT security level represents a KeyMint implementation that runs in an
-     * Android process, or a tag enforced by such an implementation.  An attacker who completely
-     * compromises Android, including the Linux kernel, does not have the ability to subvert it.  At
-     * attacker who can find an exploit that gains them control of the trusted environment, or who
-     * has access to the physical device and can mount a sophisticated hardware attack, may be able
-     * to defeat it.
+     * isolated execution environment that is securely isolated from the code running on the kernel
+     * and above, and which satisfies the requirements specified in CDD 9.11.1 [C-1-2]. An attacker
+     * who completely compromises Android, including the Linux kernel, does not have the ability to
+     * subvert it.  An attacker who can find an exploit that gains them control of the trusted
+     * environment, or who has access to the physical device and can mount a sophisticated hardware
+     * attack, may be able to defeat it.
      */
     TRUSTED_ENVIRONMENT = 1,
+
     /**
      * The STRONGBOX security level represents a KeyMint implementation that runs in security
      * hardware that satisfies the requirements specified in CDD 9.11.2.  Roughly speaking, these
diff --git a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
index 4f58cbe..aa9aa6f 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/Tag.aidl
@@ -883,11 +883,7 @@
     STORAGE_KEY = (7 << 28) /* TagType:BOOL */ | 722,
 
     /**
-     * Tag::ASSOCIATED_DATA Provides "associated data" for AES-GCM encryption or decryption.  This
-     * tag is provided to update and specifies data that is not encrypted/decrypted, but is used in
-     * computing the GCM tag.
-     *
-     * Must never appear KeyCharacteristics.
+     * TODO: Delete when keystore1 is deleted.
      */
     ASSOCIATED_DATA = (9 << 28) /* TagType:BYTES */ | 1000,
 
@@ -964,4 +960,15 @@
      * or importKey.
      */
     CERTIFICATE_NOT_AFTER = (6 << 28) /* TagType:DATE */ | 1009,
+
+    /**
+     * Tag::MAX_BOOT_LEVEL specifies a maximum boot level at which a key should function.
+     *
+     * Over the course of the init process, the boot level will be raised to
+     * monotonically increasing integer values. Implementations MUST NOT allow the key
+     * to be used once the boot level advances beyond the value of this tag.
+     *
+     * Cannot be hardware enforced in this version.
+     */
+    MAX_BOOT_LEVEL = (3 << 28) /* TagType:UINT */ | 1010,
 }
diff --git a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
index f2651fb..2373b26 100644
--- a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
+++ b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
@@ -259,8 +259,9 @@
 }
 
 static keymaster_key_param_t kKeyMintEcdsaP256Params[] = {
-        Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC),
-        Authorization(TAG_KEY_SIZE, 256), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
+        Authorization(TAG_PURPOSE, KM_PURPOSE_ATTEST_KEY),
+        Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC), Authorization(TAG_KEY_SIZE, 256),
+        Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
         Authorization(TAG_EC_CURVE, KM_EC_CURVE_P_256), Authorization(TAG_NO_AUTH_REQUIRED),
         // The certificate generated by KM will be discarded, these values don't matter.
         Authorization(TAG_CERTIFICATE_NOT_BEFORE, 0), Authorization(TAG_CERTIFICATE_NOT_AFTER, 0)};
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index d61a081..3e87b6b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -386,122 +386,50 @@
     return result;
 }
 
-ErrorCode KeyMintAidlTestBase::Update(const AuthorizationSet& in_params, const string& input,
-                                      AuthorizationSet* out_params, string* output,
-                                      int32_t* input_consumed) {
+ErrorCode KeyMintAidlTestBase::UpdateAad(const string& input) {
+    return GetReturnErrorCode(op_->updateAad(vector<uint8_t>(input.begin(), input.end()),
+                                             {} /* hardwareAuthToken */,
+                                             {} /* verificationToken */));
+}
+
+ErrorCode KeyMintAidlTestBase::Update(const string& input, string* output) {
     SCOPED_TRACE("Update");
 
     Status result;
-    EXPECT_NE(op_, nullptr);
-    if (!op_) {
-        return ErrorCode::UNEXPECTED_NULL_POINTER;
-    }
+    if (!output) return ErrorCode::UNEXPECTED_NULL_POINTER;
 
-    KeyParameterArray key_params;
-    key_params.params = in_params.vector_data();
+    std::vector<uint8_t> o_put;
+    result = op_->update(vector<uint8_t>(input.begin(), input.end()), {}, {}, &o_put);
 
-    KeyParameterArray in_keyParams;
-    in_keyParams.params = in_params.vector_data();
-
-    optional<KeyParameterArray> out_keyParams;
-    optional<ByteArray> o_put;
-    result = op_->update(in_keyParams, vector<uint8_t>(input.begin(), input.end()), {}, {},
-                         &out_keyParams, &o_put, input_consumed);
-
-    if (result.isOk()) {
-        if (o_put) {
-            output->append(o_put->data.begin(), o_put->data.end());
-        }
-
-        if (out_keyParams) {
-            out_params->push_back(AuthorizationSet(out_keyParams->params));
-        }
-    }
+    if (result.isOk()) output->append(o_put.begin(), o_put.end());
 
     return GetReturnErrorCode(result);
 }
 
-ErrorCode KeyMintAidlTestBase::Update(const string& input, string* out, int32_t* input_consumed) {
-    SCOPED_TRACE("Update");
-    AuthorizationSet out_params;
-    ErrorCode result =
-            Update(AuthorizationSet() /* in_params */, input, &out_params, out, input_consumed);
-    EXPECT_TRUE(out_params.empty());
-    return result;
-}
-
-ErrorCode KeyMintAidlTestBase::Finish(const AuthorizationSet& in_params, const string& input,
-                                      const string& signature, AuthorizationSet* out_params,
+ErrorCode KeyMintAidlTestBase::Finish(const string& input, const string& signature,
                                       string* output) {
     SCOPED_TRACE("Finish");
     Status result;
 
     EXPECT_NE(op_, nullptr);
-    if (!op_) {
-        return ErrorCode::UNEXPECTED_NULL_POINTER;
-    }
-
-    KeyParameterArray key_params;
-    key_params.params = in_params.vector_data();
-
-    KeyParameterArray in_keyParams;
-    in_keyParams.params = in_params.vector_data();
-
-    optional<KeyParameterArray> out_keyParams;
-    optional<vector<uint8_t>> o_put;
+    if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
 
     vector<uint8_t> oPut;
-    result = op_->finish(in_keyParams, vector<uint8_t>(input.begin(), input.end()),
-                         vector<uint8_t>(signature.begin(), signature.end()), {}, {},
-                         &out_keyParams, &oPut);
+    result = op_->finish(vector<uint8_t>(input.begin(), input.end()),
+                         vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
+                         {} /* timestampToken */, {} /* confirmationToken */, &oPut);
 
-    if (result.isOk()) {
-        if (out_keyParams) {
-            out_params->push_back(AuthorizationSet(out_keyParams->params));
-        }
+    if (result.isOk()) output->append(oPut.begin(), oPut.end());
 
-        output->append(oPut.begin(), oPut.end());
-    }
-
-    op_.reset();
+    op_ = {};
     return GetReturnErrorCode(result);
 }
 
-ErrorCode KeyMintAidlTestBase::Finish(const string& message, string* output) {
-    SCOPED_TRACE("Finish");
-    AuthorizationSet out_params;
-    string finish_output;
-    ErrorCode result = Finish(AuthorizationSet() /* in_params */, message, "" /* signature */,
-                              &out_params, output);
-    if (result != ErrorCode::OK) {
-        return result;
-    }
-    EXPECT_EQ(0U, out_params.size());
-    return result;
-}
-
-ErrorCode KeyMintAidlTestBase::Finish(const string& message, const string& signature,
-                                      string* output) {
-    SCOPED_TRACE("Finish");
-    AuthorizationSet out_params;
-    ErrorCode result =
-            Finish(AuthorizationSet() /* in_params */, message, signature, &out_params, output);
-
-    if (result != ErrorCode::OK) {
-        return result;
-    }
-
-    EXPECT_EQ(0U, out_params.size());
-    return result;
-}
-
 ErrorCode KeyMintAidlTestBase::Abort(const std::shared_ptr<IKeyMintOperation>& op) {
     SCOPED_TRACE("Abort");
 
     EXPECT_NE(op, nullptr);
-    if (!op) {
-        return ErrorCode::UNEXPECTED_NULL_POINTER;
-    }
+    if (!op) return ErrorCode::UNEXPECTED_NULL_POINTER;
 
     Status retval = op->abort();
     EXPECT_TRUE(retval.isOk());
@@ -512,9 +440,7 @@
     SCOPED_TRACE("Abort");
 
     EXPECT_NE(op_, nullptr);
-    if (!op_) {
-        return ErrorCode::UNEXPECTED_NULL_POINTER;
-    }
+    if (!op_) return ErrorCode::UNEXPECTED_NULL_POINTER;
 
     Status retval = op_->abort();
     return static_cast<ErrorCode>(retval.getServiceSpecificError());
@@ -530,30 +456,13 @@
 
 auto KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
                                          const string& message, const AuthorizationSet& in_params)
-        -> std::tuple<ErrorCode, string, AuthorizationSet /* out_params */> {
+        -> std::tuple<ErrorCode, string> {
     AuthorizationSet begin_out_params;
     ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
-    AuthorizationSet out_params(std::move(begin_out_params));
-    if (result != ErrorCode::OK) {
-        return {result, {}, out_params};
-    }
+    if (result != ErrorCode::OK) return {result, {}};
 
     string output;
-    int32_t consumed = 0;
-    AuthorizationSet update_params;
-    AuthorizationSet update_out_params;
-    result = Update(update_params, message, &update_out_params, &output, &consumed);
-    out_params.push_back(update_out_params);
-    if (result != ErrorCode::OK) {
-        return {result, output, out_params};
-    }
-
-    string unused;
-    AuthorizationSet finish_params;
-    AuthorizationSet finish_out_params;
-    result = Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output);
-    out_params.push_back(finish_out_params);
-    return {result, output, out_params};
+    return {Finish(message, &output), output};
 }
 
 string KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
@@ -561,30 +470,14 @@
                                            AuthorizationSet* out_params) {
     SCOPED_TRACE("ProcessMessage");
     AuthorizationSet begin_out_params;
-    ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
+    ErrorCode result = Begin(operation, key_blob, in_params, out_params);
     EXPECT_EQ(ErrorCode::OK, result);
     if (result != ErrorCode::OK) {
         return "";
     }
 
     string output;
-    int32_t consumed = 0;
-    AuthorizationSet update_params;
-    AuthorizationSet update_out_params;
-    result = Update(update_params, message, &update_out_params, &output, &consumed);
-    EXPECT_EQ(ErrorCode::OK, result);
-    if (result != ErrorCode::OK) {
-        return "";
-    }
-
-    string unused;
-    AuthorizationSet finish_params;
-    AuthorizationSet finish_out_params;
-    EXPECT_EQ(ErrorCode::OK,
-              Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output));
-
-    out_params->push_back(begin_out_params);
-    out_params->push_back(finish_out_params);
+    EXPECT_EQ(ErrorCode::OK, Finish(message, &output));
     return output;
 }
 
@@ -674,21 +567,9 @@
     ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::VERIFY, key_blob, params, &begin_out_params));
 
     string output;
-    AuthorizationSet update_params;
-    AuthorizationSet update_out_params;
-    int32_t consumed;
-    ASSERT_EQ(ErrorCode::OK,
-              Update(update_params, message, &update_out_params, &output, &consumed));
+    EXPECT_EQ(ErrorCode::OK, Finish(message, signature, &output));
     EXPECT_TRUE(output.empty());
-    EXPECT_GT(consumed, 0U);
-
-    string unused;
-    AuthorizationSet finish_params;
-    AuthorizationSet finish_out_params;
-    EXPECT_EQ(ErrorCode::OK, Finish(finish_params, message.substr(consumed), signature,
-                                    &finish_out_params, &output));
-    op_.reset();
-    EXPECT_TRUE(output.empty());
+    op_ = {};
 }
 
 void KeyMintAidlTestBase::VerifyMessage(const string& message, const string& signature,
@@ -955,14 +836,14 @@
 }
 
 ErrorCode KeyMintAidlTestBase::UseAesKey(const vector<uint8_t>& aesKeyBlob) {
-    auto [result, ciphertext, out_params] = ProcessMessage(
+    auto [result, ciphertext] = ProcessMessage(
             aesKeyBlob, KeyPurpose::ENCRYPT, "1234567890123456",
             AuthorizationSetBuilder().BlockMode(BlockMode::ECB).Padding(PaddingMode::NONE));
     return result;
 }
 
 ErrorCode KeyMintAidlTestBase::UseHmacKey(const vector<uint8_t>& hmacKeyBlob) {
-    auto [result, mac, out_params] = ProcessMessage(
+    auto [result, mac] = ProcessMessage(
             hmacKeyBlob, KeyPurpose::SIGN, "1234567890123456",
             AuthorizationSetBuilder().Authorization(TAG_MAC_LENGTH, 128).Digest(Digest::SHA_2_256));
     return result;
@@ -970,16 +851,15 @@
 
 ErrorCode KeyMintAidlTestBase::UseRsaKey(const vector<uint8_t>& rsaKeyBlob) {
     std::string message(2048 / 8, 'a');
-    auto [result, signature, out_params] = ProcessMessage(
+    auto [result, signature] = ProcessMessage(
             rsaKeyBlob, KeyPurpose::SIGN, message,
             AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE));
     return result;
 }
 
 ErrorCode KeyMintAidlTestBase::UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob) {
-    auto [result, signature, out_params] =
-            ProcessMessage(ecdsaKeyBlob, KeyPurpose::SIGN, "a",
-                           AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
+    auto [result, signature] = ProcessMessage(ecdsaKeyBlob, KeyPurpose::SIGN, "a",
+                                              AuthorizationSetBuilder().Digest(Digest::SHA_2_256));
     return result;
 }
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index 452d2b6..0aef81b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -112,15 +112,14 @@
                     AuthorizationSet* out_params);
     ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params);
 
-    ErrorCode Update(const AuthorizationSet& in_params, const string& input,
-                     AuthorizationSet* out_params, string* output, int32_t* input_consumed);
-    ErrorCode Update(const string& input, string* out, int32_t* input_consumed);
+    ErrorCode UpdateAad(const string& input);
+    ErrorCode Update(const string& input, string* output);
 
-    ErrorCode Finish(const AuthorizationSet& in_params, const string& input,
-                     const string& signature, AuthorizationSet* out_params, string* output);
-    ErrorCode Finish(const string& message, string* output);
     ErrorCode Finish(const string& message, const string& signature, string* output);
-    ErrorCode Finish(string* output) { return Finish(string(), output); }
+    ErrorCode Finish(const string& message, string* output) {
+        return Finish(message, {} /* signature */, output);
+    }
+    ErrorCode Finish(string* output) { return Finish({} /* message */, output); }
 
     ErrorCode Abort();
     ErrorCode Abort(const shared_ptr<IKeyMintOperation>& op);
@@ -129,9 +128,9 @@
     string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
                           const string& message, const AuthorizationSet& in_params,
                           AuthorizationSet* out_params);
-    std::tuple<ErrorCode, std::string /* processedMessage */, AuthorizationSet /* out_params */>
-    ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
-                   const std::string& message, const AuthorizationSet& in_params);
+    std::tuple<ErrorCode, std::string /* processedMessage */> ProcessMessage(
+            const vector<uint8_t>& key_blob, KeyPurpose operation, const std::string& message,
+            const AuthorizationSet& in_params);
     string SignMessage(const vector<uint8_t>& key_blob, const string& message,
                        const AuthorizationSet& params);
     string SignMessage(const string& message, const AuthorizationSet& params);
@@ -262,7 +261,7 @@
     ErrorCode UseRsaKey(const vector<uint8_t>& rsaKeyBlob);
     ErrorCode UseEcdsaKey(const vector<uint8_t>& ecdsaKeyBlob);
 
-  private:
+  protected:
     std::shared_ptr<IKeyMintDevice> keymint_;
     uint32_t os_version_;
     uint32_t os_patch_level_;
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 71aae90..7ecfa37 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -2751,39 +2751,22 @@
     for (int increment = 1; increment <= 240; ++increment) {
         for (auto block_mode : block_modes) {
             string message(240, 'a');
-            auto params = AuthorizationSetBuilder()
-                                  .BlockMode(block_mode)
-                                  .Padding(PaddingMode::NONE)
-                                  .Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;
+            auto params =
+                    AuthorizationSetBuilder().BlockMode(block_mode).Padding(PaddingMode::NONE);
+            if (block_mode == BlockMode::GCM) {
+                params.Authorization(TAG_MAC_LENGTH, 128) /* for GCM */;
+            }
 
             AuthorizationSet output_params;
             EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &output_params));
 
             string ciphertext;
-            int32_t input_consumed;
             string to_send;
             for (size_t i = 0; i < message.size(); i += increment) {
-                to_send.append(message.substr(i, increment));
-                EXPECT_EQ(ErrorCode::OK, Update(to_send, &ciphertext, &input_consumed));
-                EXPECT_EQ(to_send.length(), input_consumed);
-                to_send = to_send.substr(input_consumed);
-                EXPECT_EQ(0U, to_send.length());
-
-                switch (block_mode) {
-                    case BlockMode::ECB:
-                    case BlockMode::CBC:
-                        // Implementations must take as many blocks as possible, leaving less
-                        // than a block.
-                        EXPECT_LE(to_send.length(), 16U);
-                        break;
-                    case BlockMode::GCM:
-                    case BlockMode::CTR:
-                        // Implementations must always take all the data.
-                        EXPECT_EQ(0U, to_send.length());
-                        break;
-                }
+                EXPECT_EQ(ErrorCode::OK, Update(message.substr(i, increment), &ciphertext));
             }
-            EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext)) << "Error sending " << to_send;
+            EXPECT_EQ(ErrorCode::OK, Finish(to_send, &ciphertext))
+                    << "Error sending " << to_send << " with block mode " << block_mode;
 
             switch (block_mode) {
                 case BlockMode::GCM:
@@ -2818,9 +2801,7 @@
 
             string plaintext;
             for (size_t i = 0; i < ciphertext.size(); i += increment) {
-                to_send.append(ciphertext.substr(i, increment));
-                EXPECT_EQ(ErrorCode::OK, Update(to_send, &plaintext, &input_consumed));
-                to_send = to_send.substr(input_consumed);
+                EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
             }
             ErrorCode error = Finish(to_send, &plaintext);
             ASSERT_EQ(ErrorCode::OK, error) << "Decryption failed for block mode " << block_mode
@@ -3077,17 +3058,13 @@
                                 .Padding(PaddingMode::NONE)
                                 .Authorization(TAG_MAC_LENGTH, 128);
 
-    auto update_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
     // Encrypt
     AuthorizationSet begin_out_params;
     ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params))
             << "Begin encrypt";
     string ciphertext;
-    AuthorizationSet update_out_params;
-    ASSERT_EQ(ErrorCode::OK, Finish(update_params, message, "", &update_out_params, &ciphertext));
-
+    ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
+    ASSERT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
     ASSERT_EQ(ciphertext.length(), message.length() + 16);
 
     // Grab nonce
@@ -3095,12 +3072,9 @@
 
     // Decrypt.
     ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt";
+    ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
     string plaintext;
-    int32_t input_consumed;
-    ASSERT_EQ(ErrorCode::OK,
-              Update(update_params, ciphertext, &update_out_params, &plaintext, &input_consumed));
-    EXPECT_EQ(ciphertext.size(), input_consumed);
-    EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext));
+    EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
     EXPECT_EQ(message.length(), plaintext.length());
     EXPECT_EQ(message, plaintext);
 }
@@ -3127,17 +3101,15 @@
                                 .Padding(PaddingMode::NONE)
                                 .Authorization(TAG_MAC_LENGTH, 128);
 
-    auto update_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
     // Encrypt
     AuthorizationSet begin_out_params;
     ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params))
             << "Begin encrypt";
     string ciphertext;
     AuthorizationSet update_out_params;
+    ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
     sleep(5);
-    ASSERT_EQ(ErrorCode::OK, Finish(update_params, message, "", &update_out_params, &ciphertext));
+    ASSERT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
 
     ASSERT_EQ(ciphertext.length(), message.length() + 16);
 
@@ -3147,11 +3119,9 @@
     // Decrypt.
     ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params)) << "Begin decrypt";
     string plaintext;
-    int32_t input_consumed;
+    ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
     sleep(5);
-    ASSERT_EQ(ErrorCode::OK,
-              Update(update_params, ciphertext, &update_out_params, &plaintext, &input_consumed));
-    EXPECT_EQ(ciphertext.size(), input_consumed);
+    ASSERT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
     sleep(5);
     EXPECT_EQ(ErrorCode::OK, Finish("", &plaintext));
     EXPECT_EQ(message.length(), plaintext.length());
@@ -3230,9 +3200,6 @@
                           .Padding(PaddingMode::NONE)
                           .Authorization(TAG_MAC_LENGTH, 128);
 
-    auto finish_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
     // Encrypt
     AuthorizationSet begin_out_params;
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
@@ -3241,8 +3208,8 @@
 
     AuthorizationSet finish_out_params;
     string ciphertext;
-    EXPECT_EQ(ErrorCode::OK,
-              Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
+    ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
+    EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
 
     params = AuthorizationSetBuilder()
                      .Authorizations(begin_out_params)
@@ -3326,16 +3293,13 @@
                           .Padding(PaddingMode::NONE)
                           .Authorization(TAG_MAC_LENGTH, 128);
 
-    auto finish_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
     // Encrypt
     AuthorizationSet begin_out_params;
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
     string ciphertext;
     AuthorizationSet finish_out_params;
-    EXPECT_EQ(ErrorCode::OK, Finish(finish_params, "" /* input */, "" /* signature */,
-                                    &finish_out_params, &ciphertext));
+    ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
+    EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
     EXPECT_TRUE(finish_out_params.empty());
 
     // Grab nonce
@@ -3343,9 +3307,9 @@
 
     // Decrypt.
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+    ASSERT_EQ(ErrorCode::OK, UpdateAad(aad));
     string plaintext;
-    EXPECT_EQ(ErrorCode::OK, Finish(finish_params, ciphertext, "" /* signature */,
-                                    &finish_out_params, &plaintext));
+    EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
 
     EXPECT_TRUE(finish_out_params.empty());
 
@@ -3374,43 +3338,26 @@
                                 .Authorization(TAG_MAC_LENGTH, tag_bits);
     AuthorizationSet begin_out_params;
 
-    auto update_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foo", (size_t)3);
-
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
 
     // No data, AAD only.
+    EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
+    EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
     string ciphertext;
-    int32_t input_consumed;
-    AuthorizationSet update_out_params;
-    EXPECT_EQ(ErrorCode::OK, Update(update_params, "" /* input */, &update_out_params, &ciphertext,
-                                    &input_consumed));
-    EXPECT_EQ(0U, input_consumed);
-    EXPECT_EQ(0U, ciphertext.size());
-    EXPECT_TRUE(update_out_params.empty());
+    EXPECT_EQ(ErrorCode::OK, Update(message, &ciphertext));
+    EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
 
-    // AAD and data.
-    EXPECT_EQ(ErrorCode::OK,
-              Update(update_params, message, &update_out_params, &ciphertext, &input_consumed));
-    EXPECT_EQ(message.size(), input_consumed);
-    EXPECT_TRUE(update_out_params.empty());
-
-    EXPECT_EQ(ErrorCode::OK, Finish("" /* input */, &ciphertext));
     // Expect 128-bit (16-byte) tag appended to ciphertext.
-    EXPECT_EQ(message.size() + (tag_bits >> 3), ciphertext.size());
+    EXPECT_EQ(message.size() + (tag_bits / 8), ciphertext.size());
 
     // Grab nonce.
     begin_params.push_back(begin_out_params);
 
     // Decrypt
-    update_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foofoo", (size_t)6);
-
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
+    EXPECT_EQ(ErrorCode::OK, UpdateAad("foofoo"));
     string plaintext;
-    EXPECT_EQ(ErrorCode::OK, Finish(update_params, ciphertext, "" /* signature */,
-                                    &update_out_params, &plaintext));
-    EXPECT_TRUE(update_out_params.empty());
+    EXPECT_EQ(ErrorCode::OK, Finish(ciphertext, &plaintext));
     EXPECT_EQ(message, plaintext);
 }
 
@@ -3434,32 +3381,14 @@
                                 .Authorization(TAG_MAC_LENGTH, 128);
     AuthorizationSet begin_out_params;
 
-    auto update_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foo", (size_t)3);
-
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
 
-    // No data, AAD only.
+    EXPECT_EQ(ErrorCode::OK, UpdateAad("foo"));
     string ciphertext;
-    int32_t input_consumed;
-    AuthorizationSet update_out_params;
-    EXPECT_EQ(ErrorCode::OK, Update(update_params, "" /* input */, &update_out_params, &ciphertext,
-                                    &input_consumed));
-    EXPECT_EQ(0U, input_consumed);
-    EXPECT_EQ(0U, ciphertext.size());
-    EXPECT_TRUE(update_out_params.empty());
+    EXPECT_EQ(ErrorCode::OK, Update(message, &ciphertext));
+    EXPECT_EQ(ErrorCode::INVALID_TAG, UpdateAad("foo"));
 
-    // AAD and data.
-    EXPECT_EQ(ErrorCode::OK,
-              Update(update_params, message, &update_out_params, &ciphertext, &input_consumed));
-    EXPECT_EQ(message.size(), input_consumed);
-    EXPECT_TRUE(update_out_params.empty());
-
-    // More AAD
-    EXPECT_EQ(ErrorCode::INVALID_TAG,
-              Update(update_params, "", &update_out_params, &ciphertext, &input_consumed));
-
-    op_.reset();
+    op_ = {};
 }
 
 /*
@@ -3481,28 +3410,21 @@
                                 .Padding(PaddingMode::NONE)
                                 .Authorization(TAG_MAC_LENGTH, 128);
 
-    auto finish_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foobar", (size_t)6);
-
     // Encrypt
     AuthorizationSet begin_out_params;
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string ciphertext;
-    AuthorizationSet finish_out_params;
-    EXPECT_EQ(ErrorCode::OK,
-              Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
+    EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
 
     // Grab nonce
     begin_params.push_back(begin_out_params);
 
-    finish_params = AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA,
-                                                            "barfoo" /* Wrong AAD */, (size_t)6);
-
     // Decrypt.
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
+    EXPECT_EQ(ErrorCode::OK, UpdateAad("barfoo"));
     string plaintext;
-    EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
-                                                     &finish_out_params, &plaintext));
+    EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
 }
 
 /*
@@ -3524,25 +3446,22 @@
                                 .Padding(PaddingMode::NONE)
                                 .Authorization(TAG_MAC_LENGTH, 128);
 
-    auto finish_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, "foobar", (size_t)6);
-
     // Encrypt
     AuthorizationSet begin_out_params;
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, begin_params, &begin_out_params));
+    EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string ciphertext;
     AuthorizationSet finish_out_params;
-    EXPECT_EQ(ErrorCode::OK,
-              Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
+    EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
 
     // Wrong nonce
     begin_params.push_back(TAG_NONCE, AidlBuf("123456789012"));
 
     // Decrypt.
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params, &begin_out_params));
+    EXPECT_EQ(ErrorCode::OK, UpdateAad("foobar"));
     string plaintext;
-    EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
-                                                     &finish_out_params, &plaintext));
+    EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
 
     // With wrong nonce, should have gotten garbage plaintext (or none).
     EXPECT_NE(message, plaintext);
@@ -3569,17 +3488,12 @@
                           .Padding(PaddingMode::NONE)
                           .Authorization(TAG_MAC_LENGTH, 128);
 
-    auto finish_params =
-            AuthorizationSetBuilder().Authorization(TAG_ASSOCIATED_DATA, aad.data(), aad.size());
-
     // Encrypt
     AuthorizationSet begin_out_params;
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, params, &begin_out_params));
+    EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
     string ciphertext;
-    AuthorizationSet finish_out_params;
-    EXPECT_EQ(ErrorCode::OK,
-              Finish(finish_params, message, "" /* signature */, &finish_out_params, &ciphertext));
-    EXPECT_TRUE(finish_out_params.empty());
+    EXPECT_EQ(ErrorCode::OK, Finish(message, &ciphertext));
 
     // Corrupt tag
     ++(*ciphertext.rbegin());
@@ -3589,10 +3503,9 @@
 
     // Decrypt.
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, params));
+    EXPECT_EQ(ErrorCode::OK, UpdateAad(aad));
     string plaintext;
-    EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(finish_params, ciphertext, "" /* signature */,
-                                                     &finish_out_params, &plaintext));
-    EXPECT_TRUE(finish_out_params.empty());
+    EXPECT_EQ(ErrorCode::VERIFICATION_FAILED, Finish(ciphertext, &plaintext));
 }
 
 /*
@@ -3704,9 +3617,7 @@
     begin_params.push_back(TAG_PADDING, PaddingMode::PKCS7);
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
     string plaintext;
-    int32_t input_consumed;
-    EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
-    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
     EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
 }
 
@@ -4020,9 +3931,7 @@
                                 .Authorization(TAG_NONCE, iv);
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, begin_params));
     string plaintext;
-    int32_t input_consumed;
-    EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext, &input_consumed));
-    EXPECT_EQ(ciphertext.size(), input_consumed);
+    EXPECT_EQ(ErrorCode::OK, Update(ciphertext, &plaintext));
     EXPECT_EQ(ErrorCode::INVALID_ARGUMENT, Finish(&plaintext));
 }
 
@@ -4046,10 +3955,8 @@
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::ENCRYPT, input_params, &output_params));
 
     string ciphertext;
-    int32_t input_consumed;
     for (size_t i = 0; i < message.size(); i += increment)
-        EXPECT_EQ(ErrorCode::OK,
-                  Update(message.substr(i, increment), &ciphertext, &input_consumed));
+        EXPECT_EQ(ErrorCode::OK, Update(message.substr(i, increment), &ciphertext));
     EXPECT_EQ(ErrorCode::OK, Finish(&ciphertext));
     EXPECT_EQ(message.size(), ciphertext.size());
 
@@ -4062,8 +3969,7 @@
     EXPECT_EQ(ErrorCode::OK, Begin(KeyPurpose::DECRYPT, input_params, &output_params));
     string plaintext;
     for (size_t i = 0; i < ciphertext.size(); i += increment)
-        EXPECT_EQ(ErrorCode::OK,
-                  Update(ciphertext.substr(i, increment), &plaintext, &input_consumed));
+        EXPECT_EQ(ErrorCode::OK, Update(ciphertext.substr(i, increment), &plaintext));
     EXPECT_EQ(ErrorCode::OK, Finish(&plaintext));
     EXPECT_EQ(ciphertext.size(), plaintext.size());
     EXPECT_EQ(message, plaintext);
@@ -4727,7 +4633,7 @@
 
 INSTANTIATE_KEYMINT_AIDL_TEST(KeyAgreementTest);
 
-typedef KeyMintAidlTestBase EarlyBootKeyTest;
+using EarlyBootKeyTest = KeyMintAidlTestBase;
 
 TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) {
     auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
@@ -4784,9 +4690,10 @@
     CheckedDeleteKey(&rsaKeyData.blob);
     CheckedDeleteKey(&ecdsaKeyData.blob);
 }
+
 INSTANTIATE_KEYMINT_AIDL_TEST(EarlyBootKeyTest);
 
-typedef KeyMintAidlTestBase UnlockedDeviceRequiredTest;
+using UnlockedDeviceRequiredTest = KeyMintAidlTestBase;
 
 // This may be a problematic test.  It can't be run repeatedly without unlocking the device in
 // between runs... and on most test devices there are no enrolled credentials so it can't be
@@ -4818,8 +4725,19 @@
     CheckedDeleteKey(&rsaKeyData.blob);
     CheckedDeleteKey(&ecdsaKeyData.blob);
 }
+
 INSTANTIATE_KEYMINT_AIDL_TEST(UnlockedDeviceRequiredTest);
 
+using PerformOperationTest = KeyMintAidlTestBase;
+
+TEST_P(PerformOperationTest, RequireUnimplemented) {
+    vector<uint8_t> response;
+    auto result = keymint_->performOperation({} /* request */, &response);
+    ASSERT_EQ(GetReturnErrorCode(result), ErrorCode::UNIMPLEMENTED);
+}
+
+INSTANTIATE_KEYMINT_AIDL_TEST(PerformOperationTest);
+
 }  // namespace aidl::android::hardware::security::keymint::test
 
 int main(int argc, char** argv) {
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 45f9df6..db53a8f 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -80,7 +80,7 @@
 /**
  * Generate and validate a production-mode key.  MAC tag can't be verified.
  */
-TEST_P(GenerateKeyTests, DISABLED_generateEcdsaP256Key_prodMode) {
+TEST_P(GenerateKeyTests, generateEcdsaP256Key_prodMode) {
     MacedPublicKey macedPubKey;
     bytevec privateKeyBlob;
     bool testMode = false;
@@ -133,7 +133,7 @@
 /**
  * Generate and validate a test-mode key.
  */
-TEST_P(GenerateKeyTests, DISABLED_generateEcdsaP256Key_testMode) {
+TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) {
     MacedPublicKey macedPubKey;
     bytevec privateKeyBlob;
     bool testMode = true;
@@ -224,7 +224,7 @@
  * Generate an empty certificate request in test mode, and decrypt and verify the structure and
  * content.
  */
-TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_testMode) {
+TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
     bool testMode = true;
     bytevec keysToSignMac;
     ProtectedData protectedData;
@@ -294,7 +294,7 @@
  * TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be
  * able to decrypt.
  */
-TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
+TEST_P(CertificateRequestTest, EmptyRequest_prodMode) {
     bool testMode = false;
     bytevec keysToSignMac;
     ProtectedData protectedData;
@@ -309,7 +309,7 @@
 /**
  * Generate a non-empty certificate request in test mode.  Decrypt, parse and validate the contents.
  */
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_testMode) {
+TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
     bool testMode = true;
     generateKeys(testMode, 4 /* numKeys */);
 
@@ -379,7 +379,7 @@
  * TODO(swillden): Get a valid GEEK and use it so the generation can succeed, though we won't be
  * able to decrypt.
  */
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
+TEST_P(CertificateRequestTest, NonEmptyRequest_prodMode) {
     bool testMode = false;
     generateKeys(testMode, 4 /* numKeys */);
 
@@ -396,7 +396,7 @@
  * Generate a non-empty certificate request in test mode, with prod keys.  Must fail with
  * STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
  */
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodKeyInTestCert) {
+TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) {
     generateKeys(false /* testMode */, 2 /* numKeys */);
 
     bytevec keysToSignMac;
@@ -414,7 +414,7 @@
  * Generate a non-empty certificate request in prod mode, with test keys.  Must fail with
  * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
  */
-TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_testKeyInProdCert) {
+TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) {
     generateKeys(true /* testMode */, 2 /* numKeys */);
 
     bytevec keysToSignMac;
diff --git a/security/keymint/aidl/vts/performance/Android.bp b/security/keymint/aidl/vts/performance/Android.bp
index 03240c3..79ed0d5 100644
--- a/security/keymint/aidl/vts/performance/Android.bp
+++ b/security/keymint/aidl/vts/performance/Android.bp
@@ -14,6 +14,15 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
 cc_benchmark {
     name: "VtsAidlKeyMintBenchmarkTest",
     defaults: [
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index f87ca78..6c795f5 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -206,41 +206,15 @@
         return std::move(builder);
     }
 
-    optional<string> Process(const string& message, const AuthorizationSet& /*in_params*/,
-                             AuthorizationSet* out_params, const string& signature = "") {
-        static const int HIDL_BUFFER_LIMIT = 1 << 14;  // 16KB
+    optional<string> Process(const string& message, const string& signature = "") {
         ErrorCode result;
 
-        // Update
-        AuthorizationSet update_params;
-        AuthorizationSet update_out_params;
         string output;
-        string aidl_output;
-        int32_t input_consumed = 0;
-        int32_t aidl_input_consumed = 0;
-        while (message.length() - input_consumed > 0) {
-            result = Update(update_params, message.substr(input_consumed, HIDL_BUFFER_LIMIT),
-                            &update_out_params, &aidl_output, &aidl_input_consumed);
-            if (result != ErrorCode::OK) {
-                error_ = result;
-                return {};
-            }
-            output.append(aidl_output);
-            input_consumed += aidl_input_consumed;
-            aidl_output.clear();
-        }
-
-        // Finish
-        AuthorizationSet finish_params;
-        AuthorizationSet finish_out_params;
-        result = Finish(finish_params, message.substr(input_consumed), signature,
-                        &finish_out_params, &aidl_output);
+        result = Finish(message, signature, &output);
         if (result != ErrorCode::OK) {
             error_ = result;
             return {};
         }
-        output.append(aidl_output);
-        out_params->push_back(finish_out_params);
         return output;
     }
 
@@ -296,66 +270,36 @@
         name_.assign(info.keyMintName.begin(), info.keyMintName.end());
     }
 
-    ErrorCode Finish(const AuthorizationSet& in_params, const string& input,
-                     const string& signature, AuthorizationSet* out_params, string* output) {
-        Status result;
+    ErrorCode Finish(const string& input, const string& signature, string* output) {
         if (!op_) {
             std::cerr << "Finish: Operation is nullptr" << std::endl;
             return ErrorCode::UNEXPECTED_NULL_POINTER;
         }
-        KeyParameterArray key_params;
-        key_params.params = in_params.vector_data();
-
-        KeyParameterArray in_keyParams;
-        in_keyParams.params = in_params.vector_data();
-
-        std::optional<KeyParameterArray> out_keyParams;
-        std::optional<vector<uint8_t>> o_put;
 
         vector<uint8_t> oPut;
-        result = op_->finish(in_keyParams, vector<uint8_t>(input.begin(), input.end()),
-                             vector<uint8_t>(signature.begin(), signature.end()), {}, {},
-                             &out_keyParams, &oPut);
+        Status result =
+                op_->finish(vector<uint8_t>(input.begin(), input.end()),
+                            vector<uint8_t>(signature.begin(), signature.end()), {} /* authToken */,
+                            {} /* timestampToken */, {} /* confirmationToken */, &oPut);
 
-        if (result.isOk()) {
-            if (out_keyParams) {
-                out_params->push_back(AuthorizationSet(out_keyParams->params));
-            }
-            output->append(oPut.begin(), oPut.end());
-        }
+        if (result.isOk()) output->append(oPut.begin(), oPut.end());
+
         op_.reset();
         return GetReturnErrorCode(result);
     }
 
-    ErrorCode Update(const AuthorizationSet& in_params, const string& input,
-                     AuthorizationSet* out_params, string* output, int32_t* input_consumed) {
+    ErrorCode Update(const string& input, string* output) {
         Status result;
         if (!op_) {
             std::cerr << "Update: Operation is nullptr" << std::endl;
             return ErrorCode::UNEXPECTED_NULL_POINTER;
         }
 
-        KeyParameterArray key_params;
-        key_params.params = in_params.vector_data();
+        std::vector<uint8_t> o_put;
+        result = op_->update(vector<uint8_t>(input.begin(), input.end()), {} /* authToken */,
+                             {} /* timestampToken */, &o_put);
 
-        KeyParameterArray in_keyParams;
-        in_keyParams.params = in_params.vector_data();
-
-        std::optional<KeyParameterArray> out_keyParams;
-        std::optional<ByteArray> o_put;
-        result = op_->update(in_keyParams, vector<uint8_t>(input.begin(), input.end()), {}, {},
-                             &out_keyParams, &o_put, input_consumed);
-
-        if (result.isOk()) {
-            if (o_put) {
-                output->append(o_put->data.begin(), o_put->data.end());
-            }
-
-            if (out_keyParams) {
-                out_params->push_back(AuthorizationSet(out_keyParams->params));
-            }
-        }
-
+        if (result.isOk() && output) *output = {o_put.begin(), o_put.end()};
         return GetReturnErrorCode(result);
     }
 
@@ -493,7 +437,7 @@
         }
         state.ResumeTiming();
         out_params.Clear();
-        if (!keymintTest->Process(message, in_params, &out_params)) {
+        if (!keymintTest->Process(message)) {
             state.SkipWithError(("Sign error, " + std::to_string(keymintTest->getError())).c_str());
             break;
         }
@@ -516,7 +460,7 @@
                 ("Error beginning sign, " + std::to_string(keymintTest->getError())).c_str());
         return;
     }
-    std::optional<string> signature = keymintTest->Process(message, in_params, &out_params);
+    std::optional<string> signature = keymintTest->Process(message);
     if (!signature) {
         state.SkipWithError(("Sign error, " + std::to_string(keymintTest->getError())).c_str());
         return;
@@ -534,7 +478,7 @@
             return;
         }
         state.ResumeTiming();
-        if (!keymintTest->Process(message, in_params, &out_params, *signature)) {
+        if (!keymintTest->Process(message, *signature)) {
             state.SkipWithError(
                     ("Verify error, " + std::to_string(keymintTest->getError())).c_str());
             break;
@@ -612,7 +556,7 @@
         }
         out_params.Clear();
         state.ResumeTiming();
-        if (!keymintTest->Process(message, in_params, &out_params)) {
+        if (!keymintTest->Process(message)) {
             state.SkipWithError(
                     ("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
             break;
@@ -636,7 +580,7 @@
                 ("Encryption begin error, " + std::to_string(keymintTest->getError())).c_str());
         return;
     }
-    auto encryptedMessage = keymintTest->Process(message, in_params, &out_params);
+    auto encryptedMessage = keymintTest->Process(message);
     if (!encryptedMessage) {
         state.SkipWithError(
                 ("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
@@ -653,7 +597,7 @@
             return;
         }
         state.ResumeTiming();
-        if (!keymintTest->Process(*encryptedMessage, in_params, &out_params)) {
+        if (!keymintTest->Process(*encryptedMessage)) {
             state.SkipWithError(
                     ("Decryption error, " + std::to_string(keymintTest->getError())).c_str());
             break;
diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h
index 479a11d..ae21125 100644
--- a/security/keymint/support/include/keymint_support/keymint_tags.h
+++ b/security/keymint/support/include/keymint_support/keymint_tags.h
@@ -130,6 +130,7 @@
 DECLARE_TYPED_TAG(CERTIFICATE_SUBJECT);
 DECLARE_TYPED_TAG(CERTIFICATE_NOT_BEFORE);
 DECLARE_TYPED_TAG(CERTIFICATE_NOT_AFTER);
+DECLARE_TYPED_TAG(MAX_BOOT_LEVEL);
 
 #undef DECLARE_TYPED_TAG