Merge "Add the information if the assistance is not available." into main
diff --git a/audio/effect/all-versions/default/Android.bp b/audio/effect/all-versions/default/Android.bp
index cea085c..095bb86 100644
--- a/audio/effect/all-versions/default/Android.bp
+++ b/audio/effect/all-versions/default/Android.bp
@@ -52,6 +52,12 @@
         "libmedia_headers",
         "libmediautils_headers",
     ],
+
+    cflags: [
+        "-Wall",
+        "-Wthread-safety",
+        "-Werror",
+    ],
 }
 
 cc_library_shared {
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index 4a9e144..9896653 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -321,8 +321,8 @@
         status_t status = mProcessThread->join();
         ALOGE_IF(status, "processing thread exit error: %s", strerror(-status));
     }
-    if (mEfGroup) {
-        status_t status = EventFlag::deleteEventFlag(&mEfGroup);
+    if (EventFlag* evFlag = mEfGroup.load(std::memory_order_acquire)) {
+        status_t status = EventFlag::deleteEventFlag(&evFlag);
         ALOGE_IF(status, "processing MQ event flag deletion error: %s", strerror(-status));
     }
     mInBuffer.clear();
@@ -437,6 +437,7 @@
 Result Effect::analyzeStatus(const char* funcName, const char* subFuncName,
                              const char* contextDescription, status_t status) {
     if (status != OK) {
+        std::lock_guard<std::mutex> lock(mLock);
         ALOGW("Effect %p %s %s %s: %s", mHandle, funcName, subFuncName, contextDescription,
               strerror(-status));
     }
@@ -470,11 +471,14 @@
 
 Return<void> Effect::getConfigImpl(int commandCode, const char* commandName,
                                    GetConfigCallback _hidl_cb) {
-    RETURN_RESULT_IF_EFFECT_CLOSED(EffectConfig());
     uint32_t halResultSize = sizeof(effect_config_t);
     effect_config_t halConfig{};
-    status_t status =
-        (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig);
+    status_t status = OK;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_RESULT_IF_EFFECT_CLOSED(EffectConfig());
+        status = (*mHandle)->command(mHandle, commandCode, 0, NULL, &halResultSize, &halConfig);
+    }
     EffectConfig config;
     if (status == OK) {
         status = EffectUtils::effectConfigFromHal(halConfig, mIsInput, &config);
@@ -542,7 +546,10 @@
 }
 
 Return<void> Effect::prepareForProcessing(prepareForProcessing_cb _hidl_cb) {
-    RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor());
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor());
+    }
     status_t status;
     // Create message queue.
     if (mStatusMQ) {
@@ -556,16 +563,21 @@
         _hidl_cb(Result::INVALID_ARGUMENTS, StatusMQ::Descriptor());
         return Void();
     }
-    status = EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &mEfGroup);
-    if (status != OK || !mEfGroup) {
+    EventFlag* evFlag = nullptr;
+    status = EventFlag::createEventFlag(tempStatusMQ->getEventFlagWord(), &evFlag);
+    if (status != OK || !evFlag) {
         ALOGE("failed creating event flag for status MQ: %s", strerror(-status));
         _hidl_cb(Result::INVALID_ARGUMENTS, StatusMQ::Descriptor());
         return Void();
     }
+    mEfGroup.store(evFlag, std::memory_order_release);
 
-    // Create and launch the thread.
-    mProcessThread = new ProcessThread(&mStopProcessThread, mHandle, &mHalInBufferPtr,
-                                       &mHalOutBufferPtr, tempStatusMQ.get(), mEfGroup, this);
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        // Create and launch the thread.
+        mProcessThread = new ProcessThread(&mStopProcessThread, mHandle, &mHalInBufferPtr,
+                                           &mHalOutBufferPtr, tempStatusMQ.get(), evFlag, this);
+    }
     status = mProcessThread->run("effect", PRIORITY_URGENT_AUDIO);
     if (status != OK) {
         ALOGW("failed to start effect processing thread: %s", strerror(-status));
@@ -575,11 +587,15 @@
 
     // For a spatializer effect, we perform scheduler adjustments to reduce glitches and power.
     // We do it here instead of the ProcessThread::threadLoop to ensure that mHandle is valid.
-    if (effect_descriptor_t halDescriptor{};
-        (*mHandle)->get_descriptor(mHandle, &halDescriptor) == NO_ERROR &&
-        memcmp(&halDescriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) {
-        const status_t status = scheduler::updateSpatializerPriority(mProcessThread->getTid());
-        ALOGW_IF(status != OK, "Failed to update Spatializer priority");
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_RESULT_IF_EFFECT_CLOSED(StatusMQ::Descriptor());
+        if (effect_descriptor_t halDescriptor{};
+            (*mHandle)->get_descriptor(mHandle, &halDescriptor) == NO_ERROR &&
+            memcmp(&halDescriptor.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0) {
+            const status_t status = scheduler::updateSpatializerPriority(mProcessThread->getTid());
+            ALOGW_IF(status != OK, "Failed to update Spatializer priority");
+        }
     }
 
     mStatusMQ = std::move(tempStatusMQ);
@@ -589,7 +605,10 @@
 
 Return<Result> Effect::setProcessBuffers(const AudioBuffer& inBuffer,
                                          const AudioBuffer& outBuffer) {
-    RETURN_IF_EFFECT_CLOSED();
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_IF_EFFECT_CLOSED();
+    }
     AudioBufferManager& manager = AudioBufferManager::getInstance();
     sp<AudioBufferWrapper> tempInBuffer, tempOutBuffer;
     if (!manager.wrap(inBuffer, &tempInBuffer)) {
@@ -614,8 +633,12 @@
 }
 
 Result Effect::sendCommand(int commandCode, const char* commandName, uint32_t size, void* data) {
-    RETURN_IF_EFFECT_CLOSED();
-    status_t status = (*mHandle)->command(mHandle, commandCode, size, data, 0, NULL);
+    status_t status = OK;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_IF_EFFECT_CLOSED();
+        status = (*mHandle)->command(mHandle, commandCode, size, data, 0, NULL);
+    }
     return analyzeCommandStatus(commandName, sContextCallToCommand, status);
 }
 
@@ -626,9 +649,13 @@
 
 Result Effect::sendCommandReturningData(int commandCode, const char* commandName, uint32_t size,
                                         void* data, uint32_t* replySize, void* replyData) {
-    RETURN_IF_EFFECT_CLOSED();
     uint32_t expectedReplySize = *replySize;
-    status_t status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData);
+    status_t status = OK;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_IF_EFFECT_CLOSED();
+        status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData);
+    }
     if (status == OK && *replySize != expectedReplySize) {
         status = -ENODATA;
     }
