Merge "wifi: change H2E mode API arguemnt to tri-state enumeration" into sc-dev
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 af2ae9c..926a791 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -128,6 +128,7 @@
     defaults: ["VtsHalAudioTargetTest_defaults"],
     srcs: [
         "6.0/AudioPrimaryHidlHalTest.cpp",
+        "6.0/Generators.cpp",
     ],
     static_libs: [
         "libaudiofoundation",
@@ -154,6 +155,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"],
@@ -174,3 +176,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/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index e3fd16d..7ff79fe 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -3037,7 +3037,7 @@
     /**
      * Starts the ClusterUI in cluster display.
      *
-     * int32[0]: the type of ClusterUI to show
+     * int32: the type of ClusterUI to show
      *    0 indicates ClusterHome, that is a home screen of cluster display, and provides
      *        the default UI and a kind of launcher functionality for cluster display.
      *    the other values are followed by OEM's definition.
@@ -3057,12 +3057,12 @@
      * int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
      * int32[1]: width: positive number - actual width in pixels
                         -1 - don't care (should set "don't care" both width and height)
-     * int32[2]: height: ditto with width
+     * int32[2]: height: same format with 'width'
      * int32[3]: Inset - left: positive number - actual left inset value in pixels
                                -1 - don't care (should set "don't care" all Inset fields)
-     * int32[4]: Inset - top
-     * int32[5]: Inset - right
-     * int32[6]: Inset - bottom
+     * int32[4]: Inset - top:    same format with 'left'
+     * int32[5]: Inset - right:  same format with 'left'
+     * int32[6]: Inset - bottom: same format with 'left'
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:READ
@@ -3097,9 +3097,9 @@
      *    -1 indicates the area isn't used any more.
      * bytes: the array to represent the availability of ClusterUI.
      *     0 indicates non-available and 1 indicates available.
-     *     For example, let's assume a car supports 3 UI like HOME, MAPS, CALL and it only supports
-     *     CALL UI only when the cellular network is available. Then, if the nework is avaibale,
-     *     it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
+     *     For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL,
+     *     and it only supports CALL UI only when the cellular network is available. Then, if the
+     *     nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:WRITE
@@ -3117,7 +3117,7 @@
      * request to turn the display on to show some specific ClusterUI.
      * ClusterOS should response this with CLUSTER_DISPLAY_STATE.
      *
-     * int32[0]: the type of ClusterUI to show
+     * int32: the type of ClusterUI to show
      *
      * @change_mode VehiclePropertyChangeMode:ON_CHANGE
      * @access VehiclePropertyAccess:WRITE
diff --git a/biometrics/common/aidl/OWNERS b/biometrics/common/aidl/OWNERS
new file mode 100644
index 0000000..36d7261
--- /dev/null
+++ b/biometrics/common/aidl/OWNERS
@@ -0,0 +1,2 @@
+ilyamaty@google.com
+kchyn@google.com
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
index 30959b1..4b4e7df 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/CommonProps.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -37,4 +38,5 @@
   android.hardware.biometrics.common.SensorStrength sensorStrength = android.hardware.biometrics.common.SensorStrength.CONVENIENCE;
   int maxEnrollmentsPerUser;
   android.hardware.biometrics.common.HardwareInfo[] hardwareInfo;
+  String softwareInfo;
 }
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl
index 8fea864..c5288fd 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/HardwareInfo.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -35,6 +36,5 @@
 parcelable HardwareInfo {
   String deviceName;
   String hardwareVersion;
-  String firmwareVersion;
   String serialNumber;
 }
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
index b85a590..2bc6a6d 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/ICancellationSignal.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
index 3b20c9a..6675d09 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/SensorStrength.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
index 59f398e..7c3d511 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/CommonProps.aidl
@@ -44,4 +44,13 @@
      * A list of hardware information for subsystems that pertain to this biometric sensor.
      */
     HardwareInfo[] hardwareInfo;
+
+    /**
+     * Software information for subsystems that pertain to this biometric sensor.
+     * This may include information for the matching algorithm, the PAD (Presentation Attack
+     * Detection) algorithm, and any other algorithm(s) used by this biometric sensor.
+     * For example, <algorithm_1_info>;<algorithm_2_info>;<algorithm_3_info>.
+     * The format of each algorithm's info can be <vendor>/<algorithm>/<version>.
+     */
+    String softwareInfo;
 }
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl
index 23f0202..ce9e354 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/HardwareInfo.aidl
@@ -29,12 +29,7 @@
     String hardwareVersion;
 
     /**
-     * The firmware version.
-     */
-    String firmwareVersion;
-
-    /**
      * The sensor's serial number.
      */
     String serialNumber;
-}
\ No newline at end of file
+}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
index 8fd6c5f..c19534c 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -58,7 +59,5 @@
   VENDOR = 22,
   FIRST_FRAME_RECEIVED = 23,
   DARK_GLASSES_DETECTED = 24,
-  FACE_COVERING_DETECTED = 25,
-  EYES_NOT_VISIBLE = 26,
-  MOUTH_NOT_VISIBLE = 27,
+  MOUTH_COVERING_DETECTED = 25,
 }
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
index a9e4de3..20bc767 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AuthenticationFrame.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
index 9939705..aa51343 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/BaseFrame.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
index cc2bf53..6be8c8e 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Cell.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
index cb9a6c6..982e759 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentFrame.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
index fefac68..6be6e0b 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStage.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
index f55aafd..232bd52 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentStageConfig.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
index 3603c4e..8e99ad6 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/EnrollmentType.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
index 7992f99..0437f07 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Error.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
index 481b678..a215b99 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -33,6 +34,7 @@
 package android.hardware.biometrics.face;
 @Backing(type="byte") @VintfStability
 enum FaceSensorType {
-  RGB = 0,
-  IR = 1,
+  UNKNOWN = 0,
+  RGB = 1,
+  IR = 2,
 }
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
index d9e561d..a8faf06 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/Feature.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
index bfaf90d..0d1ef45 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
index c9165e1..205429b 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -33,7 +34,7 @@
 package android.hardware.biometrics.face;
 @VintfStability
 interface ISession {
-  void generateChallenge(in int cookie, in int timeoutSec);
+  void generateChallenge(in int cookie);
   void revokeChallenge(in int cookie, in long challenge);
   android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface);
   android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId);
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
index 6127c7b..d6ebbb6 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISessionCallback.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
index 69355fb..c55a600 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SensorProps.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl
index 3792eae..4db47c9 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/SessionState.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
index 217a9bb..a3b229e 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -187,7 +187,7 @@
      */
     ROLL_TOO_EXTREME = 18,
 
-   /**
+    /**
      * The user’s face has been obscured by some object.
      *
      * The user should be informed to remove any objects from the line of sight from
@@ -230,18 +230,5 @@
      * A face mask or face covering detected. This can be useful for providing relevant feedback to
      * the user and enabling an alternative authentication logic if the implementation supports it.
      */
-    FACE_COVERING_DETECTED = 25,
-
-    /**
-     * Either one or both eyes are not visible in the frame. Prefer to use DARK_GLASSES_DETECTED if
-     * the eyes are not visible due to dark glasses.
-     */
-    EYES_NOT_VISIBLE = 26,
-
-    /**
-     * The mouth is not visible in the frame. Prefer to use MASK_DETECTED if the mouth is not
-     * visible due to a mask.
-     */
-    MOUTH_NOT_VISIBLE = 27,
+    MOUTH_COVERING_DETECTED = 25,
 }
-
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
index 2a5dd20..57f39d4 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/FaceSensorType.aidl
@@ -16,9 +16,4 @@
 
 package android.hardware.biometrics.face;
 
-@VintfStability
-@Backing(type="byte")
-enum FaceSensorType {
-    RGB,
-    IR
-}
+@VintfStability @Backing(type="byte") enum FaceSensorType { UNKNOWN, RGB, IR }
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index 6f2014a..66c7c38 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -45,7 +45,7 @@
      *      to allow addition of biometric enrollments.
      * To secure this path, the following path is taken:
      *   1) Upon user requesting face enroll, the framework requests
-     *      IFace#generateChallenge
+     *      ISession#generateChallenge
      *   2) Framework sends the challenge to the credential subsystem, and upon credential
      *      confirmation, a HAT is created, containing the challenge in the "challenge" field.
      *   3) Framework sends the HAT to the HAL, e.g. ISession#enroll.
@@ -53,11 +53,10 @@
      *   5) Implementation now has confidence that the user entered their credential to allow
      *      biometric enrollment.
      *
-     * Note that the interface allows multiple in-flight challenges. For example, invoking
-     * generateChallenge(0, 0, timeoutSec) twice does not invalidate the first challenge. The
-     * challenge is invalidated only when:
-     *   1) The provided timeout expires, or
-     *   2) IFace#revokeChallenge is invoked
+     * Note that this interface allows multiple in-flight challenges. Invoking generateChallenge
+     * twice does not invalidate the first challenge. The challenge is invalidated only when:
+     *   1) Its lifespan exceeds the HAL's internal challenge timeout
+     *   2) IFingerprint#revokeChallenge is invoked
      *
      * For example, the following is a possible table of valid challenges:
      * ----------------------------------------------
@@ -70,9 +69,8 @@
      * ----------------------------------------------
      *
      * @param cookie A unique number identifying this operation
-     * @param timeoutSec Duration for which the challenge is valid for
      */
-    void generateChallenge(in int cookie, in int timeoutSec);
+    void generateChallenge(in int cookie);
 
     /**
      * revokeChallenge:
@@ -113,7 +111,7 @@
      *
      * Before capturing face data, the implementation must first verify the authenticity and
      * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge
-     * within the provided HardwareAuthToken is valid. See IFace#generateChallenge. If any of
+     * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of
      * the above checks fail, the framework must be notified via ISessionCallback#onError and the
      * HAL must notify the framework when it returns to the idle state. See
      * Error::UNABLE_TO_PROCESS.
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
index 2b40850..73e50f3 100644
--- a/biometrics/face/aidl/default/Face.cpp
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -26,14 +26,13 @@
 const bool kHalControlsPreview = true;
 const std::string kHwDeviceName = "faceSensor";
 const std::string kHardwareVersion = "vendor/model/revision";
-const std::string kFirmwareVersion = "1.01";
 const std::string kSerialNumber = "00000001";
+const std::string kSoftwareVersion = "vendor1/algorithm1/version;vendor2/algorithm2/version";
 
 ndk::ScopedAStatus Face::getSensorProps(std::vector<SensorProps>* return_val) {
     common::HardwareInfo hardware_info;
     hardware_info.deviceName = kHwDeviceName;
     hardware_info.hardwareVersion = kHardwareVersion;
-    hardware_info.firmwareVersion = kFirmwareVersion;
     hardware_info.serialNumber = kSerialNumber;
 
     common::CommonProps commonProps;
@@ -41,6 +40,7 @@
     commonProps.sensorStrength = kSensorStrength;
     commonProps.maxEnrollmentsPerUser = kMaxEnrollmentsPerUser;
     commonProps.hardwareInfo = {std::move(hardware_info)};
+    commonProps.softwareInfo = kSoftwareVersion;
 
     SensorProps props;
     props.commonProps = std::move(commonProps);
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index a7130e6..ce6c557 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -37,7 +37,7 @@
 
 Session::Session(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {}
 
-ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) {
+ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/) {
     LOG(INFO) << "generateChallenge";
     if (cb_) {
         cb_->onStateChanged(0, SessionState::GENERATING_CHALLENGE);
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index 0651726..eb9ae83 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -30,7 +30,7 @@
   public:
     explicit Session(std::shared_ptr<ISessionCallback> cb);
 
-    ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override;
+    ndk::ScopedAStatus generateChallenge(int32_t cookie) override;
 
     ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override;
 
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 189095a..a8e73fc 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -43,4 +44,5 @@
   START = 7,
   TOO_DARK = 8,
   TOO_BRIGHT = 9,
+  IMMOBILE = 10,
 }
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
index cdbc2d2..f79c576 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/Error.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
index c81cad2..9c208c4 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/FingerprintSensorType.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 2d44528..07777c9 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index b583006..87eaf96 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -33,7 +34,7 @@
 package android.hardware.biometrics.fingerprint;
 @VintfStability
 interface ISession {
-  void generateChallenge(in int cookie, in int timeoutSec);
+  void generateChallenge(in int cookie);
   void revokeChallenge(in int cookie, in long challenge);
   android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat);
   android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId);
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
index f20f153..13c2b05 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISessionCallback.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
index a6e8b4d..515ddaa 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorLocation.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
index 00cbb6d..c7a4002 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SensorProps.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
index 05dd85b..9b0b6f6 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/SessionState.aidl
@@ -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.                          //
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
index 3709a64..bf11daa 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfo.aidl
@@ -75,5 +75,12 @@
      * the image was too bright to be used for matching.
      */
     TOO_BRIGHT,
+
+    /**
+     * This message may be sent during enrollment if the same area of the finger has already
+     * been captured during this enrollment session. In general, enrolling multiple areas of the
+     * same finger can help against false rejections.
+     */
+    IMMOBILE,
 }
 
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index ab7930d..ef2e6fc 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -61,7 +61,7 @@
      *      to allow addition of biometric enrollments.
      * To secure this path, the following path is taken:
      *   1) Upon user requesting fingerprint enroll, the framework requests
-     *      IFingerprint#generateChallenge
+     *      ISession#generateChallenge
      *   2) Framework sends the challenge to the credential subsystem, and upon credential
      *      confirmation, a HAT is created, containing the challenge in the "challenge" field.
      *   3) Framework sends the HAT to the HAL, e.g. ISession#enroll.
@@ -69,10 +69,9 @@
      *   5) Implementation now has confidence that the user entered their credential to allow
      *      biometric enrollment.
      *
-     * Note that the interface allows multiple in-flight challenges. For example, invoking
-     * generateChallenge(0, 0, timeoutSec, cb) twice does not invalidate the first challenge. The
-     * challenge is invalidated only when:
-     *   1) The provided timeout expires, or
+     * Note that this interface allows multiple in-flight challenges. Invoking generateChallenge
+     * twice does not invalidate the first challenge. The challenge is invalidated only when:
+     *   1) Its lifespan exceeds the HAL's internal challenge timeout
      *   2) IFingerprint#revokeChallenge is invoked
      *
      * For example, the following is a possible table of valid challenges:
@@ -86,9 +85,8 @@
      * ----------------------------------------------
      *
      * @param cookie A unique number identifying this operation
-     * @param timeoutSec Duration for which the challenge is valid for
      */
-    void generateChallenge(in int cookie, in int timeoutSec);
+    void generateChallenge(in int cookie);
 
     /**
      * revokeChallenge:
@@ -117,7 +115,7 @@
      *
      * Before capturing fingerprint data, the implementation must first verify the authenticity and
      * integrity of the provided HardwareAuthToken. In addition, it must check that the challenge
-     * within the provided HardwareAuthToken is valid. See IFingerprint#generateChallenge. If any of
+     * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of
      * the above checks fail, the framework must be notified via ISessionCallback#onError and the
      * HAL must notify the framework when it returns to the idle state. See
      * Error::UNABLE_TO_PROCESS.
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index 8028089..206f518 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -28,8 +28,8 @@
 constexpr bool SUPPORTS_NAVIGATION_GESTURES = true;
 constexpr char HW_DEVICE_NAME[] = "fingerprintSensor";
 constexpr char HW_VERSION[] = "vendor/model/revision";
-constexpr char FW_VERSION[] = "1.01";
 constexpr char SERIAL_NUMBER[] = "00000001";
+constexpr char SW_VERSION[] = "vendor1/algorithm1/version;vendor2/algorithm2/version";
 
 }  // namespace
 
@@ -37,11 +37,10 @@
     : mEngine(std::make_unique<FakeFingerprintEngine>()), mWorker(MAX_WORKER_QUEUE_SIZE) {}
 
 ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
-    std::vector<common::HardwareInfo> hardwareInfos = {
-            {HW_DEVICE_NAME, HW_VERSION, FW_VERSION, SERIAL_NUMBER}};
+    std::vector<common::HardwareInfo> hardwareInfos = {{HW_DEVICE_NAME, HW_VERSION, SERIAL_NUMBER}};
 
     common::CommonProps commonProps = {SENSOR_ID, SENSOR_STRENGTH, MAX_ENROLLMENTS_PER_USER,
-                                       hardwareInfos};
+                                       hardwareInfos, SW_VERSION};
 
     SensorLocation sensorLocation = {0 /* displayId */, 0 /* sensorLocationX */,
                                      0 /* sensorLocationY */, 0 /* sensorRadius */};
diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp
index f6a0314..9e6ac77 100644
--- a/biometrics/fingerprint/aidl/default/Session.cpp
+++ b/biometrics/fingerprint/aidl/default/Session.cpp
@@ -60,13 +60,13 @@
     return mCurrentState == SessionState::CLOSED;
 }
 
-ndk::ScopedAStatus Session::generateChallenge(int32_t cookie, int32_t timeoutSec) {
+ndk::ScopedAStatus Session::generateChallenge(int32_t cookie) {
     LOG(INFO) << "generateChallenge";
     scheduleStateOrCrash(SessionState::GENERATING_CHALLENGE);
 
-    mWorker->schedule(Callable::from([this, cookie, timeoutSec] {
+    mWorker->schedule(Callable::from([this, cookie] {
         enterStateOrCrash(cookie, SessionState::GENERATING_CHALLENGE);
-        mEngine->generateChallengeImpl(mCb.get(), timeoutSec);
+        mEngine->generateChallengeImpl(mCb.get());
         enterIdling(cookie);
     }));
 
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 9343316..42e1aa5 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -22,7 +22,7 @@
 
 class FakeFingerprintEngine {
   public:
-    void generateChallengeImpl(ISessionCallback* cb, int32_t /*timeoutSec*/) {
+    void generateChallengeImpl(ISessionCallback* cb) {
         LOG(INFO) << "generateChallengeImpl";
         cb->onChallengeGenerated(0 /* challenge */);
     }
@@ -73,4 +73,4 @@
     }
 };
 
-}  // namespace aidl::android::hardware::biometrics::fingerprint
\ No newline at end of file
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h
index adda831..d2f0c19 100644
--- a/biometrics/fingerprint/aidl/default/include/Session.h
+++ b/biometrics/fingerprint/aidl/default/include/Session.h
@@ -32,7 +32,7 @@
     Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
             FakeFingerprintEngine* engine, WorkerThread* worker);
 
-    ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override;
+    ndk::ScopedAStatus generateChallenge(int32_t cookie) override;
 
     ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override;
 
diff --git a/camera/common/1.0/default/CameraModule.cpp b/camera/common/1.0/default/CameraModule.cpp
index 27e74f1..16fb85c 100644
--- a/camera/common/1.0/default/CameraModule.cpp
+++ b/camera/common/1.0/default/CameraModule.cpp
@@ -549,7 +549,6 @@
                 }
             }
         }