@@ -651,8 +678,12 @@
                                                  uint32_t size, void* data, uint32_t* replySize,
                                                  void* replyData, uint32_t minReplySize,
                                                  CommandSuccessCallback onSuccess) {
-    RETURN_IF_EFFECT_CLOSED();
-    status_t status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData);
+    status_t status = OK;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_IF_EFFECT_CLOSED();
+        status = (*mHandle)->command(mHandle, commandCode, size, data, replySize, replyData);
+    }
     Result retval;
     if (status == OK && minReplySize >= sizeof(uint32_t) && *replySize >= minReplySize) {
         uint32_t commandStatus = *reinterpret_cast<uint32_t*>(replyData);
@@ -860,10 +891,14 @@
 }
 
 Return<void> Effect::getDescriptor(getDescriptor_cb _hidl_cb) {
-    RETURN_RESULT_IF_EFFECT_CLOSED(EffectDescriptor());
     effect_descriptor_t halDescriptor;
     memset(&halDescriptor, 0, sizeof(effect_descriptor_t));
-    status_t status = (*mHandle)->get_descriptor(mHandle, &halDescriptor);
+    status_t status = OK;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_RESULT_IF_EFFECT_CLOSED(EffectDescriptor());
+        status = (*mHandle)->get_descriptor(mHandle, &halDescriptor);
+    }
     EffectDescriptor descriptor;
     if (status == OK) {
         status = EffectUtils::effectDescriptorFromHal(halDescriptor, &descriptor);
@@ -874,10 +909,6 @@
 
 Return<void> Effect::command(uint32_t commandId, const hidl_vec<uint8_t>& data,
                              uint32_t resultMaxSize, command_cb _hidl_cb) {
-    if (mHandle == kInvalidEffectHandle) {
-        _hidl_cb(-ENODATA, hidl_vec<uint8_t>());
-        return Void();
-    }
     uint32_t halDataSize;
     std::unique_ptr<uint8_t[]> halData = hidlVecToHal(data, &halDataSize);
     uint32_t halResultSize = resultMaxSize;
@@ -897,8 +928,15 @@
             }
             [[fallthrough]];  // allow 'gtid' overload (checked halDataSize and resultMaxSize).
         default:
-            status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr, &halResultSize,
-                                         resultPtr);
+            {
+                std::lock_guard<std::mutex> lock(mLock);
+                if (mHandle == kInvalidEffectHandle) {
+                    _hidl_cb(-ENODATA, hidl_vec<uint8_t>());
+                    return Void();
+                }
+                status = (*mHandle)->command(mHandle, commandId, halDataSize, dataPtr,
+                                            &halResultSize, resultPtr);
+            }
             break;
     }
     hidl_vec<uint8_t> result;
@@ -967,11 +1005,17 @@
         return {Result::INVALID_STATE, kInvalidEffectHandle};
     }
     mStopProcessThread.store(true, std::memory_order_release);
-    if (mEfGroup) {
-        mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::REQUEST_QUIT));
+    EventFlag* evFlag = mEfGroup.load(std::memory_order_acquire);
+    if (evFlag) {
+        evFlag->wake(static_cast<uint32_t>(
+            MessageQueueFlagBits::REQUEST_QUIT));
     }
-    effect_handle_t handle = mHandle;
-    mHandle = kInvalidEffectHandle;
+    effect_handle_t handle;
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        handle = mHandle;
+        mHandle = kInvalidEffectHandle;
+    }
 #if MAJOR_VERSION <= 5
     return {Result::OK, handle};
 #elif MAJOR_VERSION >= 6
@@ -984,7 +1028,10 @@
 }
 
 Return<Result> Effect::close() {
-    RETURN_IF_EFFECT_CLOSED();
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        RETURN_IF_EFFECT_CLOSED();
+    }
     auto [result, _] = closeImpl();
     return result;
 }
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index 2bcecec..cc76784 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -25,6 +25,7 @@
 #include <memory>
 #include <tuple>
 #include <vector>
+#include <mutex>
 
 #include <fmq/EventFlag.h>
 #include <fmq/MessageQueue.h>
@@ -194,13 +195,14 @@
     static const char* sContextCallFunction;
 
     const bool mIsInput;
-    effect_handle_t mHandle;
+    std::mutex mLock;
+    effect_handle_t mHandle GUARDED_BY(mLock);
     sp<AudioBufferWrapper> mInBuffer;
     sp<AudioBufferWrapper> mOutBuffer;
     std::atomic<audio_buffer_t*> mHalInBufferPtr;
     std::atomic<audio_buffer_t*> mHalOutBufferPtr;
     std::unique_ptr<StatusMQ> mStatusMQ;
-    EventFlag* mEfGroup;
+    std::atomic<EventFlag*> mEfGroup;
     std::atomic<bool> mStopProcessThread;
     sp<Thread> mProcessThread;
 