-        free_camera_metadata(metadata);
     }
 
     mCameraInfoMap.removeItem(cameraId);
diff --git a/camera/device/3.7/Android.bp b/camera/device/3.7/Android.bp
new file mode 100644
index 0000000..42782f2
--- /dev/null
+++ b/camera/device/3.7/Android.bp
@@ -0,0 +1,22 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.camera.device@3.7",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+        "ICameraDevice.hal",
+        "ICameraDeviceSession.hal",
+    ],
+    interfaces: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.device@3.6",
+        "android.hardware.graphics.common@1.0",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: false,
+}
diff --git a/camera/device/3.7/ICameraDevice.hal b/camera/device/3.7/ICameraDevice.hal
new file mode 100644
index 0000000..9bc2083
--- /dev/null
+++ b/camera/device/3.7/ICameraDevice.hal
@@ -0,0 +1,43 @@
+/*
+ * 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.camera.device@3.7;
+
+import android.hardware.camera.common@1.0::Status;
+import @3.6::ICameraDevice;
+
+/**
+ * Camera device interface
+ *
+ * Supports the android.hardware.Camera API, and the android.hardware.camera2
+ * API at LIMITED or better hardware level.
+ *
+ * ICameraDevice.open() must return @3.2::ICameraDeviceSession,
+ * @3.5::ICameraDeviceSession, @3.6::ICameraDeviceSession, or
+ * @3.7::ICameraDeviceSession.
+ */
+interface ICameraDevice extends @3.6::ICameraDevice {
+    /**
+     * isStreamCombinationSupported_3_7:
+     *
+     * Identical to @3.5::ICameraDevice.isStreamCombinationSupported, except
+     * that it takes a @3.7::StreamConfiguration parameter, which could contain
+     * information about multi-resolution input and output streams.
+     *
+     */
+    isStreamCombinationSupported_3_7(StreamConfiguration streams)
+            generates (Status status, bool queryStatus);
+};
diff --git a/camera/device/3.7/ICameraDeviceSession.hal b/camera/device/3.7/ICameraDeviceSession.hal
new file mode 100644
index 0000000..fb5c7fa
--- /dev/null
+++ b/camera/device/3.7/ICameraDeviceSession.hal
@@ -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.
+ */
+
+package android.hardware.camera.device@3.7;
+
+import android.hardware.camera.common@1.0::Status;
+import @3.2::BufferCache;
+import @3.5::StreamConfiguration;
+import @3.6::ICameraDeviceSession;
+import @3.6::HalStreamConfiguration;
+
+/**
+ * Camera device active session interface.
+ *
+ * Obtained via ICameraDevice::open(), this interface contains the methods to
+ * configure and request captures from an active camera device.
+ */
+interface ICameraDeviceSession extends @3.6::ICameraDeviceSession {
+    /**
+     * configureStreams_3_7:
+     *
+     * Identical to @3.6::ICameraDeviceSession.configureStreams_3_6, except that:
+     *
+     * - The requestedConfiguration allows the camera framework to configure
+     *   stream groups.
+     * - For requested configurations of streams within the same group, the
+     *   corresponding halConfiguration must have the same usage flags and
+     *   maxBuffers.
+     * - Within a CaptureRequest, the application is guaranteed not to request
+     *   more than one streams within the same stream group. When one of the
+     *   stream within a stream group is requested, the camera HAL can either
+     *   produce output on that stream, or any other stream within the same
+     *   stream group.
+     * - The requestedConfiguration allows the camera framework to indicate that
+     *   input images of different sizes may be submitted within capture
+     *   requests.
+     *
+     * @return status Status code for the operation, one of:
+     *     OK:
+     *         On successful stream configuration.
+     *     INTERNAL_ERROR:
+     *         If there has been a fatal error and the device is no longer
+     *         operational. Only close() can be called successfully by the
+     *         framework after this error is returned.
+     *     ILLEGAL_ARGUMENT:
+     *         If the requested stream configuration is invalid. Some examples
+     *         of invalid stream configurations include:
+     *           - Including more than 1 INPUT stream
+     *           - Not including any OUTPUT streams
+     *           - Including streams with unsupported formats, or an unsupported
+     *             size for that format.
+     *           - Including too many output streams of a certain format.
+     *           - Unsupported rotation configuration
+     *           - Stream sizes/formats don't satisfy the
+     *             StreamConfigurationMode requirements
+     *             for non-NORMAL mode, or the requested operation_mode is not
+     *             supported by the HAL.
+     *           - Unsupported usage flag
+     *           - Unsupported stream groupIds, or unsupported multi-resolution
+     *             input stream.
+     *         The camera service cannot filter out all possible illegal stream
+     *         configurations, since some devices may support more simultaneous
+     *         streams or larger stream resolutions than the minimum required
+     *         for a given camera device hardware level. The HAL must return an
+     *         ILLEGAL_ARGUMENT for any unsupported stream set, and then be
+     *         ready to accept a future valid stream configuration in a later
+     *         configureStreams call.
+     * @return halConfiguration The stream parameters desired by the HAL for
+     *     each stream, including maximum buffers, the usage flags, and the
+     *     override format.
+     */
+    configureStreams_3_7(StreamConfiguration requestedConfiguration)
+        generates (Status status, @3.6::HalStreamConfiguration halConfiguration);
+
+    /**
+     * processCaptureRequest_3_7:
+     *
+     * Identical to @3.4::ICameraDeviceSession.processCaptureRequest, except that:
+     *
+     * - The capture request can include width and height of the input buffer for
+     *   a reprocessing request.
+     *
+     * @return status Status code for the operation, one of:
+     *     OK:
+     *         On a successful start to processing the capture request
+     *     ILLEGAL_ARGUMENT:
+     *         If the input is malformed (the settings are empty when not
+     *         allowed, the physical camera settings are invalid, there are 0
+     *         output buffers, etc) and capture processing
+     *         cannot start. Failures during request processing must be
+     *         handled by calling ICameraDeviceCallback::notify(). In case of
+     *         this error, the framework retains responsibility for the
+     *         stream buffers' fences and the buffer handles; the HAL must not
+     *         close the fences or return these buffers with
+     *         ICameraDeviceCallback::processCaptureResult().
+     *         In case of multi-resolution input image, this error must be returned
+     *         if the caller passes in a CaptureRequest with an invalid
+     *         [inputWith, inputHeight].
+     *     INTERNAL_ERROR:
+     *         If the camera device has encountered a serious error. After this
+     *         error is returned, only the close() method can be successfully
+     *         called by the framework.
+     * @return numRequestProcessed Number of requests successfully processed by
+     *     camera HAL. When status is OK, this must be equal to the size of
+     *     requests. When the call fails, this number is the number of requests
+     *     that HAL processed successfully before HAL runs into an error.
+     *
+     */
+    processCaptureRequest_3_7(vec<CaptureRequest> requests, vec<BufferCache> cachesToRemove)
+            generates (Status status, uint32_t numRequestProcessed);
+};
diff --git a/camera/device/3.7/types.hal b/camera/device/3.7/types.hal
new file mode 100644
index 0000000..9450c2f
--- /dev/null
+++ b/camera/device/3.7/types.hal
@@ -0,0 +1,136 @@
+/*
+ * 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.camera.device@3.7;
+
+import @3.2::CameraMetadata;
+import @3.2::StreamConfigurationMode;
+import @3.4::CaptureRequest;
+import @3.4::Stream;
+
+/**
+ * Stream:
+ *
+ * A descriptor for a single camera input or output stream. A stream is defined
+ * by the framework by its buffer resolution and format, and additionally by the
+ * HAL with the gralloc usage flags and the maximum in-flight buffer count.
+ *
+ * This version extends the @3.4 Stream with the multi-resolution output surface
+ * group Id field.
+ */
+struct Stream {
+    /**
+     * The definition of Stream from the prior version.
+     */
+    @3.4::Stream v3_4;
+
+    /**
+     * The surface group id used for multi-resolution output streams.
+     *
+     * This works simliar to the surfaceGroupId of OutputConfiguration in the
+     * public API, with the exception that this is for multi-resolution image
+     * reader and is used by the camera HAL to choose a target stream within
+     * the same group to which images are written. All streams in the same group
+     * will have the same image format, data space, and usage flag.
+     *
+     * The framework must only call processCaptureRequest on at most one of the
+     * streams within a surface group. Depending on current active physical
+     * camera backing the logical multi-camera, or the pixel mode the camera is
+     * running in, the HAL can choose to request and return a buffer from any
+     * stream within the same group. -1 means that this stream is an input
+     * stream, or is an output stream which doesn't belong to any group.
+     *
+     * Streams with the same non-negative group id must have the same format and
+     * usage flag.
+     */
+    int32_t groupId;
+};
+
+/**
+ * StreamConfiguration:
+ *
+ * Identical to @3.5::StreamConfiguration, except that the streams
+ * vector contains @3.7::Stream.
+ */
+struct StreamConfiguration {
+    /**
+     * An array of camera stream pointers, defining the input/output
+     * configuration for the camera HAL device.
+     */
+    vec<Stream> streams;
+
+    /**
+     * The definition of operation mode from prior version.
+     *
+     */
+    @3.2::StreamConfigurationMode operationMode;
+
+    /**
+     * The definition of session parameters from prior version.
+     */
+    @3.2::CameraMetadata sessionParams;
+
+    /**
+     * The definition of stream configuration counter from prior version.
+     */
+    uint32_t streamConfigCounter;
+
+    /**
+     * If an input stream is configured, whether the input stream is expected to
+     * receive variable resolution images.
+     *
+     * This flag can only be set to true if the camera device supports
+     * multi-resolution input streams by advertising input stream configurations in
+     * physicalCameraMultiResolutionStreamConfigurations in its physical cameras'
+     * characteristics.
+     *
+     * When this flag is set to true, the input stream's width and height can be
+     * any one of the supported multi-resolution input stream sizes.
+     */
+    bool multiResolutionInputImage;
+};
+
+/**
+ * CaptureRequest:
+ *
+ * This version extends 3.4::CaptureRequest with the input buffer's width and
+ * height.
+ */
+struct CaptureRequest {
+    /**
+     * The definition of CaptureRequest from the prior version.
+     */
+    @3.4::CaptureRequest v3_4;
+
+    /**
+     * The width and height of the input buffer for this capture request.
+     *
+     * These fields will be [0, 0] if no input buffer exists in the capture
+     * request.
+     *
+     * If the stream configuration contains an input stream and has the
+     * multiResolutionInputImage flag set to true, the camera client may submit a
+     * reprocessing request with input buffer size different than the
+     * configured input stream size. In that case, the inputWith and inputHeight
+     * fields will be the actual size of the input image.
+     *
+     * If the stream configuration contains an input stream and the
+     * multiResolutionInputImage flag is false, the inputWidth and inputHeight must
+     * match the input stream size.
+     */
+    uint32_t inputWidth;
+    uint32_t inputHeight;
+};
diff --git a/camera/metadata/3.6/types.hal b/camera/metadata/3.6/types.hal
index fb95736..3472ae9 100644
--- a/camera/metadata/3.6/types.hal
+++ b/camera/metadata/3.6/types.hal
@@ -42,6 +42,14 @@
      */
     ANDROID_SCALER_DEFAULT_SECURE_IMAGE_SIZE = android.hardware.camera.metadata@3.5::CameraMetadataTag:ANDROID_SCALER_END_3_5,
 
+    /** android.scaler.physicalCameraMultiResolutionStreamConfigurations [static, enum[], ndk_public]
+     *
+     * <p>The available multi-resolution stream configurations that this
+     * physical camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     */
+    ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS,
+
     ANDROID_SCALER_END_3_6,
 
 };
@@ -49,3 +57,11 @@
 /*
  * Enumeration definitions for the various entries that need them
  */
+
+/** android.scaler.physicalCameraMultiResolutionStreamConfigurations enumeration values
+ * @see ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS
+ */
+enum CameraMetadataEnumAndroidScalerPhysicalCameraMultiResolutionStreamConfigurations : uint32_t {
+    ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_OUTPUT,
+    ANDROID_SCALER_PHYSICAL_CAMERA_MULTI_RESOLUTION_STREAM_CONFIGURATIONS_INPUT,
+};
diff --git a/camera/provider/2.4/vts/functional/Android.bp b/camera/provider/2.4/vts/functional/Android.bp
index 691d772..8886ee1 100644
--- a/camera/provider/2.4/vts/functional/Android.bp
+++ b/camera/provider/2.4/vts/functional/Android.bp
@@ -48,10 +48,12 @@
         "android.hardware.camera.device@3.4",
         "android.hardware.camera.device@3.5",
         "android.hardware.camera.device@3.6",
+        "android.hardware.camera.device@3.7",
         "android.hardware.camera.metadata@3.4",
         "android.hardware.camera.provider@2.4",
         "android.hardware.camera.provider@2.5",
         "android.hardware.camera.provider@2.6",
+        "android.hardware.camera.provider@2.7",
         "android.hardware.graphics.common@1.0",
         "android.hidl.allocator@1.0",
         "libgrallocusage",
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index d621344..b2fd402 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -40,11 +40,14 @@
 #include <android/hardware/camera/device/3.5/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.6/ICameraDevice.h>
 #include <android/hardware/camera/device/3.6/ICameraDeviceSession.h>
+#include <android/hardware/camera/device/3.7/ICameraDevice.h>
+#include <android/hardware/camera/device/3.7/ICameraDeviceSession.h>
 #include <android/hardware/camera/metadata/3.4/types.h>
 #include <android/hardware/camera/provider/2.4/ICameraProvider.h>
 #include <android/hardware/camera/provider/2.5/ICameraProvider.h>
 #include <android/hardware/camera/provider/2.6/ICameraProvider.h>
 #include <android/hardware/camera/provider/2.6/ICameraProviderCallback.h>
+#include <android/hardware/camera/provider/2.7/ICameraProvider.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <binder/MemoryHeapBase.h>
 #include <cutils/properties.h>
@@ -189,12 +192,14 @@
 namespace {
     // "device@<version>/legacy/<id>"
     const char *kDeviceNameRE = "device@([0-9]+\\.[0-9]+)/%s/(.+)";
+    const int CAMERA_DEVICE_API_VERSION_3_7 = 0x307;
     const int CAMERA_DEVICE_API_VERSION_3_6 = 0x306;
     const int CAMERA_DEVICE_API_VERSION_3_5 = 0x305;
     const int CAMERA_DEVICE_API_VERSION_3_4 = 0x304;
     const int CAMERA_DEVICE_API_VERSION_3_3 = 0x303;
     const int CAMERA_DEVICE_API_VERSION_3_2 = 0x302;
     const int CAMERA_DEVICE_API_VERSION_1_0 = 0x100;
+    const char *kHAL3_7 = "3.7";
     const char *kHAL3_6 = "3.6";
     const char *kHAL3_5 = "3.5";
     const char *kHAL3_4 = "3.4";
@@ -231,7 +236,9 @@
             return -1;
         }
 
-        if (version.compare(kHAL3_6) == 0) {
+        if (version.compare(kHAL3_7) == 0) {
+            return CAMERA_DEVICE_API_VERSION_3_7;
+        } else if (version.compare(kHAL3_6) == 0) {
             return CAMERA_DEVICE_API_VERSION_3_6;
         } else if (version.compare(kHAL3_5) == 0) {
             return CAMERA_DEVICE_API_VERSION_3_5;
@@ -756,7 +763,8 @@
             sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
             sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
             sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
-            sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/);
+            sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/,
+            sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/);
     void castDevice(const sp<device::V3_2::ICameraDevice> &device, int32_t deviceVersion,
             sp<device::V3_5::ICameraDevice> *device3_5/*out*/);
     void createStreamConfiguration(const ::android::hardware::hidl_vec<V3_2::Stream>& streams3_2,
@@ -1883,6 +1891,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
@@ -1926,6 +1935,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
@@ -2666,6 +2676,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
@@ -2752,6 +2763,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
@@ -2832,6 +2844,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
@@ -2959,6 +2972,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
@@ -3025,6 +3039,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
@@ -3056,9 +3071,13 @@
                 sp<device::V3_4::ICameraDeviceSession> sessionV3_4;
                 sp<device::V3_5::ICameraDeviceSession> sessionV3_5;
                 sp<device::V3_6::ICameraDeviceSession> sessionV3_6;
+                sp<device::V3_7::ICameraDeviceSession> sessionV3_7;
                 castSession(session, deviceVersion, &sessionV3_3,
-                        &sessionV3_4, &sessionV3_5, &sessionV3_6);
-                if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
+                        &sessionV3_4, &sessionV3_5, &sessionV3_6,
+                        &sessionV3_7);
+                if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_7) {
+                    ASSERT_TRUE(sessionV3_7.get() != nullptr);
+                } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
                     ASSERT_TRUE(sessionV3_6.get() != nullptr);
                 } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
                     ASSERT_TRUE(sessionV3_5.get() != nullptr);
@@ -3122,6 +3141,7 @@
     for (const auto& name : cameraDeviceNames) {
         int deviceVersion = getCameraDeviceVersion(name, mProviderType);
         switch (deviceVersion) {
+            case CAMERA_DEVICE_API_VERSION_3_7:
             case CAMERA_DEVICE_API_VERSION_3_6:
             case CAMERA_DEVICE_API_VERSION_3_5:
             case CAMERA_DEVICE_API_VERSION_3_4:
@@ -3221,11 +3241,13 @@
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
         sp<device::V3_6::ICameraDeviceSession> session3_6;
+        sp<device::V3_7::ICameraDeviceSession> session3_7;
         sp<device::V3_2::ICameraDevice> cameraDevice;
         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         openEmptyDeviceSession(name, mProvider,
                 &session /*out*/, &staticMeta /*out*/, &cameraDevice /*out*/);
-        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+                &session3_6, &session3_7);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         outputStreams.clear();
@@ -3307,6 +3329,7 @@
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
         sp<device::V3_6::ICameraDeviceSession> session3_6;
+        sp<device::V3_7::ICameraDeviceSession> session3_7;
         sp<device::V3_2::ICameraDevice> cameraDevice;
         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         ::android::hardware::camera::device::V3_5::StreamConfiguration config3_5;
@@ -3344,7 +3367,7 @@
             openEmptyDeviceSession(name, mProvider2_6, &cti.session /*out*/,
                                    &cti.staticMeta /*out*/, &cti.cameraDevice /*out*/);
             castSession(cti.session, deviceVersion, &cti.session3_3, &cti.session3_4,
-                        &cti.session3_5, &cti.session3_6);
+                        &cti.session3_5, &cti.session3_6, &cti.session3_7);
             castDevice(cti.cameraDevice, deviceVersion, &cti.cameraDevice3_5);
 
             outputStreams.clear();
@@ -3462,11 +3485,13 @@
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
         sp<device::V3_6::ICameraDeviceSession> session3_6;
+        sp<device::V3_7::ICameraDeviceSession> session3_7;
         sp<device::V3_2::ICameraDevice> cameraDevice;
         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
                 &cameraDevice /*out*/);