diff --git a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
index 53e5e99..92681de 100644
--- a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
+++ b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
@@ -1339,7 +1339,7 @@
             {
                 "name": "EV_CHARGE_CURRENT_DRAW_LIMIT",
                 "value": 291508031,
-                "description": "Indicates the maximum current draw threshold for charging set by the user\nconfigArray[0] is used to specify the max current draw allowed by the vehicle in Amperes at boot time.\nIf {@code HasSupportedValueInfo} for the global area ID (0) is not {@code null}, {@code HasSupportedValueInfo#hasMaxSupportedValue} and {@code HasSupportedValueInfo#hasMinSupportedValue} must be {@code true}. {@code MinMaxSupportedValueResult#maxSupportedValue} specifies the max current draw allowed by the vehicle in Amperes at the current moment. {@code MinMaxSupportedValueResult#minSupportedValue} must be 0. At boot, configArray[0] is equal to maxSupportedValue.\nIf the max current draw allowed by the vehicle may change dynamically, {@code HasSupportedValueInfo#hasMaxSupportedValue} must be {@code true} and {@code MinMaxSupportedValueResult#maxSupportedValue} must be implemented.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
+                "description": "The vehicle's selected alternating current (AC) EV charging draw limit in Amperes.\nconfigArray[0] is used to specify the max current draw allowed by the vehicle in Amperes at boot time.\nIf {@code HasSupportedValueInfo} for the global area ID (0) is not {@code null}, {@code HasSupportedValueInfo#hasMaxSupportedValue} and {@code HasSupportedValueInfo#hasMinSupportedValue} must be {@code true}. {@code MinMaxSupportedValueResult#maxSupportedValue} specifies the max current draw allowed by the vehicle in Amperes at the current moment. {@code MinMaxSupportedValueResult#minSupportedValue} must be 0. At boot, configArray[0] is equal to maxSupportedValue.\nIf the max current draw allowed by the vehicle may change dynamically, {@code HasSupportedValueInfo#hasMaxSupportedValue} must be {@code true} and {@code MinMaxSupportedValueResult#maxSupportedValue} must be implemented.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EV_CHARGE_PERCENT_LIMIT",
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index a7ecb36..2f1b277 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -6156,7 +6156,7 @@
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
 
     /**
-     * Indicates the maximum current draw threshold for charging set by the user
+     * The vehicle's selected alternating current (AC) EV charging draw limit in Amperes.
      *
      * configArray[0] is used to specify the max current draw allowed by the vehicle in Amperes at
      * boot time.
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index d4b0528..7f5e06d 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -96,6 +96,10 @@
 static constexpr char ANNOTATION_SUPPORTED_VALUES_IN_CONFIG[] = "legacy_supported_values_in_config";
 static constexpr char ANNOTATIONS_DATA_ENUM[] = "data_enum";
 
+inline VehiclePropertyType getPropertyType(int32_t propId) {
+    return static_cast<VehiclePropertyType>(propId & toInt(VehiclePropertyType::MASK));
+}
+
 struct ServiceDescriptor {
     std::string name;
     bool isAidlService;
@@ -181,10 +185,12 @@
     void testGetMinMaxSupportedValueForPropIdAreaId(int32_t propId,
                                                     const IHalAreaConfig& areaConfig,
                                                     bool minMaxValueRequired);
+    void testGetSupportedValuesListsForPropIdAreaId(int32_t propId,
+                                                    const IHalAreaConfig& areaConfig,
+                                                    bool supportedValuesRequired);
 
     static bool isBooleanGlobalProp(int32_t property) {
-        return (property & toInt(VehiclePropertyType::MASK)) ==
-                       toInt(VehiclePropertyType::BOOLEAN) &&
+        return getPropertyType(property) == VehiclePropertyType::BOOLEAN &&
                (property & toInt(VehicleArea::MASK)) == toInt(VehicleArea::GLOBAL);
     }
 
@@ -810,39 +816,36 @@
     }
 }
 
-void verifyRawPropValues(const RawPropValues& rawPropValues, int32_t propertyType) {
+void verifyRawPropValues(const RawPropValues& rawPropValues, VehiclePropertyType propertyType) {
     switch (propertyType) {
-        case toInt(VehiclePropertyType::INT32):
+        case VehiclePropertyType::INT32:
             ASSERT_THAT(rawPropValues.int32Values, ::testing::SizeIs(1))
                     << "int32Values field must contain exactly one element for INT32 type";
             break;
-        case toInt(VehiclePropertyType::FLOAT):
+        case VehiclePropertyType::FLOAT:
             ASSERT_THAT(rawPropValues.floatValues, ::testing::SizeIs(1))
                     << "floatValues field must contain exactly one element for FLOAT type";
             break;
-        case toInt(VehiclePropertyType::INT64):
+        case VehiclePropertyType::INT64:
             ASSERT_THAT(rawPropValues.int64Values, ::testing::SizeIs(1))
                     << "int64Values field must contain exactly one element for INT64 type";
             break;
         default:
-            // This must not happen since we already checked this condition in
-            // verifyPropertyConfigMinMaxValue
-            FAIL() << "minSupportedValue or maxSupportedValue must only be specified for "
-                      "INT32, INT64 or FLOAT type property";
+            // We do not check for other types.
             break;
     }
 }
 
 void VtsHalAutomotiveTest::testGetMinMaxSupportedValueForPropIdAreaId(
         int32_t propId, const IHalAreaConfig& areaConfig, bool minMaxValueRequired) {
-    int areaId = areaConfig.getAreaId();
-    int propertyType = propId & toInt(VehiclePropertyType::MASK);
+    int32_t areaId = areaConfig.getAreaId();
+    VehiclePropertyType propertyType = getPropertyType(propId);
     std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
             areaConfig.getHasSupportedValueInfo();
     if (!maybeHasSupportedValueInfo.has_value()) {
         return;
     }
-    if (!maybeHasSupportedValueInfo->hasMaxSupportedValue &&
+    if (!maybeHasSupportedValueInfo->hasMinSupportedValue &&
         !maybeHasSupportedValueInfo->hasMaxSupportedValue) {
         return;
     }
@@ -859,8 +862,7 @@
     const MinMaxSupportedValueResult& individualResult = (*result)[0];
     if (minMaxValueRequired) {
         ASSERT_EQ(individualResult.status, StatusCode::OK)
-                << "getMinMaxSupportedValue must return okay status if min/max value is required "
-                   "for";
+                << "getMinMaxSupportedValue must return okay status if min/max value is required";
     }
     if (individualResult.status != StatusCode::OK) {
         return;
@@ -895,19 +897,19 @@
         int64_t minInt64Value;
         int64_t maxInt64Value;
         switch (propertyType) {
-            case toInt(VehiclePropertyType::INT32):
+            case VehiclePropertyType::INT32:
                 minInt32Value = (individualResult.minSupportedValue)->int32Values[0];
                 maxInt32Value = (individualResult.maxSupportedValue)->int32Values[0];
                 ASSERT_LE(minInt32Value, maxInt32Value)
                         << "minSupportedValue must be less or equal to maxSupportedValue";
                 break;
-            case toInt(VehiclePropertyType::FLOAT):
+            case VehiclePropertyType::FLOAT:
                 minFloatValue = (individualResult.minSupportedValue)->floatValues[0];
                 maxFloatValue = (individualResult.maxSupportedValue)->floatValues[0];
                 ASSERT_LE(minFloatValue, maxFloatValue)
                         << "minSupportedValue must be less or equal to maxSupportedValue";
                 break;
-            case toInt(VehiclePropertyType::INT64):
+            case VehiclePropertyType::INT64:
                 minInt64Value = (individualResult.minSupportedValue)->int64Values[0];
                 maxInt64Value = (individualResult.maxSupportedValue)->int64Values[0];
                 ASSERT_LE(minInt64Value, maxInt64Value)
@@ -923,12 +925,12 @@
     }
 }
 
-// Test the getMinMaxSupportedValues API. We use this one test case to cover all properties that
+// Test the getMinMaxSupportedValue API. We use this one test case to cover all properties that
 // may support this API.
 TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetMinMaxSupportedValue) {
     if (!mVhalClient->isAidlVhal() || mVhalClient->getRemoteInterfaceVersion() < 4) {
-        GTEST_SKIP() << "Skip checking testGetMinMaxSupportedValues the behavior is not supported "
-                        "for current VHAL version";
+        GTEST_SKIP() << "Skip checking getMinMaxSupportedValue because the behavior is not "
+                        "supported for current VHAL version";
     }
 
     auto configsResult = mVhalClient->getAllPropConfigs();
@@ -956,12 +958,93 @@
     }
 }
 
-void verifyPropertyConfigMinMaxValue(const IHalPropConfig* config, int32_t propertyType) {
+void VtsHalAutomotiveTest::testGetSupportedValuesListsForPropIdAreaId(
+        int32_t propId, const IHalAreaConfig& areaConfig, bool supportedValuesRequired) {
+    int32_t areaId = areaConfig.getAreaId();
+    VehiclePropertyType propertyType = getPropertyType(propId);
+    std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
+            areaConfig.getHasSupportedValueInfo();
+    if (!maybeHasSupportedValueInfo.has_value()) {
+        return;
+    }
+    if (!maybeHasSupportedValueInfo->hasSupportedValuesList) {
+        return;
+    }
+    VhalClientResult<std::vector<SupportedValuesListResult>> result =
+            mVhalClient->getSupportedValuesLists({PropIdAreaId{
+                    .propId = propId,
+                    .areaId = areaId,
+            }});
+    ASSERT_RESULT_OK(result)
+            << "getSupportedValuesLists must return okay result if hasSupportedValuesList is true";
+    ASSERT_THAT(*result, ::testing::SizeIs(1))
+            << "getSupportedValuesLists result list size must be 1 for 1 request";
+    const SupportedValuesListResult& individualResult = (*result)[0];
+    if (supportedValuesRequired) {
+        ASSERT_EQ(individualResult.status, StatusCode::OK)
+                << "getSupportedValuesLists must return okay status if supported values are "
+                   "required";
+    }
+    if (individualResult.status != StatusCode::OK) {
+        return;
+    }
+    ASSERT_TRUE(individualResult.supportedValuesList.has_value())
+            << "supportedValuesList field must not be null if hasSupportedValuesList is true";
+    const std::vector<std::optional<RawPropValues>>& supportedValuesList =
+            individualResult.supportedValuesList.value();
+    if (supportedValuesRequired) {
+        ASSERT_THAT(supportedValuesList, ::testing::Not(::testing::IsEmpty()))
+                << "supportedValuesList must not be empty if supported values are required";
+    }
+    for (const std::optional<RawPropValues>& supportedValue : supportedValuesList) {
+        ASSERT_TRUE(supportedValue.has_value())
+                << "Each item in supportedValuesList must not be null";
+        ASSERT_NO_FATAL_FAILURE(verifyRawPropValues(*supportedValue, propertyType))
+                << "one of supported value is not a valid RawPropValues for "
+                << "the property type, value: " << supportedValue->toString();
+    }
+}
+
+// Test the getSupportedValues API. We use this one test case to cover all properties that
+// may support this API.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, testGetSupportedValuesLists) {
+    if (!mVhalClient->isAidlVhal() || mVhalClient->getRemoteInterfaceVersion() < 4) {
+        GTEST_SKIP() << "Skip checking getSupportedValuesLists because the behavior is not "
+                        "supported for current VHAL version";
+    }
+
+    auto configsResult = mVhalClient->getAllPropConfigs();
+    ASSERT_TRUE(configsResult.ok())
+            << "Failed to get all property configs, error: " << configsResult.error().message();
+
+    for (const auto& cfgPtr : configsResult.value()) {
+        int32_t propId = cfgPtr->getPropId();
+        bool supportedValuesRequired = false;
+        std::unordered_set<std::string> annotations;
+        auto it = AnnotationsForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+        if (it != AnnotationsForVehicleProperty.end()) {
+            annotations = it->second;
+        }
+        if (annotations.find(ANNOTATION_REQUIRE_SUPPORTED_VALUES) != annotations.end()) {
+            supportedValuesRequired = true;
+        }
+        const std::vector<std::unique_ptr<IHalAreaConfig>>& areaConfigs = cfgPtr->getAreaConfigs();
+        for (const auto& areaCfgPtr : areaConfigs) {
+            EXPECT_NO_FATAL_FAILURE(testGetSupportedValuesListsForPropIdAreaId(
+                    propId, *areaCfgPtr, supportedValuesRequired))
+                    << "test getSupportedValues failed for property: " << propIdToString(propId)
+                    << ", areaId: " << areaCfgPtr->getAreaId();
+        }
+    }
+}
+
+void verifyPropertyConfigMinMaxValue(const IHalPropConfig* config,
+                                     VehiclePropertyType propertyType) {
     for (const auto& areaConfig : config->getAreaConfigs()) {
         std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
                 areaConfig->getHasSupportedValueInfo();
         if (areaConfig->getMinInt32Value() != 0 || areaConfig->getMaxInt32Value() != 0) {
-            EXPECT_EQ(propertyType, toInt(VehiclePropertyType::INT32))
+            EXPECT_EQ(propertyType, VehiclePropertyType::INT32)
                     << "minInt32Value and maxInt32Value must not be specified for INT32 type "
                        "property";
             EXPECT_THAT(areaConfig->getMinInt32Value(),
@@ -977,7 +1060,7 @@
             }
         }
         if (areaConfig->getMinFloatValue() != 0 || areaConfig->getMaxFloatValue() != 0) {
-            EXPECT_EQ(propertyType, toInt(VehiclePropertyType::FLOAT))
+            EXPECT_EQ(propertyType, VehiclePropertyType::FLOAT)
                     << "minFloatValue and maxFloatValue must not be specified for FLOAT type "
                        "property";
             EXPECT_THAT(areaConfig->getMinFloatValue(),
@@ -993,7 +1076,7 @@
             }
         }
         if (areaConfig->getMinInt64Value() != 0 || areaConfig->getMaxInt64Value() != 0) {
-            EXPECT_EQ(propertyType, toInt(VehiclePropertyType::INT64))
+            EXPECT_EQ(propertyType, VehiclePropertyType::INT64)
                     << "minInt64Value and maxInt64Value must not be specified for INT64 type "
                        "property";
             EXPECT_THAT(areaConfig->getMinInt64Value(),
@@ -1011,9 +1094,9 @@
         if (maybeHasSupportedValueInfo.has_value() &&
             (maybeHasSupportedValueInfo->hasMinSupportedValue ||
              maybeHasSupportedValueInfo->hasMaxSupportedValue)) {
-            EXPECT_THAT(propertyType, ::testing::AnyOf(toInt(VehiclePropertyType::INT32),
-                                                       toInt(VehiclePropertyType::INT64),
-                                                       toInt(VehiclePropertyType::FLOAT)))
+            EXPECT_THAT(propertyType,
+                        ::testing::AnyOf(VehiclePropertyType::INT32, VehiclePropertyType::INT64,
+                                         VehiclePropertyType::FLOAT))
                     << "HasSupportedValueInfo.hasMinSupportedValue and "
                        "HasSupportedValueInfo.hasMaxSupportedValue is only allowed to be set to "
                        "true "
@@ -1022,27 +1105,31 @@
     }
 }
 
-void verifyPropertyConfigRequireMinMaxValue(const IHalPropConfig* config, int propertyType) {
+void verifyPropertyConfigRequireMinMaxValue(const IHalPropConfig* config,
+                                            VehiclePropertyType propertyType) {
     for (const auto& areaConfig : config->getAreaConfigs()) {
         switch (propertyType) {
-            case toInt(VehiclePropertyType::INT32):
+            case VehiclePropertyType::INT32:
                 EXPECT_FALSE(areaConfig->getMinInt32Value() == 0 &&
                              areaConfig->getMaxInt32Value() == 0)
                         << "minInt32Value and maxInt32Value must not both be 0 because "
                            "min and max value is required for this property";
                 break;
-            case toInt(VehiclePropertyType::FLOAT):
+            case VehiclePropertyType::FLOAT:
                 EXPECT_FALSE(areaConfig->getMinFloatValue() == 0 &&
                              areaConfig->getMaxFloatValue() == 0)
                         << "minFloatValue and maxFloatValue must not both be 0 because "
                            "min and max value is required for this property";
                 break;
-            case toInt(VehiclePropertyType::INT64):
+            case VehiclePropertyType::INT64:
                 EXPECT_FALSE(areaConfig->getMinInt64Value() == 0 &&
                              areaConfig->getMaxInt64Value() == 0)
                         << "minInt64Value and maxInt64Value must not both be 0 because "
                            "min and max value is required for this property";
                 break;
+            default:
+                // Do nothing.
+                break;
         }
 
         std::optional<HasSupportedValueInfo> maybeHasSupportedValueInfo =
@@ -1171,7 +1258,7 @@
         annotations = it->second;
     }
 
-    int propertyType = expectedPropId & toInt(VehiclePropertyType::MASK);
+    VehiclePropertyType propertyType = getPropertyType(expectedPropId);
     verifyPropertyConfigMinMaxValue(config.get(), propertyType);
     if (annotations.find(ANNOTATION_REQUIRE_MIN_MAX_VALUE) != annotations.end()) {
         verifyPropertyConfigRequireMinMaxValue(config.get(), propertyType);
@@ -1215,6 +1302,7 @@
 }
 
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotiveVehicleTargetTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VtsHalAutomotivePropertyConfigTest);
 
 INSTANTIATE_TEST_SUITE_P(PerInstance, VtsHalAutomotiveVehicleTargetTest,
                          testing::ValuesIn(getDescriptors()),
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
index 3f1f5f6..3d7c376 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.cpp
@@ -123,40 +123,6 @@
   return (sessionType == session_type_);
 }
 
-std::string getSettingOutputString(
-    IBluetoothAudioProvider::LeAudioAseConfigurationSetting& setting) {
-  std::stringstream ss;
-  std::string name = "";
-  if (!setting.sinkAseConfiguration.has_value() &&
-      !setting.sourceAseConfiguration.has_value())
-    return "";
-  std::vector<
-      std::optional<LeAudioAseConfigurationSetting::AseDirectionConfiguration>>*
-      directionAseConfiguration;
-  if (setting.sinkAseConfiguration.has_value() &&
-      !setting.sinkAseConfiguration.value().empty())
-    directionAseConfiguration = &setting.sinkAseConfiguration.value();
-  else
-    directionAseConfiguration = &setting.sourceAseConfiguration.value();
-  for (auto& aseConfiguration : *directionAseConfiguration) {
-    if (aseConfiguration.has_value() &&
-        aseConfiguration.value().aseConfiguration.metadata.has_value()) {
-      for (auto& meta :
-           aseConfiguration.value().aseConfiguration.metadata.value()) {
-        if (meta.has_value() &&
-            meta.value().getTag() == MetadataLtv::vendorSpecific) {
-          auto k = meta.value().get<MetadataLtv::vendorSpecific>().opaqueValue;
-          name = std::string(k.begin(), k.end());
-          break;
-        }
-      }
-    }
-  }
-
-  ss << "setting name: " << name << ", setting: " << setting.toString();
-  return ss.str();
-}
-
 ndk::ScopedAStatus LeAudioOffloadAudioProvider::startSession(
     const std::shared_ptr<IBluetoothAudioPort>& host_if,
     const AudioConfiguration& audio_config,
@@ -742,9 +708,11 @@
   return filtered_setting;
 }
 
-std::optional<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+std::optional<std::pair<
+    std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
 LeAudioOffloadAudioProvider::matchWithRequirement(
-    std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>&
+    std::vector<std::pair<
+        std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>&
         matched_ase_configuration_settings,
     const IBluetoothAudioProvider::LeAudioConfigurationRequirement& requirement,
     bool isMatchContext, bool isExact, bool isMatchFlags) {
@@ -758,14 +726,15 @@
     if (!requirement.flags.has_value()) return std::nullopt;
     requirement_flags_bitmask = requirement.flags.value().bitmask;
   }
-  for (auto& setting : matched_ase_configuration_settings) {
+  for (auto& [setting_name, setting] : matched_ase_configuration_settings) {
     // Try to match context.
     if (isMatchContext) {
       if ((setting.audioContext.bitmask & requirement.audioContext.bitmask) !=
           requirement.audioContext.bitmask)
         continue;
-      LOG(DEBUG) << __func__ << ": Setting with matched context: "
-                 << getSettingOutputString(setting);
+      LOG(DEBUG) << __func__
+                 << ": Setting with matched context: name: " << setting_name
+                 << ", setting: " << setting.toString();
     }
 
     // Try to match configuration flags
@@ -774,19 +743,20 @@
       if ((setting.flags.value().bitmask & requirement_flags_bitmask) !=
           requirement_flags_bitmask)
         continue;
-      LOG(DEBUG) << __func__ << ": Setting with matched flags: "
-                 << getSettingOutputString(setting);
+      LOG(DEBUG) << __func__
+                 << ": Setting with matched flags: name: " << setting_name
+                 << ", setting: " << setting.toString();
     }
 
     auto filtered_ase_configuration_setting =
         getRequirementMatchedAseConfigurationSettings(setting, requirement,
                                                       isExact);
     if (filtered_ase_configuration_setting.has_value()) {
-      LOG(INFO) << __func__ << ": Result found: "
-                << getSettingOutputString(
-                       filtered_ase_configuration_setting.value());
+      LOG(INFO) << __func__ << ": Result found: name: " << setting_name
+                << ", setting: "
+                << filtered_ase_configuration_setting.value().toString();
       // Found a matched setting, ignore other settings
-      return filtered_ase_configuration_setting;
+      return {{setting_name, filtered_ase_configuration_setting.value()}};
     }
   }
   // If cannot satisfy this requirement, return nullopt
@@ -812,7 +782,8 @@
     std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>*
         _aidl_return) {
   // Get all configuration settings
-  std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+  std::vector<std::pair<
+      std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
       ase_configuration_settings =
           BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
 
@@ -822,15 +793,17 @@
   }
 
   // Matched ASE configuration with ignored audio context
-  std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+  std::vector<std::pair<
+      std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
       sink_matched_ase_configuration_settings;
-  std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+  std::vector<std::pair<
+      std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
       matched_ase_configuration_settings;
 
   // A setting must match both source and sink.
   // First filter all setting matched with sink capability
   if (in_remoteSinkAudioCapabilities.has_value()) {
-    for (auto& setting : ase_configuration_settings) {
+    for (auto& [setting_name, setting] : ase_configuration_settings) {
       for (auto& capability : in_remoteSinkAudioCapabilities.value()) {
         if (!capability.has_value()) continue;
         auto filtered_ase_configuration_setting =
@@ -838,7 +811,7 @@
                 setting, capability.value(), kLeAudioDirectionSink);
         if (filtered_ase_configuration_setting.has_value()) {
           sink_matched_ase_configuration_settings.push_back(
-              filtered_ase_configuration_setting.value());
+              {setting_name, filtered_ase_configuration_setting.value()});
         }
       }
     }
@@ -848,7 +821,8 @@
 
   // Combine filter every source capability
   if (in_remoteSourceAudioCapabilities.has_value()) {
-    for (auto& setting : sink_matched_ase_configuration_settings)
+    for (auto& [setting_name, setting] :
+         sink_matched_ase_configuration_settings)
       for (auto& capability : in_remoteSourceAudioCapabilities.value()) {
         if (!capability.has_value()) continue;
         auto filtered_ase_configuration_setting =
@@ -856,7 +830,7 @@
                 setting, capability.value(), kLeAudioDirectionSource);
         if (filtered_ase_configuration_setting.has_value()) {
           matched_ase_configuration_settings.push_back(
-              filtered_ase_configuration_setting.value());
+              {setting_name, filtered_ase_configuration_setting.value()});
         }
       }
   } else {
@@ -864,7 +838,11 @@
         sink_matched_ase_configuration_settings;
   }
 
-  std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting> result;
+  std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+      result_no_name;
+  std::vector<std::pair<
+      std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
+      result;
   for (auto& requirement : in_requirements) {
     // For each requirement, try to match with a setting.
     // If we cannot match, return an empty result.
@@ -896,18 +874,19 @@
     if (!found) {
       LOG(ERROR) << __func__
                  << ": Cannot find any match for this requirement, exitting...";
-      result.clear();
-      *_aidl_return = result;
+      *_aidl_return = result_no_name;
       return ndk::ScopedAStatus::ok();
     }
   }
 
   LOG(INFO) << __func__
             << ": Found matches for all requirements, chosen settings:";
-  for (auto& setting : result) {
-    LOG(INFO) << __func__ << ": " << getSettingOutputString(setting);
+  for (auto& [setting_name, setting] : result) {
+    LOG(INFO) << __func__ << ": name: " << setting_name
+              << ", setting: " << setting.toString();
+    result_no_name.push_back(setting);
   }
-  *_aidl_return = result;
+  *_aidl_return = result_no_name;
   return ndk::ScopedAStatus::ok();
 };
 
@@ -937,7 +916,8 @@
     uint8_t direction,
     const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
         qosRequirement,
-    std::vector<LeAudioAseConfigurationSetting>& ase_configuration_settings,
+    std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>&
+        ase_configuration_settings,
     bool isExact, bool isMatchFlags) {
   auto requirement_flags_bitmask = 0;
   if (isMatchFlags) {
@@ -955,13 +935,14 @@
     direction_qos_requirement = qosRequirement.sourceAseQosRequirement.value();
   }
 
-  for (auto& setting : ase_configuration_settings) {
+  for (auto& [setting_name, setting] : ase_configuration_settings) {
     // Context matching
     if ((setting.audioContext.bitmask & qosRequirement.audioContext.bitmask) !=
         qosRequirement.audioContext.bitmask)
       continue;
-    LOG(DEBUG) << __func__ << ": Setting with matched context: "
-               << getSettingOutputString(setting);
+    LOG(DEBUG) << __func__
+               << ": Setting with matched context: name: " << setting_name
+               << ", setting: " << setting.toString();
 
     // Match configuration flags
     if (isMatchFlags) {
@@ -969,8 +950,9 @@
       if ((setting.flags.value().bitmask & requirement_flags_bitmask) !=
           requirement_flags_bitmask)
         continue;
-      LOG(DEBUG) << __func__ << ": Setting with matched flags: "
-                 << getSettingOutputString(setting);
+      LOG(DEBUG) << __func__
+                 << ": Setting with matched flags: name: " << setting_name
+                 << ", setting: " << setting.toString();
     }
 
     // Get a list of all matched AseDirectionConfiguration
@@ -1041,7 +1023,8 @@
   IBluetoothAudioProvider::LeAudioAseQosConfigurationPair result;
 
   // Get all configuration settings
-  std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+  std::vector<std::pair<
+      std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
       ase_configuration_settings =
           BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings();
 
diff --git a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
index 8c4f543..6d402a4 100644
--- a/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
+++ b/bluetooth/audio/aidl/default/LeAudioOffloadAudioProvider.h
@@ -163,15 +163,19 @@
       uint8_t direction,
       const IBluetoothAudioProvider::LeAudioAseQosConfigurationRequirement&
           qosRequirement,
-      std::vector<LeAudioAseConfigurationSetting>& ase_configuration_settings,
+      std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>&
+          ase_configuration_settings,
       bool isExact, bool isMatchedFlag);
   bool isSubgroupConfigurationMatchedContext(
       AudioContext requirement_context,
       IBluetoothAudioProvider::BroadcastQuality quality,
       LeAudioBroadcastSubgroupConfiguration configuration);
-  std::optional<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>
+  std::optional<std::pair<
+      std::string, IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>
   matchWithRequirement(
-      std::vector<IBluetoothAudioProvider::LeAudioAseConfigurationSetting>&
+      std::vector<
+          std::pair<std::string,
+                    IBluetoothAudioProvider::LeAudioAseConfigurationSetting>>&
           matched_ase_configuration_settings,
       const IBluetoothAudioProvider::LeAudioConfigurationRequirement&
           requirements,
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index db2528e..89472e6 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -452,7 +452,7 @@
   return kDefaultOffloadHfpCodecInfo;
 }
 
-std::vector<LeAudioAseConfigurationSetting>
+std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
 BluetoothAudioCodecs::GetLeAudioAseConfigurationSettings() {
   return AudioSetConfigurationProviderJson::
       GetLeAudioAseConfigurationSettings();
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
index 0a1f708..c77de61 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.h
@@ -54,7 +54,7 @@
   static std::vector<CodecInfo> GetLeAudioOffloadCodecInfo(
       const SessionType& session_type);
 
-  static std::vector<LeAudioAseConfigurationSetting>
+  static std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
   GetLeAudioAseConfigurationSettings();
 
   static std::vector<CodecInfo> GetHfpOffloadCodecInfo();
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
index 2474916..feb4cda 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.cpp
@@ -65,7 +65,8 @@
                     ConfigurationFlags>>
     configurations_;
 
-std::vector<LeAudioAseConfigurationSetting> ase_configuration_settings_;
+std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
+    ase_configuration_settings_;
 
 constexpr uint8_t kIsoDataPathHci = 0x00;
 constexpr uint8_t kIsoDataPathPlatformDefault = 0x01;
@@ -273,7 +274,7 @@
 
 /* Implementation */
 
-std::vector<LeAudioAseConfigurationSetting>
+std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
 AudioSetConfigurationProviderJson::GetLeAudioAseConfigurationSettings() {
   AudioSetConfigurationProviderJson::LoadAudioSetConfigurationProviderJson();
   return ase_configuration_settings_;
@@ -392,7 +393,7 @@
 }
 
 void AudioSetConfigurationProviderJson::populateAseConfiguration(
-    const std::string& name, LeAudioAseConfiguration& ase,
+    LeAudioAseConfiguration& ase,
     const le_audio::AudioSetSubConfiguration* flat_subconfig,
     const le_audio::QosConfiguration* qos_cfg,
     ConfigurationFlags& configurationFlags) {
@@ -431,12 +432,6 @@
   }
   // Codec configuration data
   populateConfigurationData(ase, flat_subconfig->codec_configuration());
-  // Populate the config name for easier debug
-  auto meta = std::vector<std::optional<MetadataLtv>>();
-  MetadataLtv::VendorSpecific cfg_name;
-  cfg_name.opaqueValue = std::vector<uint8_t>(name.begin(), name.end());
-  meta.push_back(cfg_name);
-  ase.metadata = meta;
 }
 
 void AudioSetConfigurationProviderJson::populateAseQosConfiguration(
@@ -507,7 +502,6 @@
 // Parse into AseDirectionConfiguration
 AseDirectionConfiguration
 AudioSetConfigurationProviderJson::SetConfigurationFromFlatSubconfig(
-    const std::string& name,
     const le_audio::AudioSetSubConfiguration* flat_subconfig,
     const le_audio::QosConfiguration* qos_cfg, CodecLocation location,
     ConfigurationFlags& configurationFlags) {
@@ -518,8 +512,7 @@
   LeAudioDataPathConfiguration path;
 
   // Translate into LeAudioAseConfiguration
-  populateAseConfiguration(name, ase, flat_subconfig, qos_cfg,
-                           configurationFlags);
+  populateAseConfiguration(ase, flat_subconfig, qos_cfg, configurationFlags);
 
   // Translate into LeAudioAseQosConfiguration
   populateAseQosConfiguration(qos, qos_cfg, ase,
@@ -553,15 +546,14 @@
 // Parse into AseDirectionConfiguration and the ConfigurationFlags
 // and put them in the given list.
 void AudioSetConfigurationProviderJson::processSubconfig(
-    const std::string& name,
     const le_audio::AudioSetSubConfiguration* subconfig,
     const le_audio::QosConfiguration* qos_cfg,
     std::vector<std::optional<AseDirectionConfiguration>>&
         directionAseConfiguration,
     CodecLocation location, ConfigurationFlags& configurationFlags) {
   auto ase_cnt = subconfig->ase_cnt();
-  auto config = SetConfigurationFromFlatSubconfig(name, subconfig, qos_cfg,
-                                                  location, configurationFlags);
+  auto config = SetConfigurationFromFlatSubconfig(subconfig, qos_cfg, location,
+                                                  configurationFlags);
   directionAseConfiguration.push_back(config);
   // Put the same setting again.
   if (ase_cnt == 2) directionAseConfiguration.push_back(config);
@@ -646,11 +638,11 @@
     /* Load subconfigurations */
     for (auto subconfig : *codec_cfg->subconfigurations()) {
       if (subconfig->direction() == kLeAudioDirectionSink) {
-        processSubconfig(flat_cfg->name()->str(), subconfig, qos_sink_cfg,
-                         sinkAseConfiguration, location, configurationFlags);
+        processSubconfig(subconfig, qos_sink_cfg, sinkAseConfiguration,
+                         location, configurationFlags);
       } else {
-        processSubconfig(flat_cfg->name()->str(), subconfig, qos_source_cfg,
-                         sourceAseConfiguration, location, configurationFlags);
+        processSubconfig(subconfig, qos_source_cfg, sourceAseConfiguration,
+                         location, configurationFlags);
       }
     }
 
@@ -860,7 +852,7 @@
       setting.flags = flags;
       // Add to list of setting
       LOG(DEBUG) << "Pushing configuration to list: " << config_name;
-      ase_configuration_settings_.push_back(setting);
+      ase_configuration_settings_.push_back({config_name, setting});
     }
   }
 
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
index 8e12618..f115d61 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioAseConfigurationSettingProvider.h
@@ -50,7 +50,7 @@
 
 class AudioSetConfigurationProviderJson {
  public:
-  static std::vector<LeAudioAseConfigurationSetting>
+  static std::vector<std::pair<std::string, LeAudioAseConfigurationSetting>>
   GetLeAudioAseConfigurationSettings();
 
  private:
@@ -73,7 +73,7 @@
           flat_codec_specific_params);
 
   static void populateAseConfiguration(
-      const std::string& name, LeAudioAseConfiguration& ase,
+      LeAudioAseConfiguration& ase,
       const le_audio::AudioSetSubConfiguration* flat_subconfig,
       const le_audio::QosConfiguration* qos_cfg,
       ConfigurationFlags& configurationFlags);
@@ -84,13 +84,11 @@
       uint8_t ase_channel_cnt);
 
   static AseDirectionConfiguration SetConfigurationFromFlatSubconfig(
-      const std::string& name,
       const le_audio::AudioSetSubConfiguration* flat_subconfig,
       const le_audio::QosConfiguration* qos_cfg, CodecLocation location,
       ConfigurationFlags& configurationFlags);
 
   static void processSubconfig(
-      const std::string& name,
       const le_audio::AudioSetSubConfiguration* subconfig,
       const le_audio::QosConfiguration* qos_cfg,
       std::vector<std::optional<AseDirectionConfiguration>>&
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index cf9c6d7..6ff51bf 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -36,6 +36,7 @@
     srcs: [
         "VtsHalGraphicsComposer3_TargetTest.cpp",
         "VtsHalGraphicsComposer3_ReadbackTest.cpp",
+        "VtsHalGraphicsComposer3_ConnectedDisplays.cpp",
     ],
     shared_libs: [
         "libEGL",
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ConnectedDisplays.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ConnectedDisplays.cpp
new file mode 100644
index 0000000..dff1fa5
--- /dev/null
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ConnectedDisplays.cpp
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2025, 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 <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <aidl/android/hardware/graphics/common/FRect.h>
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/IComposer.h>
+#include <android-base/properties.h>
+#include <android/binder_process.h>
+#include <android/hardware/graphics/composer3/ComposerClientReader.h>
+#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
+#include <binder/ProcessState.h>
+#include <gtest/gtest.h>
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <string>
+#include <unordered_map>
+#include "ComposerClientWrapper.h"
+
+#undef LOG_TAG
+#define LOG_TAG "VtsHalGraphicsComposer3_ConnectedDisplays"
+
+namespace aidl::android::hardware::graphics::composer3::vts {
+
+using namespace std::chrono_literals;
+using namespace aidl::android::hardware::graphics::composer3::libhwc_aidl_test;
+
+/**
+ * @class ConnectedDisplaysTest
+ * @brief A test suite for validating the HWC (Hardware Composer) API when multiple displays are
+ * present.
+ *
+ * This test suite is part of the VTS (Vendor Test Suite) and is designed to test the interactions
+ * between multiple displays using the HWC API. It ensures that the API behaves correctly when more
+ * than one display are present.
+ *
+ * @note The test requires at least two displays to be found. If only one display is found, the test
+ * will be skipped.
+ */
+class ConnectedDisplaysTest : public ::testing::TestWithParam<std::string> {
+  protected:
+    void SetUp() override {
+        mComposerClient = std::make_unique<ComposerClientWrapper>(GetParam());
+        ASSERT_TRUE(mComposerClient->createClient().isOk());
+
+        const auto& [status, displays] = mComposerClient->getDisplays();
+        ASSERT_TRUE(status.isOk());
+        mDisplays = displays;
+
+        // Skip test if there's only one display
+        if (mDisplays.size() <= 1) {
+            GTEST_SKIP() << "Test requires at least 2 displays, found " << mDisplays.size();
+        }
+
+        // explicitly disable vsync for all displays
+        for (const auto& display : mDisplays) {
+            EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), false).isOk());
+        }
+        mComposerClient->setVsyncAllowed(false);
+    }
+
+    void TearDown() override {
+        ASSERT_TRUE(
+                mComposerClient->tearDown(std::unordered_map<int64_t, ComposerClientWriter*>{}));
+        mComposerClient.reset();
+    }
+
+    std::unique_ptr<ComposerClientWrapper> mComposerClient;
+    std::vector<DisplayWrapper> mDisplays;
+    static constexpr uint32_t kBufferSlotCount = 64;
+};
+
+/**
+ * Test that verifies display configurations can be changed independently without affecting other
+ * displays.
+ */
+TEST_P(ConnectedDisplaysTest, IndependentConfigChange) {
+    // Store initial configs for all displays
+    std::unordered_map<int64_t, int32_t> initialConfigs;
+    for (const auto& display : mDisplays) {
+        const auto& [activeStatus, activeConfig] =
+                mComposerClient->getActiveConfig(display.getDisplayId());
+        ASSERT_TRUE(activeStatus.isOk());
+        initialConfigs[display.getDisplayId()] = activeConfig;
+    }
+
+    for (auto& display : mDisplays) {
+        const auto& [status, configs] = mComposerClient->getDisplayConfigs(display.getDisplayId());
+        ASSERT_TRUE(status.isOk());
+        ASSERT_FALSE(configs.empty());
+
+        // Try to set each config
+        for (const auto& config : configs) {
+            if (config == initialConfigs[display.getDisplayId()]) continue;
+
+            EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config).isOk());
+
+            // Verify other displays' configs remain unchanged
+            for (const auto& otherDisplay : mDisplays) {
+                if (otherDisplay.getDisplayId() != display.getDisplayId()) {
+                    const auto& [otherStatus, otherConfig] =
+                            mComposerClient->getActiveConfig(otherDisplay.getDisplayId());
+                    EXPECT_TRUE(otherStatus.isOk());
+                    EXPECT_EQ(otherConfig, initialConfigs[otherDisplay.getDisplayId()]);
+                }
+            }
+        }
+        // Restore original config
+        EXPECT_TRUE(
+                mComposerClient->setActiveConfig(&display, initialConfigs[display.getDisplayId()])
+                        .isOk());
+    }
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ConnectedDisplaysTest);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, ConnectedDisplaysTest,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+        ::android::PrintInstanceNameToString);
+
+}  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/nfc/OWNERS b/nfc/OWNERS
index f46dccd..47f209f 100644
--- a/nfc/OWNERS
+++ b/nfc/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 48448
-include platform/packages/apps/Nfc:/OWNERS
\ No newline at end of file
+include platform/packages/modules/Nfc:/OWNERS
\ No newline at end of file
diff --git a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
index 6db7e14..9c44c3a 100644
--- a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
+++ b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
@@ -349,44 +349,18 @@
 }
 
 /*
- * SetPassiveObserverTech_individualTechnologies:
- * Verifies per-technology observe mode is supported as a capability. Then sets observe mode
- * for each individual technology and verifies the command succeeds.
- *
- * @VsrTest = GMS-VSR-3.2.8-002
+ * SetPassiveObserverTech_getCaps:
+ * Verifies GET_CAPS returns get correct value for observe mode capabilities.
  */