-        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+                &session3_6, &session3_7);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         outputStreams.clear();
@@ -3660,11 +3685,13 @@
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
         sp<device::V3_6::ICameraDeviceSession> session3_6;
+        sp<device::V3_7::ICameraDeviceSession> session3_7;
         sp<device::V3_2::ICameraDevice> cameraDevice;
         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
                 &cameraDevice /*out*/);
-        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+                &session3_6, &session3_7);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         Status rc = isZSLModeAvailable(staticMeta);
@@ -3828,8 +3855,10 @@
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
         sp<device::V3_6::ICameraDeviceSession> session3_6;
+        sp<device::V3_7::ICameraDeviceSession> session3_7;
         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMetaBuffer /*out*/);
-        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+                &session3_6, &session3_7);
         if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_4) {
             ASSERT_NE(session3_4, nullptr);
         } else {
@@ -3951,11 +3980,13 @@
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
         sp<device::V3_6::ICameraDeviceSession> session3_6;
+        sp<device::V3_7::ICameraDeviceSession> session3_7;
         sp<device::V3_2::ICameraDevice> cameraDevice;
         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
                 &cameraDevice /*out*/);
-        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+                &session3_6, &session3_7);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         // Check if camera support depth only
@@ -4069,11 +4100,13 @@
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
         sp<device::V3_6::ICameraDeviceSession> session3_6;
+        sp<device::V3_7::ICameraDeviceSession> session3_7;
         sp<device::V3_2::ICameraDevice> cameraDevice;
         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
                 &cameraDevice /*out*/);
-        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+                &session3_6, &session3_7);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         Status rc = isConstrainedModeAvailable(staticMeta);
@@ -4281,11 +4314,13 @@
         sp<device::V3_4::ICameraDeviceSession> session3_4;
         sp<device::V3_5::ICameraDeviceSession> session3_5;
         sp<device::V3_6::ICameraDeviceSession> session3_6;
+        sp<device::V3_7::ICameraDeviceSession> session3_7;
         sp<device::V3_2::ICameraDevice> cameraDevice;
         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         openEmptyDeviceSession(name, mProvider, &session /*out*/, &staticMeta /*out*/,
                 &cameraDevice /*out*/);
-        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+        castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+                &session3_6, &session3_7);
         castDevice(cameraDevice, deviceVersion, &cameraDevice3_5);
 
         // Check if camera support depth only
@@ -6103,7 +6138,9 @@
 
     sp<device::V3_3::ICameraDeviceSession> session3_3;
     sp<device::V3_6::ICameraDeviceSession> session3_6;
-    castSession(session, deviceVersion, &session3_3, session3_4, session3_5, &session3_6);
+    sp<device::V3_7::ICameraDeviceSession> session3_7;
+    castSession(session, deviceVersion, &session3_3, session3_4, session3_5,
+            &session3_6, &session3_7);
     ASSERT_NE(nullptr, (*session3_4).get());
 
     *useHalBufManager = false;
@@ -6144,7 +6181,7 @@
             });
     ASSERT_TRUE(ret.isOk());
 
-    ASSERT_TRUE(!allowUnsupport || deviceVersion == CAMERA_DEVICE_API_VERSION_3_5);
+    ASSERT_TRUE(!allowUnsupport || deviceVersion >= CAMERA_DEVICE_API_VERSION_3_5);
     if (allowUnsupport) {
         sp<device::V3_5::ICameraDevice> cameraDevice3_5;
         castDevice(device3_x, deviceVersion, &cameraDevice3_5);
@@ -6446,7 +6483,9 @@
     sp<device::V3_4::ICameraDeviceSession> session3_4;
     sp<device::V3_5::ICameraDeviceSession> session3_5;
     sp<device::V3_6::ICameraDeviceSession> session3_6;
-    castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+    sp<device::V3_7::ICameraDeviceSession> session3_7;
+    castSession(*session, deviceVersion, &session3_3, &session3_4, &session3_5,
+            &session3_6, &session3_7);
 
     *useHalBufManager = false;
     status = find_camera_metadata_ro_entry(staticMeta,
@@ -6583,13 +6622,21 @@
         sp<device::V3_3::ICameraDeviceSession> *session3_3 /*out*/,
         sp<device::V3_4::ICameraDeviceSession> *session3_4 /*out*/,
         sp<device::V3_5::ICameraDeviceSession> *session3_5 /*out*/,
-        sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/) {
+        sp<device::V3_6::ICameraDeviceSession> *session3_6 /*out*/,
+        sp<device::V3_7::ICameraDeviceSession> *session3_7 /*out*/) {
     ASSERT_NE(nullptr, session3_3);
     ASSERT_NE(nullptr, session3_4);
     ASSERT_NE(nullptr, session3_5);
     ASSERT_NE(nullptr, session3_6);
+    ASSERT_NE(nullptr, session3_7);
 
     switch (deviceVersion) {
+        case CAMERA_DEVICE_API_VERSION_3_7: {
+            auto castResult = device::V3_7::ICameraDeviceSession::castFrom(session);
+            ASSERT_TRUE(castResult.isOk());
+            *session3_7 = castResult;
+        }
+        [[fallthrough]];
         case CAMERA_DEVICE_API_VERSION_3_6: {
             auto castResult = device::V3_6::ICameraDeviceSession::castFrom(session);
             ASSERT_TRUE(castResult.isOk());
@@ -7233,7 +7280,9 @@
     sp<device::V3_4::ICameraDeviceSession> session3_4;
     sp<device::V3_5::ICameraDeviceSession> session3_5;
     sp<device::V3_6::ICameraDeviceSession> session3_6;
-    castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5, &session3_6);
+    sp<device::V3_7::ICameraDeviceSession> session3_7;
+    castSession(session, deviceVersion, &session3_3, &session3_4, &session3_5,
+            &session3_6, &session3_7);
     ASSERT_NE(nullptr, session3_5.get());
 
     hidl_vec<int32_t> streamIds(1);
diff --git a/camera/provider/2.7/Android.bp b/camera/provider/2.7/Android.bp
new file mode 100644
index 0000000..094dd9d
--- /dev/null
+++ b/camera/provider/2.7/Android.bp
@@ -0,0 +1,26 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.camera.provider@2.7",
+    root: "android.hardware",
+    srcs: [
+        "types.hal",
+        "ICameraProvider.hal",
+    ],
+    interfaces: [
+        "android.hardware.camera.common@1.0",
+        "android.hardware.camera.device@1.0",
+        "android.hardware.camera.device@3.2",
+        "android.hardware.camera.device@3.3",
+        "android.hardware.camera.device@3.4",
+        "android.hardware.camera.device@3.5",
+        "android.hardware.camera.device@3.6",
+        "android.hardware.camera.device@3.7",
+        "android.hardware.camera.provider@2.4",
+        "android.hardware.camera.provider@2.5",
+        "android.hardware.camera.provider@2.6",
+        "android.hardware.graphics.common@1.0",
+        "android.hidl.base@1.0",
+    ],
+    gen_java: false,
+}
diff --git a/camera/provider/2.7/ICameraProvider.hal b/camera/provider/2.7/ICameraProvider.hal
new file mode 100644
index 0000000..c9d52ee
--- /dev/null
+++ b/camera/provider/2.7/ICameraProvider.hal
@@ -0,0 +1,51 @@
+/*
+ * 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.camera.provider@2.7;
+
+import @2.6::ICameraProvider;
+import android.hardware.camera.common@1.0::Status;
+
+/**
+ * Camera provider HAL
+ *
+ * Adds support for the isConcurrentStreamCombinationSupported() with
+ * ICameraDevice@3.7::StreamConfiguration.
+ */
+interface ICameraProvider extends @2.6::ICameraProvider {
+    /**
+     * isConcurrentStreamCombinationSupported_2_7:
+     *
+     * Identical to @2.6::isConcurrentStreamCombinationSupported except that
+     * this function takes a vector of @3.7::StreamConfiguration.
+     *
+     * @param configs a vector of camera ids and their corresponding stream
+     *                configurations that need to be queried for support.
+     *
+     * @return status Status code for the operation, one of:
+     *     OK:
+     *          On successful stream combination query.
+     *     METHOD_NOT_SUPPORTED:
+     *          The camera provider does not support stream combination query.
+     *     INTERNAL_ERROR:
+     *          The stream combination query cannot complete due to internal
+     *          error.
+     * @return true in case the stream combination is supported, false otherwise.
+     *
+     */
+    isConcurrentStreamCombinationSupported_2_7(vec<CameraIdAndStreamCombination> configs)
+        generates (Status status, bool queryStatus);
+};
diff --git a/camera/provider/2.7/types.hal b/camera/provider/2.7/types.hal
new file mode 100644
index 0000000..363e894
--- /dev/null
+++ b/camera/provider/2.7/types.hal
@@ -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.
+ */
+
+package android.hardware.camera.provider@2.7;
+
+import android.hardware.camera.device@3.7::StreamConfiguration;
+
+/**
+ * CameraIdAndStreamCombination:
+ *
+ * This is identical to @2.6::CameraIdAndStreamCombination except that
+ * streamConfiguration is of version @3.7.
+ */
+struct CameraIdAndStreamCombination {
+    string cameraId;
+    @3.7::StreamConfiguration streamConfiguration;
+};
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 6562f22..9e99c48 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -165,7 +165,7 @@
     </hal>
     <hal format="hidl" optional="true">
         <name>android.hardware.camera.provider</name>
-        <version>2.4-6</version>
+        <version>2.4-7</version>
         <interface>
             <name>ICameraProvider</name>
             <regex-instance>[^/]+/[0-9]+</regex-instance>
@@ -387,14 +387,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 dfe5d9d..af50841 100644
--- a/current.txt
+++ b/current.txt
@@ -787,7 +787,13 @@
 0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types
 38d65fb20c60a5b823298560fc0825457ecdc49603a4b4e94bf81511790737da android.hardware.radio@1.4::types
 954c334efd80e8869b66d1ce5fe2755712d96ba4b3c38d415739c330af5fb4cb android.hardware.radio@1.5::types
+cfaab0e45c5d7b3595032d649da29ed712e920f956c13671efd35602fa81c923 android.hardware.radio@1.0::IRadio
+89d78fa49b09e2f31812bb63e1bfac2bf318a9561473c6b0ed6904ce18377d54 android.hardware.radio@1.0::IRadioIndication
+bc3c8c233085fca3879dc74b490b9e5bc1063258470d3b4c12f7a74bf215cbbd android.hardware.radio@1.0::IRadioResponse
+86fb079a600b2301a752249dfbfc53983a795d752f11aabcb68315a189f6c9a2 android.hardware.radio@1.1::IRadio
+00366b2f88f9ec2458014972938270c8413d4ab303218e37bf3add2b8e6b829a android.hardware.radio@1.1::IRadioResponse
+2b5afef68e3e2ff1dab63e4f2ee57337ef2635ec812f49080cadfce966d33b52 android.hardware.radio@1.2::IRadio
 
 # HALs released in Android S
 # NOTE: waiting to freeze HALs until later in the release
-# NOTE: new HALs are recommended to be in AIDL
\ No newline at end of file
+# NOTE: new HALs are recommended to be in AIDL
diff --git a/drm/1.4/types.hal b/drm/1.4/types.hal
index 17eba8a..a4490a5 100644
--- a/drm/1.4/types.hal
+++ b/drm/1.4/types.hal
@@ -119,6 +119,10 @@
      */
     PROVISIONING_PARSE_ERROR,
     /**
+     * The provisioning server detected an error in the provisioning request.
+     */
+    PROVISIONING_REQUEST_REJECTED,
+    /**
      * Provisioning failed in a way that is likely to succeed on a subsequent
      * attempt.
      */
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
index 2d21748..9c9a241 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
@@ -33,7 +33,7 @@
 package android.hardware.gnss;
 @VintfStability
 parcelable CorrelationVector {
-  int frequencyOffsetMps;
+  double frequencyOffsetMps;
   double samplingWidthM;
   double samplingStartM;
   int[] magnitude;
diff --git a/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl
index 22a80ce..6fbabbc 100644
--- a/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl
+++ b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl
@@ -22,11 +22,10 @@
  */
 @VintfStability
 parcelable CorrelationVector {
-
     /**
      * Frequency offset from reported pseudorange rate for this Correlation Vector.
      */
-    int frequencyOffsetMps;
+    double frequencyOffsetMps;
 
     /**
      * Space between correlation samples in meters.
@@ -48,4 +47,4 @@
      * The length of the array is defined by the GNSS chipset.
      */
     int[] magnitude;
-}
\ No newline at end of file
+}
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/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/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/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/IRadio.hal b/radio/1.0/IRadio.hal
index 236dbf5..66cd4f0 100644
--- a/radio/1.0/IRadio.hal
+++ b/radio/1.0/IRadio.hal
@@ -385,7 +385,10 @@
      *                  Note this is for backward compatibility with the old radio modem. The modem
      *                  must not use this param for any other reason.
      *
-     * Response function is IRadioResponse.setupDataCallResponse()
+     * Response function is IRadioResponse.setupDataCallResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.2 or higher, use @1.2::IRadio.setupDataCall_1_2() instead.
      */
     oneway setupDataCall(int32_t serial, RadioTechnology radioTechnology,
             DataProfileInfo dataProfileInfo, bool modemCognitive, bool roamingAllowed,
@@ -546,7 +549,10 @@
      *        false => No specific reason specified
      *        true => Radio shutdown requested
      *
-     * Response function is IRadioResponse.deactivateDataCallResponse()
+     * Response function is IRadioResponse.deactivateDataCallResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.2 or higher, use @1.2::IRadio.deactivateDataCall_1_2() instead.
      */
     oneway deactivateDataCall(int32_t serial, int32_t cid,
             bool reasonRadioShutDown);
@@ -1456,7 +1462,10 @@
      * @param reportInterval desired reporting interval (ms).
      * @param pullMode LCE service mode. true: PULL; false: PUSH.
      *
-     * Response callback is IRadioResponse.startLceServiceResponse()
+     * Response callback is IRadioResponse.startLceServiceResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
      */
     oneway startLceService(int32_t serial, int32_t reportInterval, bool pullMode);
 
@@ -1466,7 +1475,10 @@
      *
      * @param serial Serial number of request.
      *
-     * Response callback is IRadioResponse.stopLceServiceResponse()
+     * Response callback is IRadioResponse.stopLceServiceResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
      */
     oneway stopLceService(int32_t serial);
 
@@ -1475,7 +1487,10 @@
      *
      * @param serial Serial number of request.
      *
-     * Response callback is IRadioResponse.pullLceDataResponse()
+     * Response callback is IRadioResponse.pullLceDataResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.2 or higher which use the always-on LCE that relies on indications.
      */
     oneway pullLceData(int32_t serial);
 
@@ -1546,7 +1561,10 @@
      * @param indicationFilter 32-bit bitmap of IndicationFilter. Bits set to 1 indicate the
      *        indications are enabled. See IndicationFilter for the definition of each bit.
      *
-     * Response callback is IRadioResponse.setIndicationFilterResponse()
+     * Response callback is IRadioResponse.setIndicationFilterResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.2 or higher, use @1.2::IRadio.setIndicationFilter_1_2() instead.
      */
     oneway setIndicationFilter(int32_t serial, bitfield<IndicationFilter> indicationFilter);
 
@@ -1560,7 +1578,10 @@
      * @param serial Serial number of request
      * @param powerUp True if powering up the sim card
      *
-     * Response callback is IRadioResponse.setSimCardPowerResponse()
+     * Response callback is IRadioResponse.setSimCardPowerResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.1::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.1 or higher, use @1.1::IRadio.setSimCardPower_1_1() instead.
      */
     oneway setSimCardPower(int32_t serial, bool powerUp);
 
diff --git a/radio/1.0/IRadioIndication.hal b/radio/1.0/IRadioIndication.hal
index eb07226..eb6c8ef 100644
--- a/radio/1.0/IRadioIndication.hal
+++ b/radio/1.0/IRadioIndication.hal
@@ -427,6 +427,9 @@
     *
     * @param type Type of radio indication
     * @param lce LceData information
+    *
+    * DEPRECATED in @1.2 and above, use
+    * @1.2::IRadioIndication.currentLinkCapacityEstimate() instead.
     */
    oneway lceData(RadioIndicationType type, LceDataInfo lce);
 
diff --git a/radio/1.0/IRadioResponse.hal b/radio/1.0/IRadioResponse.hal
index c1b16b7..00cec9f 100644
--- a/radio/1.0/IRadioResponse.hal
+++ b/radio/1.0/IRadioResponse.hal
@@ -590,10 +590,10 @@
      *   RadioError:NONE must be returned on both success and failure of setup with the
      *              DataCallResponse.status containing the actual status
      *              For all other errors the DataCallResponse is ignored.
+     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW
      *   RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
@@ -856,12 +856,12 @@
      * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:INVALID_CALL_ID
      *   RadioError:INVALID_STATE
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
@@ -2420,11 +2420,11 @@
      * @param statusInfo LceStatusInfo indicating LCE status
      *
      * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:LCE_NOT_SUPPORTED
      *   RadioError:INTERNAL_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
@@ -2436,6 +2436,7 @@
      * @param statusInfo LceStatusInfo indicating LCE status
      *
      * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:LCE_NOT_SUPPORTED
@@ -2443,7 +2444,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     oneway stopLceServiceResponse(RadioResponseInfo info, LceStatusInfo statusInfo);
@@ -2453,6 +2453,7 @@
      * @param lceInfo LceDataInfo indicating LCE data as defined in types.hal
      *
      * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:LCE_NOT_SUPPORTED
@@ -2460,7 +2461,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:SIM_ABSENT
      */
     oneway pullLceDataResponse(RadioResponseInfo info, LceDataInfo lceInfo);
@@ -2534,13 +2534,13 @@
      * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
      *   RadioError:NONE
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:NO_MEMORY
      *   RadioError:INTERNAL_ERR
      *   RadioError:SYSTEM_ERR
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      */
@@ -2550,9 +2550,9 @@
      * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.1 or higher is supported.
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *   RadioError:REQUEST_NOT_SUPPORTED
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INTERNAL_ERR
      *   RadioError:NO_MEMORY
diff --git a/radio/1.0/vts/functional/vts_test_util.cpp b/radio/1.0/vts/functional/vts_test_util.cpp
index 9a2d089..fc37201 100644
--- a/radio/1.0/vts/functional/vts_test_util.cpp
+++ b/radio/1.0/vts/functional/vts_test_util.cpp
@@ -19,6 +19,8 @@
 #include <iostream>
 #include "VtsCoreUtil.h"
 
+#define WAIT_TIMEOUT_PERIOD 75
+
 int GetRandomSerialNumber() {
     return rand();
 }
@@ -99,4 +101,33 @@
            ::android::hardware::radio::V1_0::RegState::NOT_REG_MT_SEARCHING_OP_EM == state ||
            ::android::hardware::radio::V1_0::RegState::REG_DENIED_EM == state ||
            ::android::hardware::radio::V1_0::RegState::UNKNOWN_EM == state;
-}
\ No newline at end of file
+}
+
+/*
+ * Notify that the response message is received.
+ */
+void RadioResponseWaiter::notify(int receivedSerial) {
+    std::unique_lock<std::mutex> lock(mtx_);
+    if (serial == receivedSerial) {
+        count_++;
+        cv_.notify_one();
+    }
+}
+
+/*
+ * Wait till the response message is notified or till WAIT_TIMEOUT_PERIOD.
+ */
+std::cv_status RadioResponseWaiter::wait() {
+    std::unique_lock<std::mutex> lock(mtx_);
+
+    std::cv_status status = std::cv_status::no_timeout;
+    auto now = std::chrono::system_clock::now();
+    while (count_ == 0) {
+        status = cv_.wait_until(lock, now + std::chrono::seconds(WAIT_TIMEOUT_PERIOD));
+        if (status == std::cv_status::timeout) {
+            return status;
+        }
+    }
+    count_--;
+    return status;
+}
diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h
index 218e823..08f7ba3 100644
--- a/radio/1.0/vts/functional/vts_test_util.h
+++ b/radio/1.0/vts/functional/vts_test_util.h
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#pragma once
+
 #include <android-base/logging.h>
 
 #include <android/hardware/radio/1.0/types.h>
@@ -81,4 +83,24 @@
 /*
  * Check if voice status is in service.
  */
-bool isVoiceInService(RegState state);
\ No newline at end of file
+bool isVoiceInService(RegState state);
+
+/**
+ * Used when waiting for an asynchronous response from the HAL.
+ */
+class RadioResponseWaiter {
+  protected:
+    std::mutex mtx_;
+    std::condition_variable cv_;
+    int count_;
+
+  public:
+    /* Serial number for radio request */
+    int serial;
+
+    /* Used as a mechanism to inform the test about data/event callback */
+    void notify(int receivedSerial);
+
+    /* Test code calls this function to wait for response */
+    std::cv_status wait();
+};
diff --git a/radio/1.1/IRadio.hal b/radio/1.1/IRadio.hal
index 22d27d4..de2135a 100644
--- a/radio/1.1/IRadio.hal
+++ b/radio/1.1/IRadio.hal
@@ -77,7 +77,10 @@
      * @param serial Serial number of request.
      * @param request Defines the radio networks/bands/channels which need to be scanned.
      *
-     * Response function is IRadioResponse.startNetworkScanResponse()
+     * Response function is IRadioResponse.startNetworkScanResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.2::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.2 or higher, use @1.2::IRadio.startNetworkScan_1_2() instead.
      */
     oneway startNetworkScan(int32_t serial, NetworkScanRequest request);
 
diff --git a/radio/1.1/IRadioResponse.hal b/radio/1.1/IRadioResponse.hal
index 759602b..7dc1bc6 100644
--- a/radio/1.1/IRadioResponse.hal
+++ b/radio/1.1/IRadioResponse.hal
@@ -51,6 +51,7 @@
      * @param info Response info struct containing response type, serial no. and error
      *
      * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED may be returned when HAL 1.2 or higher is supported.
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
      *   RadioError:OPERATION_NOT_ALLOWED
@@ -59,7 +60,6 @@
      *   RadioError:NO_MEMORY
      *   RadioError:MODEM_ERR
      *   RadioError:INVALID_ARGUMENTS
-     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     oneway startNetworkScanResponse(RadioResponseInfo info);
 
diff --git a/radio/1.2/IRadio.hal b/radio/1.2/IRadio.hal
index 87b0add..6d48ca0 100644
--- a/radio/1.2/IRadio.hal
+++ b/radio/1.2/IRadio.hal
@@ -37,7 +37,10 @@
      * @param serial Serial number of request.
      * @param request Defines the radio networks/bands/channels which need to be scanned.
      *
-     * Response function is IRadioResponse.startNetworkScanResponse()
+     * Response function is IRadioResponse.startNetworkScanResponse() which may return
+     * RadioError:REQUEST_NOT_SUPPORTED if @1.4::IRadio or higher is supported.
+     *
+     * DEPRECATED in @1.4 or higher, use @1.4::IRadio.startNetworkScan_1_4() instead.
      */
     oneway startNetworkScan_1_2(int32_t serial, NetworkScanRequest request);
 
diff --git a/radio/1.6/vts/functional/Android.bp b/radio/1.6/vts/functional/Android.bp
index dde718b..65b0dd0 100644
--- a/radio/1.6/vts/functional/Android.bp
+++ b/radio/1.6/vts/functional/Android.bp
@@ -36,6 +36,7 @@
     ],
     static_libs: [
         "RadioVtsTestUtilBase",
+        "RadioConfigVtsTestResponse",
         "android.hardware.radio@1.6",
         "android.hardware.radio@1.5",
         "android.hardware.radio@1.4",
@@ -45,8 +46,13 @@
         "android.hardware.radio@1.0",
         "android.hardware.radio.config@1.0",
         "android.hardware.radio.config@1.1",
+        "android.hardware.radio.config@1.2",
+        "android.hardware.radio.config@1.3",
     ],