-TEST_P(NfcBehaviorChanges, SetPassiveObserverTech_individualTechnologies) {
+TEST_P(NfcBehaviorChanges, SetPassiveObserverTech_getCaps) {
     if (get_vsr_api_level() < 202504) {
         GTEST_SKIP() << "Skipping test for board API level < 202504";
     }
 
     tNFC_STATUS status = nfaGetCaps();
+
     ASSERT_EQ(status, NFC_STATUS_OK);
     ASSERT_EQ(getCapsPassiveObserverModeValue(), 0x2);
-
-    status = nfaSetPassiveObserverTech(NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_A);
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    status = nfaQueryObserveModeState();
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    ASSERT_EQ(sObserveModeState, NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_A);
-
-    status = nfaSetPassiveObserverTech(NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_B);
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    status = nfaQueryObserveModeState();
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    ASSERT_EQ(sObserveModeState, NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_B);
-
-    status = nfaSetPassiveObserverTech(NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_V);
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    status = nfaQueryObserveModeState();
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    ASSERT_EQ(sObserveModeState, NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_V);
-
-    status = nfaSetPassiveObserverTech(NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_F);
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    status = nfaQueryObserveModeState();
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    ASSERT_EQ(sObserveModeState, NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE_F);
 }
 
 /*
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 87797ae..93b7c38 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -317,6 +317,9 @@
     }
     ASSERT_TRUE(ret.isOk());
     ASSERT_GE(mSupportInfo->headroom.cpuMinIntervalMillis, 0);
+    ASSERT_LE(mSupportInfo->headroom.cpuMinCalculationWindowMillis, 50);
+    ASSERT_GE(mSupportInfo->headroom.cpuMaxCalculationWindowMillis, 10000);
+    ASSERT_GE(mSupportInfo->headroom.cpuMaxTidCount, 5);
     ASSERT_EQ(headroom.getTag(), CpuHeadroomResult::globalHeadroom);
     ASSERT_GE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 0.0f);
     ASSERT_LE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 100.00f);
@@ -335,6 +338,8 @@
     }
     ASSERT_TRUE(ret.isOk());
     ASSERT_GE(mSupportInfo->headroom.gpuMinIntervalMillis, 0);
+    ASSERT_LE(mSupportInfo->headroom.gpuMinCalculationWindowMillis, 50);
+    ASSERT_GE(mSupportInfo->headroom.gpuMaxCalculationWindowMillis, 10000);
     ASSERT_EQ(headroom.getTag(), GpuHeadroomResult::globalHeadroom);
     ASSERT_GE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 0.0f);
     ASSERT_LE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 100.00f);
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index c6b2579..98ea0d2 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -55,6 +55,15 @@
     ASSERT_NE(nullptr, radio_config.get());
 }
 
+bool RadioModemTest::shouldTestCdma() {
+    int32_t aidl_version = 0;
+    ndk::ScopedAStatus aidl_status = radio_modem->getInterfaceVersion(&aidl_version);
+    EXPECT_TRUE(aidl_status.isOk());
+    if (aidl_version < 2) return true;  // < RADIO_HAL_VERSION_2_1
+
+    return !telephony_flags::cleanup_cdma();
+}
+
 /*
  * Test IRadioModem.setRadioPower() for the response returned.
  */
@@ -244,6 +253,10 @@
  * Test IRadioModem.nvReadItem() for the response returned.
  */
 TEST_P(RadioModemTest, nvReadItem) {
+    if (!shouldTestCdma()) {
+        GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+    }
+
     serial = GetRandomSerialNumber();
 
     radio_modem->nvReadItem(serial, NvItem::LTE_BAND_ENABLE_25);
@@ -261,6 +274,10 @@
  * Test IRadioModem.nvWriteItem() for the response returned.
  */
 TEST_P(RadioModemTest, nvWriteItem) {
+    if (!shouldTestCdma()) {
+        GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+    }
+
     serial = GetRandomSerialNumber();
     NvWriteItem item;
     memset(&item, 0, sizeof(item));
diff --git a/radio/aidl/vts/radio_modem_utils.h b/radio/aidl/vts/radio_modem_utils.h
index aa99ea3..21481bd 100644
--- a/radio/aidl/vts/radio_modem_utils.h
+++ b/radio/aidl/vts/radio_modem_utils.h
@@ -119,6 +119,8 @@
   public:
     void SetUp() override;
 
+    bool shouldTestCdma();
+
     /* radio modem service handle */
     std::shared_ptr<IRadioModem> radio_modem;
     /* radio modem response handle */
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 9a3a429..439d268 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -78,6 +78,15 @@
     ASSERT_NE(nullptr, radio_config.get());
 }
 
+bool RadioNetworkTest::shouldTestCdma() {
+    int32_t aidl_version = 0;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    EXPECT_TRUE(aidl_status.isOk());
+    if (aidl_version < 4) return true;  // < RADIO_HAL_VERSION_2_3
+
+    return !telephony_flags::cleanup_cdma();
+}
+
 void RadioNetworkTest::stopNetworkScan() {
     serial = GetRandomSerialNumber();
     radio_network->stopNetworkScan(serial);
@@ -1775,6 +1784,9 @@
  * Test IRadioNetwork.getAvailableBandModes() for the response returned.
  */
 TEST_P(RadioNetworkTest, getAvailableBandModes) {
+    if (!shouldTestCdma()) {
+        GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+    }
     if (telephony_flags::enforce_telephony_feature_mapping()) {
         if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
             GTEST_SKIP() << "Skipping getAvailableBandModes "
@@ -2019,6 +2031,9 @@
  * Test IRadioNetwork.setBandMode() for the response returned.
  */
 TEST_P(RadioNetworkTest, setBandMode) {
+    if (!shouldTestCdma()) {
+        GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+    }
     if (telephony_flags::enforce_telephony_feature_mapping()) {
         if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
             GTEST_SKIP() << "Skipping setBandMode "
@@ -2043,6 +2058,10 @@
  * Test IRadioNetwork.setLocationUpdates() for the response returned.
  */
 TEST_P(RadioNetworkTest, setLocationUpdates) {
+    // While setLocationUpdates is not CDMA-related, it's guarded by the same release flag.
+    if (!shouldTestCdma()) {
+        GTEST_SKIP() << "Skipping testing of deprecated setLocationUpdates method";
+    }
     if (telephony_flags::enforce_telephony_feature_mapping()) {
         if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
             GTEST_SKIP() << "Skipping setLocationUpdates "
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index 17c0896..3387dec 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -263,6 +263,8 @@
   public:
     void SetUp() override;
 
+    bool shouldTestCdma();
+
     /* radio network service handle */
     std::shared_ptr<IRadioNetwork> radio_network;
     /* radio network response handle */
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index 2823977..aaccb21 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -52,6 +52,15 @@
     ASSERT_NE(nullptr, radio_config.get());
 }
 
+bool RadioSimTest::shouldTestCdma() {
+    int32_t aidl_version = 0;
+    ndk::ScopedAStatus aidl_status = radio_sim->getInterfaceVersion(&aidl_version);
+    EXPECT_TRUE(aidl_status.isOk());
+    if (aidl_version < 4) return true;  // < RADIO_HAL_VERSION_2_3
+
+    return !telephony_flags::cleanup_cdma();
+}
+
 void RadioSimTest::updateSimCardStatus() {
     serial = GetRandomSerialNumber();
     radio_sim->getIccCardStatus(serial);
@@ -935,6 +944,13 @@
  * Test IRadioSim.iccCloseLogicalChannel() for the response returned.
  */
 TEST_P(RadioSimTest, iccCloseLogicalChannel) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_sim->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version >= 2) {  // >= RADIO_HAL_VERSION_2_1
+        GTEST_SKIP() << "Skipping iccCloseLogicalChannel (deprecated)";
+    }
+
     if (telephony_flags::enforce_telephony_feature_mapping()) {
         if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
             GTEST_SKIP() << "Skipping iccCloseLogicalChannel "
@@ -1176,6 +1192,9 @@
  * Test IRadioSim.setUiccSubscription() for the response returned.
  */
 TEST_P(RadioSimTest, setUiccSubscription) {
+    if (!shouldTestCdma()) {
+        GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
+    }
     if (telephony_flags::enforce_telephony_feature_mapping()) {
         if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
             GTEST_SKIP() << "Skipping setUiccSubscription "
diff --git a/radio/aidl/vts/radio_sim_utils.h b/radio/aidl/vts/radio_sim_utils.h
index 7cbcc58..eb3efb2 100644
--- a/radio/aidl/vts/radio_sim_utils.h
+++ b/radio/aidl/vts/radio_sim_utils.h
@@ -198,6 +198,8 @@
   public:
     void SetUp() override;
 
+    bool shouldTestCdma();
+
     /* Override updateSimCardStatus in RadioServiceTest to not call setResponseFunctions */
     void updateSimCardStatus();
 
diff --git a/security/see/authmgr/aidl/README.md b/security/see/authmgr/aidl/README.md
new file mode 100644
index 0000000..97b2b1d
--- /dev/null
+++ b/security/see/authmgr/aidl/README.md
@@ -0,0 +1,21 @@
+# AuthMgr
+
+The AuthMgr protocol authenticates and authorizes clients before they can
+access trusted HALs, AIDL-defined services in trusted execution environments.
+Version 1 was designed to allow applications running in a protected virtual
+machine (pVM) to access services running in a TEE in ARM TrustZone. An
+implementation of `IAuthMgrAuthorization` is referred to as an AuthMgr Backend.
+An implementation of a client of the AuthMgr Backend is referred to as an
+AuthMgr Frontend.
+
+
+## Additional Requirements by Android Version
+
+The comments on `IAuthMgrAuthorization` describe the requirements for implementing
+an AuthMgr Backend (implementor of the interface) itself. There are some additional
+requirements that are specific to Android release versions.
+
+### Android 16
+If implementing `IAuthMgrAuthorization` in Android 16 only one AuthMgr Backend is
+supported and dynamic service discovery is not supported. The AuthMgr Backend
+service must be exposed on secure partition ID 0x8001 over VSOCK port 1.
\ No newline at end of file