-    header_libs: ["radio.util.header@1.0"],
+    header_libs: [
+        "radio.util.header@1.0",
+        "radio.config.util.header@1.3",
+    ],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
index 59f7682..6255f66 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -45,35 +45,6 @@
     EXPECT_EQ(CardState::PRESENT, cardStatus.base.base.base.cardState);
 }
 
-/*
- * Notify that the response message is received.
- */
-void RadioHidlTest_v1_6::notify(int receivedSerial) {
-    std::unique_lock<std::mutex> lock(mtx_);
-    if (serial == receivedSerial) {
-        count_++;
-        cv_.notify_one();
-    }
-}
-
-/*
- * Wait till the response message is notified or till TIMEOUT_PERIOD.
- */
-std::cv_status RadioHidlTest_v1_6::wait() {
-    std::unique_lock<std::mutex> lock(mtx_);
-
-    std::cv_status status = std::cv_status::no_timeout;
-    auto now = std::chrono::system_clock::now();
-    while (count_ == 0) {
-        status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
-        if (status == std::cv_status::timeout) {
-            return status;
-        }
-    }
-    count_--;
-    return status;
-}
-
 void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() {
     // Get the current call Id to hangup the established emergency call.
     serial = GetRandomSerialNumber();
@@ -108,3 +79,31 @@
     radio_v1_6->getDataCallList_1_6(serial);
     EXPECT_EQ(std::cv_status::no_timeout, wait());
 }
+
+/**
+ * Specific features on the Radio Hal rely on Radio Hal Capabilities.  The VTS
+ * tests related to that features must not run if the related capability is
+ * disabled.
+ * <p/>
+ * Typical usage within VTS:
+ * if (getRadioHalCapabilities().modemReducedFeatureSet) return;
+ */
+HalDeviceCapabilities RadioHidlTest_v1_6::getRadioHalCapabilities() {
+    sp<::android::hardware::radio::config::V1_3::IRadioConfig> radioConfig_v1_3 =
+            ::android::hardware::radio::config::V1_3::IRadioConfig::getService();
+    if (radioConfig_v1_3.get() == nullptr) {
+        // If v1_3 isn't present, the values are initialized to false
+        HalDeviceCapabilities radioHalCapabilities;
+        memset(&radioHalCapabilities, 0, sizeof(radioHalCapabilities));
+        return radioHalCapabilities;
+    } else {
+        // Get radioHalDeviceCapabilities from the radio config
+        sp<RadioConfigResponse> radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this);
+        radioConfig_v1_3->setResponseFunctions(radioConfigRsp, nullptr);
+        serial = GetRandomSerialNumber();
+
+        radioConfig_v1_3->getHalDeviceCapabilities(serial);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        return radioConfigRsp->halDeviceCapabilities;
+    }
+}
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 f610f2a..23378b5 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
@@ -18,16 +18,12 @@
 
 #include <android-base/logging.h>
 
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/ServiceManagement.h>
-#include <utils/Log.h>
+#include "radio_config_hidl_hal_utils.h"
+
 #include <chrono>
 #include <condition_variable>
 #include <mutex>
 
-#include <android/hardware/radio/config/1.1/IRadioConfig.h>
-
 #include <android/hardware/radio/1.6/IRadio.h>
 #include <android/hardware/radio/1.6/IRadioIndication.h>
 #include <android/hardware/radio/1.6/IRadioResponse.h>
@@ -42,14 +38,15 @@
 using namespace ::android::hardware::radio::V1_2;
 using namespace ::android::hardware::radio::V1_1;
 using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config::V1_3;
 
 using ::android::sp;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities;
 
-#define TIMEOUT_PERIOD 75
 #define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
 #define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
 
@@ -61,7 +58,7 @@
 /* Callback class for radio response v1_6 */
 class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioResponse {
   protected:
-    RadioHidlTest_v1_6& parent_v1_6;
+    RadioResponseWaiter& parent_v1_6;
 
   public:
     hidl_vec<RadioBandMode> radioBandModes;
@@ -105,7 +102,7 @@
     ::android::hardware::radio::V1_5::CellIdentity barringCellIdentity;
     ::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo> barringInfos;
 
-    RadioResponse_v1_6(RadioHidlTest_v1_6& parent_v1_6);
+    RadioResponse_v1_6(RadioResponseWaiter& parent_v1_6);
     virtual ~RadioResponse_v1_6() = default;
 
     Return<void> getIccCardStatusResponse(
@@ -1079,15 +1076,9 @@
 };
 
 // The main test class for Radio HIDL.
-class RadioHidlTest_v1_6 : public ::testing::TestWithParam<std::string> {
+class RadioHidlTest_v1_6 : public ::testing::TestWithParam<std::string>,
+                           public RadioResponseWaiter {
   protected:
-    std::mutex mtx_;
-    std::condition_variable cv_;
-    int count_;
-
-    /* Serial number for radio request */
-    int serial;
-
     /* Clear Potential Established Calls */
     void clearPotentialEstablishedCalls();
 
@@ -1100,11 +1091,7 @@
   public:
     virtual void SetUp() override;
 
-    /* Used as a mechanism to inform the test about data/event callback */
-    void notify(int receivedSerial);
-
-    /* Test code calls this function to wait for response */
-    std::cv_status wait();
+    HalDeviceCapabilities getRadioHalCapabilities();
 
     /* radio service handle */
     sp<::android::hardware::radio::V1_6::IRadio> radio_v1_6;
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index d9da40a..8034fd2 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -18,7 +18,7 @@
 
 ::android::hardware::radio::V1_5::CardStatus cardStatus;
 
-RadioResponse_v1_6::RadioResponse_v1_6(RadioHidlTest_v1_6& parent) : parent_v1_6(parent) {}
+RadioResponse_v1_6::RadioResponse_v1_6(RadioResponseWaiter& parent) : parent_v1_6(parent) {}
 
 /* 1.0 Apis */
 Return<void> RadioResponse_v1_6::getIccCardStatusResponse(
diff --git a/radio/config/1.3/vts/functional/Android.bp b/radio/config/1.3/vts/functional/Android.bp
index aa3522d..20c480f 100644
--- a/radio/config/1.3/vts/functional/Android.bp
+++ b/radio/config/1.3/vts/functional/Android.bp
@@ -46,3 +46,26 @@
         "vts",
     ],
 }
+
+cc_library_static {
+    name: "RadioConfigVtsTestResponse",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs : [
+        "radio_config_response.cpp",
+        "radio_config_hidl_hal_test.cpp",
+    ],
+    header_libs: ["radio.util.header@1.0"],
+    static_libs: ["RadioVtsTestUtilBase"],
+    shared_libs: [
+        "android.hardware.radio@1.0",
+        "android.hardware.radio.config@1.0",
+        "android.hardware.radio.config@1.1",
+        "android.hardware.radio.config@1.2",
+        "android.hardware.radio.config@1.3",
+    ],
+}
+
+cc_library_headers {
+    name: "radio.config.util.header@1.3",
+    export_include_dirs: ["."],
+}
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
index de8365a..da61464 100644
--- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
@@ -31,32 +31,3 @@
 
     radioConfig->setResponseFunctions(radioConfigRsp, nullptr);
 }
-
-/*
- * Notify that the response message is received.
- */
-void RadioConfigHidlTest::notify(int receivedSerial) {
-    std::unique_lock<std::mutex> lock(mtx_);
-    if (serial == receivedSerial) {
-        count_++;
-        cv_.notify_one();
-    }
-}
-
-/*
- * Wait till the response message is notified or till TIMEOUT_PERIOD.
- */
-std::cv_status RadioConfigHidlTest::wait() {
-    std::unique_lock<std::mutex> lock(mtx_);
-
-    std::cv_status status = std::cv_status::no_timeout;
-    auto now = std::chrono::system_clock::now();
-    while (count_ == 0) {
-        status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
-        if (status == std::cv_status::timeout) {
-            return status;
-        }
-    }
-    count_--;
-    return status;
-}
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
index 439eb70..895ae08 100644
--- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#pragma once
+
 #include <android-base/logging.h>
 
 #include <chrono>
@@ -49,7 +51,6 @@
 using ::android::hardware::radio::config::V1_3::IRadioConfig;
 using ::android::hardware::radio::V1_0::RadioResponseInfo;
 
-#define TIMEOUT_PERIOD 75
 #define RADIO_SERVICE_NAME "slot1"
 
 class RadioConfigHidlTest;
@@ -57,13 +58,14 @@
 /* Callback class for radio config response */
 class RadioConfigResponse : public IRadioConfigResponse {
   protected:
-    RadioConfigHidlTest& parent;
+    RadioResponseWaiter& parent;
 
   public:
     RadioResponseInfo rspInfo;
     PhoneCapability phoneCap;
+    HalDeviceCapabilities halDeviceCapabilities;
 
-    RadioConfigResponse(RadioConfigHidlTest& parent);
+    RadioConfigResponse(RadioResponseWaiter& parent);
     virtual ~RadioConfigResponse() = default;
 
     Return<void> getSimSlotsStatusResponse(
@@ -107,26 +109,13 @@
 };
 
 // The main test class for Radio config HIDL.
-class RadioConfigHidlTest : public ::testing::TestWithParam<std::string> {
-  protected:
-    std::mutex mtx_;
-    std::condition_variable cv_;
-    int count_;
-
+class RadioConfigHidlTest : public ::testing::TestWithParam<std::string>,
+                            public RadioResponseWaiter {
   public:
     virtual void SetUp() override;
 
-    /* Used as a mechanism to inform the test about data/event callback */
-    void notify(int receivedSerial);
-
-    /* Test code calls this function to wait for response */
-    std::cv_status wait();
-
     void updateSimCardStatus();
 
-    /* Serial number for radio request */
-    int serial;
-
     /* radio config service handle */
     sp<IRadioConfig> radioConfig;
 
diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp
index 2a8b28b..11e3cce 100644
--- a/radio/config/1.3/vts/functional/radio_config_response.cpp
+++ b/radio/config/1.3/vts/functional/radio_config_response.cpp
@@ -18,7 +18,7 @@
 
 // SimSlotStatus slotStatus;
 
-RadioConfigResponse::RadioConfigResponse(RadioConfigHidlTest& parent) : parent(parent) {}
+RadioConfigResponse::RadioConfigResponse(RadioResponseWaiter& parent) : parent(parent) {}
 
 Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
         const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */,
@@ -65,6 +65,7 @@
 
 Return<void> RadioConfigResponse::getHalDeviceCapabilitiesResponse(
         const ::android::hardware::radio::V1_6::RadioResponseInfo& /* info */,
-        const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& /* capabilities */) {
+        const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& capabilities) {
+    halDeviceCapabilities = capabilities;
     return Void();
-}
\ No newline at end of file
+}
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/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 6d42db2..384416e 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -760,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/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/vts/functional/KeyMintAidlTestBase.h b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
index e79fe80..0aef81b 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.h
@@ -261,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 f8eca6b..7ecfa37 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -4633,7 +4633,7 @@
 
 INSTANTIATE_KEYMINT_AIDL_TEST(KeyAgreementTest);
 
-typedef KeyMintAidlTestBase EarlyBootKeyTest;
+using EarlyBootKeyTest = KeyMintAidlTestBase;
 
 TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) {
     auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
@@ -4690,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
@@ -4724,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/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index aec1fd0..5ddac99 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -259,11 +259,14 @@
     int av_fd = createAvIonFd(BUFFER_SIZE_16M);
     if (av_fd == -1) {
         _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0);
+        return Void();
     }
 
     native_handle_t* nativeHandle = createNativeHandle(av_fd);
     if (nativeHandle == NULL) {
+        ::close(av_fd);
         _hidl_cb(Result::UNKNOWN_ERROR, NULL, 0);
+        return Void();
     }
     mSharedAvMemHandle.setTo(nativeHandle, /*shouldOwn=*/true);
     ::close(av_fd);
diff --git a/vibrator/aidl/Android.bp b/vibrator/aidl/Android.bp
index 9bad971..4363407 100644
--- a/vibrator/aidl/Android.bp
+++ b/vibrator/aidl/Android.bp
@@ -16,7 +16,7 @@
     stability: "vintf",
     backend: {
         java: {
-            platform_apis: true,
+            sdk_version: "module_current",
         },
         ndk: {
             vndk: {
diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal
index 3a5560b..e1c0d32 100644
--- a/wifi/1.5/types.hal
+++ b/wifi/1.5/types.hal
@@ -142,23 +142,23 @@
      * Data packet min contention time (usec).  It includes both the internal contention time
      * among different access categories within the chipset and the contention time for the medium.
      */
-    uint64_t contentionTimeMinInUsec;
+    uint32_t contentionTimeMinInUsec;
 
     /**
      * Data packet max contention time (usec).  It includes both the internal contention time
      * among different access categories within the chipset and the contention time for the medium.
      */
-    uint64_t contentionTimeMaxInUsec;
+    uint32_t contentionTimeMaxInUsec;
     /**
      * Data packet average contention time (usec).  It includes both the internal contention time
      * among different access categories within the chipset and the contention time for the medium.
      */
-    uint64_t contentionTimeAvgInUsec;
+    uint32_t contentionTimeAvgInUsec;
 
     /**
      * Number of data packets used for contention statistics.
      */
-    uint64_t contentionNumSamples;
+    uint32_t contentionNumSamples;
 };
 
 /**
diff --git a/wifi/supplicant/1.4/types.hal b/wifi/supplicant/1.4/types.hal
index aec61c4..c39de6e 100644
--- a/wifi/supplicant/1.4/types.hal
+++ b/wifi/supplicant/1.4/types.hal
@@ -104,6 +104,7 @@
  */
 enum WpaDriverCapabilitiesMask : @1.3::WpaDriverCapabilitiesMask {
     /**
+     * WPA3 SAE Public-Key.
      */
     SAE_PK = 1 << 2,
 };