Merge "Add RustDerive attributes to radio AIDL interfaces" into main
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index 52ae936..dc411ff 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -186,6 +186,12 @@
 
 template <typename E, typename U = std::underlying_type_t<E>,
           typename = std::enable_if_t<is_bit_position_enum<E>::value>>
+constexpr bool areAllBitPositionFlagsSet(U mask, std::initializer_list<E> flags) {
+    return (mask & makeBitPositionFlagMask<E>(flags)) == makeBitPositionFlagMask<E>(flags);
+}
+
+template <typename E, typename U = std::underlying_type_t<E>,
+          typename = std::enable_if_t<is_bit_position_enum<E>::value>>
 constexpr bool isAnyBitPositionFlagSet(U mask, std::initializer_list<E> flags) {
     return (mask & makeBitPositionFlagMask<E>(flags)) != 0;
 }
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 687d8fc..230c717 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -77,8 +77,10 @@
         "r_submix/ModuleRemoteSubmix.cpp",
         "r_submix/SubmixRoute.cpp",
         "r_submix/StreamRemoteSubmix.cpp",
+        "stub/ApeHeader.cpp",
         "stub/DriverStubImpl.cpp",
         "stub/ModuleStub.cpp",
+        "stub/StreamOffloadStub.cpp",
         "stub/StreamStub.cpp",
         "usb/ModuleUsb.cpp",
         "usb/StreamUsb.cpp",
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index f9fa799..077d80b 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -211,9 +211,9 @@
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
     const auto& flags = portConfigIt->flags.value();
-    StreamContext::DebugParameters params{
-            mDebug.streamTransientStateDelayMs, mVendorDebug.forceTransientBurst,
-            mVendorDebug.forceSynchronousDrain, mVendorDebug.forceDrainToDraining};
+    StreamContext::DebugParameters params{mDebug.streamTransientStateDelayMs,
+                                          mVendorDebug.forceTransientBurst,
+                                          mVendorDebug.forceSynchronousDrain};
     std::unique_ptr<StreamContext::DataMQ> dataMQ = nullptr;
     std::shared_ptr<IStreamCallback> streamAsyncCallback = nullptr;
     std::shared_ptr<ISoundDose> soundDose;
@@ -1546,7 +1546,6 @@
 
 const std::string Module::VendorDebug::kForceTransientBurstName = "aosp.forceTransientBurst";
 const std::string Module::VendorDebug::kForceSynchronousDrainName = "aosp.forceSynchronousDrain";
-const std::string Module::VendorDebug::kForceDrainToDrainingName = "aosp.forceDrainToDraining";
 
 ndk::ScopedAStatus Module::getVendorParameters(const std::vector<std::string>& in_ids,
                                                std::vector<VendorParameter>* _aidl_return) {
@@ -1561,10 +1560,6 @@
             VendorParameter forceSynchronousDrain{.id = id};
             forceSynchronousDrain.ext.setParcelable(Boolean{mVendorDebug.forceSynchronousDrain});
             _aidl_return->push_back(std::move(forceSynchronousDrain));
-        } else if (id == VendorDebug::kForceDrainToDrainingName) {
-            VendorParameter forceDrainToDraining{.id = id};
-            forceDrainToDraining.ext.setParcelable(Boolean{mVendorDebug.forceDrainToDraining});
-            _aidl_return->push_back(std::move(forceDrainToDraining));
         } else {
             allParametersKnown = false;
             LOG(VERBOSE) << __func__ << ": " << mType << ": unrecognized parameter \"" << id << "\"";
@@ -1605,10 +1600,6 @@
             if (!extractParameter<Boolean>(p, &mVendorDebug.forceSynchronousDrain)) {
                 return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
             }
-        } else if (p.id == VendorDebug::kForceDrainToDrainingName) {
-            if (!extractParameter<Boolean>(p, &mVendorDebug.forceDrainToDraining)) {
-                return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
-            }
         } else {
             allParametersKnown = false;
             LOG(VERBOSE) << __func__ << ": " << mType << ": unrecognized parameter \"" << p.id
diff --git a/audio/aidl/default/ModulePrimary.cpp b/audio/aidl/default/ModulePrimary.cpp
index 3da6d48..2a1dba9 100644
--- a/audio/aidl/default/ModulePrimary.cpp
+++ b/audio/aidl/default/ModulePrimary.cpp
@@ -21,12 +21,16 @@
 #include <android-base/logging.h>
 
 #include "core-impl/ModulePrimary.h"
+#include "core-impl/StreamOffloadStub.h"
 #include "core-impl/StreamPrimary.h"
 #include "core-impl/Telephony.h"
 
+using aidl::android::hardware::audio::common::areAllBitPositionFlagsSet;
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioIoFlags;
 using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::AudioOutputFlags;
 using aidl::android::media::audio::common::AudioPort;
 using aidl::android::media::audio::common::AudioPortConfig;
 using aidl::android::media::audio::common::MicrophoneInfo;
@@ -43,6 +47,17 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus ModulePrimary::calculateBufferSizeFrames(
+        const ::aidl::android::media::audio::common::AudioFormatDescription& format,
+        int32_t latencyMs, int32_t sampleRateHz, int32_t* bufferSizeFrames) {
+    if (format.type != ::aidl::android::media::audio::common::AudioFormatType::PCM &&
+        StreamOffloadStub::getSupportedEncodings().count(format.encoding)) {
+        *bufferSizeFrames = sampleRateHz / 2;  // 1/2 of a second.
+        return ndk::ScopedAStatus::ok();
+    }
+    return Module::calculateBufferSizeFrames(format, latencyMs, sampleRateHz, bufferSizeFrames);
+}
+
 ndk::ScopedAStatus ModulePrimary::createInputStream(StreamContext&& context,
                                                     const SinkMetadata& sinkMetadata,
                                                     const std::vector<MicrophoneInfo>& microphones,
@@ -54,8 +69,18 @@
 ndk::ScopedAStatus ModulePrimary::createOutputStream(
         StreamContext&& context, const SourceMetadata& sourceMetadata,
         const std::optional<AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) {
-    return createStreamInstance<StreamOutPrimary>(result, std::move(context), sourceMetadata,
-                                                  offloadInfo);
+    if (!areAllBitPositionFlagsSet(
+                context.getFlags().get<AudioIoFlags::output>(),
+                {AudioOutputFlags::COMPRESS_OFFLOAD, AudioOutputFlags::NON_BLOCKING})) {
+        return createStreamInstance<StreamOutPrimary>(result, std::move(context), sourceMetadata,
+                                                      offloadInfo);
+    } else {
+        // "Stub" is used because there is no actual decoder. The stream just
+        // extracts the clip duration from the media file header and simulates
+        // playback over time.
+        return createStreamInstance<StreamOutOffloadStub>(result, std::move(context),
+                                                          sourceMetadata, offloadInfo);
+    }
 }
 
 int32_t ModulePrimary::getNominalLatencyMs(const AudioPortConfig&) {
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index c138095..c6c1b5d 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -142,12 +142,16 @@
                    ", size in bytes: " + std::to_string(mDataBufferSize);
         }
     }
-    if (::android::status_t status = mDriver->init(); status != STATUS_OK) {
+    if (::android::status_t status = mDriver->init(this /*DriverCallbackInterface*/);
+        status != STATUS_OK) {
         return "Failed to initialize the driver: " + std::to_string(status);
     }
     return "";
 }
 
+void StreamWorkerCommonLogic::onBufferStateChange(size_t /*bufferFramesLeft*/) {}
+void StreamWorkerCommonLogic::onClipStateChange(size_t /*clipFramesLeft*/, bool /*hasNextClip*/) {}
+
 void StreamWorkerCommonLogic::populateReply(StreamDescriptor::Reply* reply,
                                             bool isConnected) const {
     static const StreamDescriptor::Position kUnknownPosition = {
@@ -381,48 +385,60 @@
 
 const std::string StreamOutWorkerLogic::kThreadName = "writer";
 
-StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() {
-    if (mState == StreamDescriptor::State::DRAINING && mContext->getForceDrainToDraining() &&
-        mOnDrainReadyStatus == OnDrainReadyStatus::UNSENT) {
+void StreamOutWorkerLogic::onBufferStateChange(size_t bufferFramesLeft) {
+    const StreamDescriptor::State state = mState;
+    LOG(DEBUG) << __func__ << ": state: " << toString(state)
+               << ", bufferFramesLeft: " << bufferFramesLeft;
+    if (state == StreamDescriptor::State::TRANSFERRING) {
+        mState = StreamDescriptor::State::ACTIVE;
         std::shared_ptr<IStreamCallback> asyncCallback = mContext->getAsyncCallback();
         if (asyncCallback != nullptr) {
+            ndk::ScopedAStatus status = asyncCallback->onTransferReady();
+            if (!status.isOk()) {
+                LOG(ERROR) << __func__ << ": error from onTransferReady: " << status;
+            }
+        }
+    }
+}
+
+void StreamOutWorkerLogic::onClipStateChange(size_t clipFramesLeft, bool hasNextClip) {
+    const DrainState drainState = mDrainState;
+    std::shared_ptr<IStreamCallback> asyncCallback = mContext->getAsyncCallback();
+    LOG(DEBUG) << __func__ << ": drainState: " << drainState << "; clipFramesLeft "
+               << clipFramesLeft << "; hasNextClip? " << hasNextClip << "; asyncCallback? "
+               << (asyncCallback != nullptr);
+    if (drainState != DrainState::NONE && clipFramesLeft == 0) {
+        mState =
+                hasNextClip ? StreamDescriptor::State::TRANSFERRING : StreamDescriptor::State::IDLE;
+        mDrainState = DrainState::NONE;
+        if (drainState == DrainState::ALL && asyncCallback != nullptr) {
+            LOG(DEBUG) << __func__ << ": sending onDrainReady";
             ndk::ScopedAStatus status = asyncCallback->onDrainReady();
             if (!status.isOk()) {
                 LOG(ERROR) << __func__ << ": error from onDrainReady: " << status;
             }
-            // This sets the timeout for moving into IDLE on next iterations.
-            switchToTransientState(StreamDescriptor::State::DRAINING);
-            mOnDrainReadyStatus = OnDrainReadyStatus::SENT;
         }
-    } else if (mState == StreamDescriptor::State::DRAINING ||
-               mState == StreamDescriptor::State::TRANSFERRING) {
+    } else if (drainState == DrainState::EN && clipFramesLeft > 0) {
+        // The stream state does not change, it is still draining.
+        mDrainState = DrainState::EN_SENT;
+        if (asyncCallback != nullptr) {
+            LOG(DEBUG) << __func__ << ": sending onDrainReady";
+            ndk::ScopedAStatus status = asyncCallback->onDrainReady();
+            if (!status.isOk()) {
+                LOG(ERROR) << __func__ << ": error from onDrainReady: " << status;
+            }
+        }
+    }
+}
+
+StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() {
+    // Non-blocking mode is handled within 'onClipStateChange'
+    if (std::shared_ptr<IStreamCallback> asyncCallback = mContext->getAsyncCallback();
+        mState == StreamDescriptor::State::DRAINING && asyncCallback == nullptr) {
         if (auto stateDurationMs = std::chrono::duration_cast<std::chrono::milliseconds>(
                     std::chrono::steady_clock::now() - mTransientStateStart);
             stateDurationMs >= mTransientStateDelayMs) {
-            std::shared_ptr<IStreamCallback> asyncCallback = mContext->getAsyncCallback();
-            if (asyncCallback == nullptr) {
-                // In blocking mode, mState can only be DRAINING.
-                mState = StreamDescriptor::State::IDLE;
-            } else {
-                // In a real implementation, the driver should notify the HAL about
-                // drain or transfer completion. In the stub, we switch unconditionally.
-                if (mState == StreamDescriptor::State::DRAINING) {
-                    mState = StreamDescriptor::State::IDLE;
-                    if (mOnDrainReadyStatus != OnDrainReadyStatus::SENT) {
-                        ndk::ScopedAStatus status = asyncCallback->onDrainReady();
-                        if (!status.isOk()) {
-                            LOG(ERROR) << __func__ << ": error from onDrainReady: " << status;
-                        }
-                        mOnDrainReadyStatus = OnDrainReadyStatus::SENT;
-                    }
-                } else {
-                    mState = StreamDescriptor::State::ACTIVE;
-                    ndk::ScopedAStatus status = asyncCallback->onTransferReady();
-                    if (!status.isOk()) {
-                        LOG(ERROR) << __func__ << ": error from onTransferReady: " << status;
-                    }
-                }
-            }
+            mState = StreamDescriptor::State::IDLE;
             if (mTransientStateDelayMs.count() != 0) {
                 LOG(DEBUG) << __func__ << ": switched to state " << toString(mState)
                            << " after a timeout";
@@ -552,10 +568,9 @@
                             mState = StreamDescriptor::State::IDLE;
                         } else {
                             switchToTransientState(StreamDescriptor::State::DRAINING);
-                            mOnDrainReadyStatus =
-                                    mode == StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY
-                                            ? OnDrainReadyStatus::UNSENT
-                                            : OnDrainReadyStatus::IGNORE;
+                            mDrainState = mode == StreamDescriptor::DrainMode::DRAIN_EARLY_NOTIFY
+                                                  ? DrainState::EN
+                                                  : DrainState::ALL;
                         }
                     } else {
                         LOG(ERROR) << __func__ << ": drain failed: " << status;
diff --git a/audio/aidl/default/alsa/StreamAlsa.cpp b/audio/aidl/default/alsa/StreamAlsa.cpp
index 210c26b..7a44cc7 100644
--- a/audio/aidl/default/alsa/StreamAlsa.cpp
+++ b/audio/aidl/default/alsa/StreamAlsa.cpp
@@ -72,7 +72,7 @@
     return source;
 }
 
-::android::status_t StreamAlsa::init() {
+::android::status_t StreamAlsa::init(DriverCallbackInterface* /*callback*/) {
     return mConfig.has_value() ? ::android::OK : ::android::NO_INIT;
 }
 
diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
index 6e1a811..77ce121 100644
--- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
@@ -70,7 +70,7 @@
     cleanupWorker();
 }
 
-::android::status_t StreamBluetooth::init() {
+::android::status_t StreamBluetooth::init(DriverCallbackInterface*) {
     std::lock_guard guard(mLock);
     if (mBtDeviceProxy == nullptr) {
         // This is a normal situation in VTS tests.
diff --git a/audio/aidl/default/include/core-impl/DriverStubImpl.h b/audio/aidl/default/include/core-impl/DriverStubImpl.h
index 40a9fea..84f869a 100644
--- a/audio/aidl/default/include/core-impl/DriverStubImpl.h
+++ b/audio/aidl/default/include/core-impl/DriverStubImpl.h
@@ -22,9 +22,11 @@
 
 class DriverStubImpl : virtual public DriverInterface {
   public:
-    explicit DriverStubImpl(const StreamContext& context);
+    explicit DriverStubImpl(const StreamContext& context)
+        : DriverStubImpl(context, 500 /*asyncSleepTimeUs*/) {}
+    DriverStubImpl(const StreamContext& context, int asyncSleepTimeUs);
 
-    ::android::status_t init() override;
+    ::android::status_t init(DriverCallbackInterface* callback) override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
     ::android::status_t flush() override;
     ::android::status_t pause() override;
@@ -34,12 +36,14 @@
                                  int32_t* latencyMs) override;
     void shutdown() override;
 
-  private:
+  protected:
     const size_t mBufferSizeFrames;
     const size_t mFrameSizeBytes;
     const int mSampleRate;
     const bool mIsAsynchronous;
     const bool mIsInput;
+    const int32_t mMixPortHandle;
+    const int mAsyncSleepTimeUs;
     bool mIsInitialized = false;  // Used for validating the state machine logic.
     bool mIsStandby = true;       // Used for validating the state machine logic.
     int64_t mStartTimeNs = 0;
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index cbc13d1..6a43102 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -148,10 +148,8 @@
     struct VendorDebug {
         static const std::string kForceTransientBurstName;
         static const std::string kForceSynchronousDrainName;
-        static const std::string kForceDrainToDrainingName;
         bool forceTransientBurst = false;
         bool forceSynchronousDrain = false;
-        bool forceDrainToDraining = false;
     };
     // ids of device ports created at runtime via 'connectExternalDevice'.
     // Also stores a list of ids of mix ports with dynamic profiles that were populated from
diff --git a/audio/aidl/default/include/core-impl/ModulePrimary.h b/audio/aidl/default/include/core-impl/ModulePrimary.h
index 82c8a03..a657dc5 100644
--- a/audio/aidl/default/include/core-impl/ModulePrimary.h
+++ b/audio/aidl/default/include/core-impl/ModulePrimary.h
@@ -28,6 +28,9 @@
   protected:
     ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
 
+    ndk::ScopedAStatus calculateBufferSizeFrames(
+            const ::aidl::android::media::audio::common::AudioFormatDescription& format,
+            int32_t latencyMs, int32_t sampleRateHz, int32_t* bufferSizeFrames) override;
     ndk::ScopedAStatus createInputStream(
             StreamContext&& context,
             const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 304f9b7..f0139b4 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -78,10 +78,6 @@
         bool forceTransientBurst = false;
         // Force the "drain" command to be synchronous, going directly to the IDLE state.
         bool forceSynchronousDrain = false;
-        // Force the "drain early notify" command to keep the SM in the DRAINING state
-        // after sending 'onDrainReady' callback. The SM moves to IDLE after
-        // 'transientStateDelayMs'.
-        bool forceDrainToDraining = false;
     };
 
     StreamContext() = default;
@@ -123,7 +119,6 @@
     ::aidl::android::media::audio::common::AudioIoFlags getFlags() const { return mFlags; }
     bool getForceTransientBurst() const { return mDebugParameters.forceTransientBurst; }
     bool getForceSynchronousDrain() const { return mDebugParameters.forceSynchronousDrain; }
-    bool getForceDrainToDraining() const { return mDebugParameters.forceDrainToDraining; }
     size_t getFrameSize() const;
     int getInternalCommandCookie() const { return mInternalCommandCookie; }
     int32_t getMixPortHandle() const { return mMixPortHandle; }
@@ -146,8 +141,8 @@
     // locking because it only cleans MQ pointers which were also set on the Binder thread.
     void reset();
     // 'advanceFrameCount' and 'getFrameCount' are only called on the worker thread.
-    long advanceFrameCount(size_t increase) { return mFrameCount += increase; }
-    long getFrameCount() const { return mFrameCount; }
+    int64_t advanceFrameCount(size_t increase) { return mFrameCount += increase; }
+    int64_t getFrameCount() const { return mFrameCount; }
 
   private:
     // Fields are non const to allow move assignment.
@@ -165,14 +160,30 @@
     std::shared_ptr<IStreamOutEventCallback> mOutEventCallback;  // Only used by output streams
     std::weak_ptr<sounddose::StreamDataProcessorInterface> mStreamDataProcessor;
     DebugParameters mDebugParameters;
-    long mFrameCount = 0;
+    int64_t mFrameCount = 0;
+};
+
+// Driver callbacks are executed on a dedicated thread, not on the worker thread.
+struct DriverCallbackInterface {
+    virtual ~DriverCallbackInterface() = default;
+    // Both callbacks are used to notify the worker about the progress of the playback
+    // offloaded to the DSP.
+
+    //   'bufferFramesLeft' is how many *encoded* frames are left in the buffer until
+    //    it depletes.
+    virtual void onBufferStateChange(size_t bufferFramesLeft) = 0;
+    //   'clipFramesLeft' is how many *decoded* frames are left until the end of the currently
+    //    playing clip. '0' frames left means that the clip has ended (by itself or due
+    //    to draining).
+    //   'hasNextClip' indicates whether the DSP has audio data for the next clip.
+    virtual void onClipStateChange(size_t clipFramesLeft, bool hasNextClip) = 0;
 };
 
 // This interface provides operations of the stream which are executed on the worker thread.
 struct DriverInterface {
     virtual ~DriverInterface() = default;
     // All the methods below are called on the worker thread.
-    virtual ::android::status_t init() = 0;  // This function is only called once.
+    virtual ::android::status_t init(DriverCallbackInterface* callback) = 0;  // Called once.
     virtual ::android::status_t drain(StreamDescriptor::DrainMode mode) = 0;
     virtual ::android::status_t flush() = 0;
     virtual ::android::status_t pause() = 0;
@@ -194,7 +205,8 @@
     virtual void shutdown() = 0;  // This function is only called once.
 };
 
-class StreamWorkerCommonLogic : public ::android::hardware::audio::common::StreamLogic {
+class StreamWorkerCommonLogic : public ::android::hardware::audio::common::StreamLogic,
+                                public DriverCallbackInterface {
   public:
     bool isClosed() const { return mState == StreamContext::STATE_CLOSED; }
     StreamDescriptor::State setClosed() {
@@ -214,7 +226,13 @@
           mDriver(driver),
           mTransientStateDelayMs(context->getTransientStateDelayMs()) {}
     pid_t getTid() const;
+
+    // ::android::hardware::audio::common::StreamLogic
     std::string init() override;
+    // DriverCallbackInterface
+    void onBufferStateChange(size_t bufferFramesLeft) override;
+    void onClipStateChange(size_t clipFramesLeft, bool hasNextClip) override;
+
     void populateReply(StreamDescriptor::Reply* reply, bool isConnected) const;
     void populateReplyWrongState(StreamDescriptor::Reply* reply,
                                  const StreamDescriptor::Command& command) const;
@@ -301,14 +319,17 @@
 
   protected:
     Status cycle() override;
+    // DriverCallbackInterface
+    void onBufferStateChange(size_t bufferFramesLeft) override;
+    void onClipStateChange(size_t clipFramesLeft, bool hasNextClip) override;
 
   private:
     bool write(size_t clientSize, StreamDescriptor::Reply* reply);
 
     std::shared_ptr<IStreamOutEventCallback> mEventCallback;
 
-    enum OnDrainReadyStatus : int32_t { IGNORE /*used for DRAIN_ALL*/, UNSENT, SENT };
-    OnDrainReadyStatus mOnDrainReadyStatus = OnDrainReadyStatus::IGNORE;
+    enum DrainState : int32_t { NONE, ALL, EN /*early notify*/, EN_SENT };
+    std::atomic<DrainState> mDrainState = DrainState::NONE;
 };
 using StreamOutWorker = StreamWorkerImpl<StreamOutWorkerLogic>;
 
diff --git a/audio/aidl/default/include/core-impl/StreamAlsa.h b/audio/aidl/default/include/core-impl/StreamAlsa.h
index 7e0f0ac..c0dcb63 100644
--- a/audio/aidl/default/include/core-impl/StreamAlsa.h
+++ b/audio/aidl/default/include/core-impl/StreamAlsa.h
@@ -40,7 +40,7 @@
     ~StreamAlsa();
 
     // Methods of 'DriverInterface'.
-    ::android::status_t init() override;
+    ::android::status_t init(DriverCallbackInterface* callback) override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
     ::android::status_t flush() override;
     ::android::status_t pause() override;
diff --git a/audio/aidl/default/include/core-impl/StreamBluetooth.h b/audio/aidl/default/include/core-impl/StreamBluetooth.h
index 357a546..2bdd6b2 100644
--- a/audio/aidl/default/include/core-impl/StreamBluetooth.h
+++ b/audio/aidl/default/include/core-impl/StreamBluetooth.h
@@ -44,7 +44,7 @@
     ~StreamBluetooth();
 
     // Methods of 'DriverInterface'.
-    ::android::status_t init() override;
+    ::android::status_t init(DriverCallbackInterface*) override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
     ::android::status_t flush() override;
     ::android::status_t pause() override;
diff --git a/audio/aidl/default/include/core-impl/StreamOffloadStub.h b/audio/aidl/default/include/core-impl/StreamOffloadStub.h
new file mode 100644
index 0000000..67abe95
--- /dev/null
+++ b/audio/aidl/default/include/core-impl/StreamOffloadStub.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <mutex>
+#include <set>
+#include <string>
+
+#include "core-impl/DriverStubImpl.h"
+#include "core-impl/Stream.h"
+
+namespace aidl::android::hardware::audio::core {
+
+struct DspSimulatorState {
+    const std::string formatEncoding;
+    const int sampleRate;
+    const int64_t earlyNotifyFrames;
+    const int64_t bufferNotifyFrames;
+    DriverCallbackInterface* callback = nullptr;  // set before starting DSP worker
+    std::mutex lock;
+    std::vector<int64_t> clipFramesLeft GUARDED_BY(lock);
+    int64_t bufferFramesLeft GUARDED_BY(lock);
+};
+
+class DspSimulatorLogic : public ::android::hardware::audio::common::StreamLogic {
+  protected:
+    explicit DspSimulatorLogic(DspSimulatorState& sharedState) : mSharedState(sharedState) {}
+    std::string init() override;
+    Status cycle() override;
+
+  private:
+    DspSimulatorState& mSharedState;
+};
+
+class DspSimulatorWorker
+    : public ::android::hardware::audio::common::StreamWorker<DspSimulatorLogic> {
+  public:
+    explicit DspSimulatorWorker(DspSimulatorState& sharedState)
+        : ::android::hardware::audio::common::StreamWorker<DspSimulatorLogic>(sharedState) {}
+};
+
+class DriverOffloadStubImpl : public DriverStubImpl {
+  public:
+    DriverOffloadStubImpl(const StreamContext& context);
+    ::android::status_t init(DriverCallbackInterface* callback) override;
+    ::android::status_t drain(StreamDescriptor::DrainMode drainMode) override;
+    ::android::status_t flush() override;
+    ::android::status_t pause() override;
+    ::android::status_t start() override;
+    ::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
+                                 int32_t* latencyMs) override;
+    void shutdown() override;
+
+  private:
+    ::android::status_t startWorkerIfNeeded();
+
+    DspSimulatorState mState;
+    DspSimulatorWorker mDspWorker;
+    bool mDspWorkerStarted = false;
+};
+
+class StreamOffloadStub : public StreamCommonImpl, public DriverOffloadStubImpl {
+  public:
+    static const std::set<std::string>& getSupportedEncodings();
+
+    StreamOffloadStub(StreamContext* context, const Metadata& metadata);
+    ~StreamOffloadStub();
+};
+
+class StreamOutOffloadStub final : public StreamOut, public StreamOffloadStub {
+  public:
+    friend class ndk::SharedRefBase;
+    StreamOutOffloadStub(
+            StreamContext&& context,
+            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
+            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
+                    offloadInfo);
+
+  private:
+    void onClose(StreamDescriptor::State) override { defaultOnClose(); }
+};
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/StreamPrimary.h b/audio/aidl/default/include/core-impl/StreamPrimary.h
index 4f19a46..06f8bc3 100644
--- a/audio/aidl/default/include/core-impl/StreamPrimary.h
+++ b/audio/aidl/default/include/core-impl/StreamPrimary.h
@@ -32,7 +32,7 @@
     StreamPrimary(StreamContext* context, const Metadata& metadata);
 
     // Methods of 'DriverInterface'.
-    ::android::status_t init() override;
+    ::android::status_t init(DriverCallbackInterface* callback) override;
     ::android::status_t drain(StreamDescriptor::DrainMode mode) override;
     ::android::status_t flush() override;
     ::android::status_t pause() override;
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index 5e52ad0..28a446a 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -32,7 +32,7 @@
     ~StreamRemoteSubmix();
 
     // Methods of 'DriverInterface'.
-    ::android::status_t init() override;
+    ::android::status_t init(DriverCallbackInterface*) override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
     ::android::status_t flush() override;
     ::android::status_t pause() override;
diff --git a/audio/aidl/default/primary/StreamPrimary.cpp b/audio/aidl/default/primary/StreamPrimary.cpp
index 46e384e..8455680 100644
--- a/audio/aidl/default/primary/StreamPrimary.cpp
+++ b/audio/aidl/default/primary/StreamPrimary.cpp
@@ -46,9 +46,9 @@
     context->startStreamDataProcessor();
 }
 
-::android::status_t StreamPrimary::init() {
-    RETURN_STATUS_IF_ERROR(mStubDriver.init());
-    return StreamAlsa::init();
+::android::status_t StreamPrimary::init(DriverCallbackInterface* callback) {
+    RETURN_STATUS_IF_ERROR(mStubDriver.init(callback));
+    return StreamAlsa::init(callback);
 }
 
 ::android::status_t StreamPrimary::drain(StreamDescriptor::DrainMode mode) {
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index f8ead16..cc3c644 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -51,7 +51,7 @@
     cleanupWorker();
 }
 
-::android::status_t StreamRemoteSubmix::init() {
+::android::status_t StreamRemoteSubmix::init(DriverCallbackInterface*) {
     mCurrentRoute = SubmixRoute::findOrCreateRoute(mDeviceAddress, mStreamConfig);
     if (mCurrentRoute == nullptr) {
         return ::android::NO_INIT;
diff --git a/audio/aidl/default/stub/ApeHeader.cpp b/audio/aidl/default/stub/ApeHeader.cpp
new file mode 100644
index 0000000..9112377
--- /dev/null
+++ b/audio/aidl/default/stub/ApeHeader.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AHAL_OffloadStream"
+#include <android-base/logging.h>
+
+#include "ApeHeader.h"
+
+namespace aidl::android::hardware::audio::core {
+
+static constexpr uint32_t kApeSignature1 = 0x2043414d;  // 'MAC ';
+static constexpr uint32_t kApeSignature2 = 0x4643414d;  // 'MACF';
+static constexpr uint16_t kMinimumVersion = 3980;
+
+void* findApeHeader(void* buffer, size_t bufferSizeBytes, ApeHeader** header) {
+    auto advanceBy = [&](size_t bytes) -> void* {
+        buffer = static_cast<uint8_t*>(buffer) + bytes;
+        bufferSizeBytes -= bytes;
+        return buffer;
+    };
+
+    while (bufferSizeBytes >= sizeof(ApeDescriptor) + sizeof(ApeHeader)) {
+        ApeDescriptor* descPtr = static_cast<ApeDescriptor*>(buffer);
+        if (descPtr->signature != kApeSignature1 && descPtr->signature != kApeSignature2) {
+            advanceBy(sizeof(descPtr->signature));
+            continue;
+        }
+        if (descPtr->version < kMinimumVersion) {
+            LOG(ERROR) << __func__ << ": Unsupported APE version: " << descPtr->version
+                       << ", minimum supported version: " << kMinimumVersion;
+            // Older versions only have a header, which is of the size similar to the modern header.
+            advanceBy(sizeof(ApeHeader));
+            continue;
+        }
+        if (descPtr->descriptorSizeBytes > bufferSizeBytes) {
+            LOG(ERROR) << __func__
+                       << ": Invalid APE descriptor size: " << descPtr->descriptorSizeBytes
+                       << ", overruns remaining buffer size: " << bufferSizeBytes;
+            advanceBy(sizeof(ApeDescriptor));
+            continue;
+        }
+        advanceBy(descPtr->descriptorSizeBytes);
+        if (sizeof(ApeHeader) > bufferSizeBytes) {
+            LOG(ERROR) << __func__ << ": APE header is incomplete, want: " << sizeof(ApeHeader)
+                       << " bytes, have: " << bufferSizeBytes;
+            return nullptr;
+        }
+        *header = static_cast<ApeHeader*>(buffer);
+        return advanceBy(sizeof(ApeHeader));
+    }
+    return nullptr;
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/stub/ApeHeader.h b/audio/aidl/default/stub/ApeHeader.h
new file mode 100644
index 0000000..df30335
--- /dev/null
+++ b/audio/aidl/default/stub/ApeHeader.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+namespace aidl::android::hardware::audio::core {
+
+// Simplified APE (Monkey Audio) header definition sufficient to figure out
+// the basic parameters of the encoded file. Only supports the "current"
+// versions of the header (>= 3980).
+
+#pragma pack(push, 4)
+
+// Only the beginning of the descriptor is needed to find the header which
+// follows the descriptor.
+struct ApeDescriptor {
+    uint32_t signature;  // 'MAC ' or 'MACF'
+    uint16_t version;
+    uint16_t padding;
+    uint32_t descriptorSizeBytes;
+    uint32_t headerSizeBytes;
+};
+
+struct ApeHeader {
+    uint16_t compressionLevel;
+    uint16_t flags;
+    uint32_t blocksPerFrame;   // "frames" are encoder frames, while "blocks" are audio frames
+    uint32_t lastFrameBlocks;  // number of "blocks" in the last encoder "frame"
+    uint32_t totalFrames;      // total number of encoder "frames"
+    uint16_t bitsPerSample;
+    uint16_t channelCount;
+    uint32_t sampleRate;
+};
+
+#pragma pack(pop)
+
+// Tries to find APE descriptor and header in the buffer. Returns the position
+// after the header or nullptr if it was not found.
+void* findApeHeader(void* buffer, size_t bufferSizeBytes, ApeHeader** header);
+
+// Clip duration in audio frames ("blocks" in the APE terminology).
+inline int64_t getApeClipDurationFrames(const ApeHeader* header) {
+    return header->totalFrames != 0
+                   ? (header->totalFrames - 1) * header->blocksPerFrame + header->lastFrameBlocks
+                   : 0;
+}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/stub/DriverStubImpl.cpp b/audio/aidl/default/stub/DriverStubImpl.cpp
index beb0114..0d129e6 100644
--- a/audio/aidl/default/stub/DriverStubImpl.cpp
+++ b/audio/aidl/default/stub/DriverStubImpl.cpp
@@ -24,19 +24,27 @@
 
 namespace aidl::android::hardware::audio::core {
 
-DriverStubImpl::DriverStubImpl(const StreamContext& context)
+DriverStubImpl::DriverStubImpl(const StreamContext& context, int asyncSleepTimeUs)
     : mBufferSizeFrames(context.getBufferSizeInFrames()),
       mFrameSizeBytes(context.getFrameSize()),
       mSampleRate(context.getSampleRate()),
       mIsAsynchronous(!!context.getAsyncCallback()),
-      mIsInput(context.isInput()) {}
+      mIsInput(context.isInput()),
+      mMixPortHandle(context.getMixPortHandle()),
+      mAsyncSleepTimeUs(asyncSleepTimeUs) {}
 
-::android::status_t DriverStubImpl::init() {
+#define LOG_ENTRY()                                                                          \
+    LOG(DEBUG) << "[" << (mIsInput ? "in" : "out") << "|ioHandle:" << mMixPortHandle << "] " \
+               << __func__;
+
+::android::status_t DriverStubImpl::init(DriverCallbackInterface* /*callback*/) {
+    LOG_ENTRY();
     mIsInitialized = true;
     return ::android::OK;
 }
 
 ::android::status_t DriverStubImpl::drain(StreamDescriptor::DrainMode) {
+    LOG_ENTRY();
     if (!mIsInitialized) {
         LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
     }
@@ -46,14 +54,15 @@
             const size_t delayUs = static_cast<size_t>(
                     std::roundf(mBufferSizeFrames * kMicrosPerSecond / mSampleRate));
             usleep(delayUs);
-        } else {
-            usleep(500);
+        } else if (mAsyncSleepTimeUs) {
+            usleep(mAsyncSleepTimeUs);
         }
     }
     return ::android::OK;
 }
 
 ::android::status_t DriverStubImpl::flush() {
+    LOG_ENTRY();
     if (!mIsInitialized) {
         LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
     }
@@ -61,6 +70,7 @@
 }
 
 ::android::status_t DriverStubImpl::pause() {
+    LOG_ENTRY();
     if (!mIsInitialized) {
         LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
     }
@@ -68,6 +78,7 @@
 }
 
 ::android::status_t DriverStubImpl::standby() {
+    LOG_ENTRY();
     if (!mIsInitialized) {
         LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
     }
@@ -76,6 +87,7 @@
 }
 
 ::android::status_t DriverStubImpl::start() {
+    LOG_ENTRY();
     if (!mIsInitialized) {
         LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
     }
@@ -87,6 +99,7 @@
 
 ::android::status_t DriverStubImpl::transfer(void* buffer, size_t frameCount,
                                              size_t* actualFrameCount, int32_t*) {
+    // No LOG_ENTRY as this is called very often.
     if (!mIsInitialized) {
         LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
     }
@@ -95,7 +108,7 @@
     }
     *actualFrameCount = frameCount;
     if (mIsAsynchronous) {
-        usleep(500);
+        if (mAsyncSleepTimeUs) usleep(mAsyncSleepTimeUs);
     } else {
         mFramesSinceStart += *actualFrameCount;
         const long bufferDurationUs = (*actualFrameCount) * MICROS_PER_SECOND / mSampleRate;
@@ -120,6 +133,7 @@
 }
 
 void DriverStubImpl::shutdown() {
+    LOG_ENTRY();
     mIsInitialized = false;
 }
 
diff --git a/audio/aidl/default/stub/StreamOffloadStub.cpp b/audio/aidl/default/stub/StreamOffloadStub.cpp
new file mode 100644
index 0000000..95cef35
--- /dev/null
+++ b/audio/aidl/default/stub/StreamOffloadStub.cpp
@@ -0,0 +1,230 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AHAL_OffloadStream"
+#include <android-base/logging.h>
+#include <audio_utils/clock.h>
+#include <error/Result.h>
+#include <utils/SystemClock.h>
+
+#include "ApeHeader.h"
+#include "core-impl/StreamOffloadStub.h"
+
+using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioOffloadInfo;
+using aidl::android::media::audio::common::MicrophoneInfo;
+
+namespace aidl::android::hardware::audio::core {
+
+std::string DspSimulatorLogic::init() {
+    return "";
+}
+
+DspSimulatorLogic::Status DspSimulatorLogic::cycle() {
+    std::vector<std::pair<int64_t, bool>> clipNotifies;
+    // Simulate playback.
+    const int64_t timeBeginNs = ::android::uptimeNanos();
+    usleep(1000);
+    const int64_t clipFramesPlayed =
+            (::android::uptimeNanos() - timeBeginNs) * mSharedState.sampleRate / NANOS_PER_SECOND;
+    const int64_t bufferFramesConsumed = clipFramesPlayed / 2;  // assume 1:2 compression ratio
+    int64_t bufferFramesLeft = 0;
+    {
+        std::lock_guard l(mSharedState.lock);
+        mSharedState.bufferFramesLeft =
+                mSharedState.bufferFramesLeft > bufferFramesConsumed
+                        ? mSharedState.bufferFramesLeft - bufferFramesConsumed
+                        : 0;
+        bufferFramesLeft = mSharedState.bufferFramesLeft;
+        int64_t framesPlayed = clipFramesPlayed;
+        while (framesPlayed > 0 && !mSharedState.clipFramesLeft.empty()) {
+            LOG(VERBOSE) << __func__ << ": clips: "
+                         << ::android::internal::ToString(mSharedState.clipFramesLeft);
+            const bool hasNextClip = mSharedState.clipFramesLeft.size() > 1;
+            if (mSharedState.clipFramesLeft[0] > framesPlayed) {
+                mSharedState.clipFramesLeft[0] -= framesPlayed;
+                framesPlayed = 0;
+                if (mSharedState.clipFramesLeft[0] <= mSharedState.earlyNotifyFrames) {
+                    clipNotifies.emplace_back(mSharedState.clipFramesLeft[0], hasNextClip);
+                }
+            } else {
+                clipNotifies.emplace_back(0 /*clipFramesLeft*/, hasNextClip);
+                framesPlayed -= mSharedState.clipFramesLeft[0];
+                mSharedState.clipFramesLeft.erase(mSharedState.clipFramesLeft.begin());
+            }
+        }
+    }
+    if (bufferFramesLeft <= mSharedState.bufferNotifyFrames) {
+        LOG(DEBUG) << __func__ << ": sending onBufferStateChange: " << bufferFramesLeft;
+        mSharedState.callback->onBufferStateChange(bufferFramesLeft);
+    }
+    for (const auto& notify : clipNotifies) {
+        LOG(DEBUG) << __func__ << ": sending onClipStateChange: " << notify.first << ", "
+                   << notify.second;
+        mSharedState.callback->onClipStateChange(notify.first, notify.second);
+    }
+    return Status::CONTINUE;
+}
+
+DriverOffloadStubImpl::DriverOffloadStubImpl(const StreamContext& context)
+    : DriverStubImpl(context, 0 /*asyncSleepTimeUs*/),
+      mState{context.getFormat().encoding, context.getSampleRate(),
+             250 /*earlyNotifyMs*/ * context.getSampleRate() / MILLIS_PER_SECOND,
+             static_cast<int64_t>(context.getBufferSizeInFrames()) / 2},
+      mDspWorker(mState) {
+    LOG_IF(FATAL, !mIsAsynchronous) << "The steam must be used in asynchronous mode";
+}
+
+::android::status_t DriverOffloadStubImpl::init(DriverCallbackInterface* callback) {
+    RETURN_STATUS_IF_ERROR(DriverStubImpl::init(callback));
+    if (!StreamOffloadStub::getSupportedEncodings().count(mState.formatEncoding)) {
+        LOG(ERROR) << __func__ << ": encoded format \"" << mState.formatEncoding
+                   << "\" is not supported";
+        return ::android::NO_INIT;
+    }
+    mState.callback = callback;
+    return ::android::OK;
+}
+
+::android::status_t DriverOffloadStubImpl::drain(StreamDescriptor::DrainMode drainMode) {
+    RETURN_STATUS_IF_ERROR(DriverStubImpl::drain(drainMode));
+    std::lock_guard l(mState.lock);
+    if (!mState.clipFramesLeft.empty()) {
+        // Cut playback of the current clip.
+        mState.clipFramesLeft[0] = std::min(mState.earlyNotifyFrames * 2, mState.clipFramesLeft[0]);
+        if (drainMode == StreamDescriptor::DrainMode::DRAIN_ALL) {
+            // Make sure there are no clips after the current one.
+            mState.clipFramesLeft.resize(1);
+        }
+    }
+    return ::android::OK;
+}
+
+::android::status_t DriverOffloadStubImpl::flush() {
+    RETURN_STATUS_IF_ERROR(DriverStubImpl::flush());
+    mDspWorker.pause();
+    {
+        std::lock_guard l(mState.lock);
+        mState.clipFramesLeft.clear();
+        mState.bufferFramesLeft = 0;
+    }
+    return ::android::OK;
+}
+
+::android::status_t DriverOffloadStubImpl::pause() {
+    RETURN_STATUS_IF_ERROR(DriverStubImpl::pause());
+    mDspWorker.pause();
+    return ::android::OK;
+}
+
+::android::status_t DriverOffloadStubImpl::start() {
+    RETURN_STATUS_IF_ERROR(DriverStubImpl::start());
+    RETURN_STATUS_IF_ERROR(startWorkerIfNeeded());
+    bool hasClips;  // Can be start after paused draining.
+    {
+        std::lock_guard l(mState.lock);
+        hasClips = !mState.clipFramesLeft.empty();
+        LOG(DEBUG) << __func__
+                   << ": clipFramesLeft: " << ::android::internal::ToString(mState.clipFramesLeft);
+    }
+    if (hasClips) {
+        mDspWorker.resume();
+    }
+    return ::android::OK;
+}
+
+::android::status_t DriverOffloadStubImpl::transfer(void* buffer, size_t frameCount,
+                                                    size_t* actualFrameCount, int32_t* latencyMs) {
+    RETURN_STATUS_IF_ERROR(
+            DriverStubImpl::transfer(buffer, frameCount, actualFrameCount, latencyMs));
+    RETURN_STATUS_IF_ERROR(startWorkerIfNeeded());
+    // Scan the buffer for clip headers.
+    *actualFrameCount = frameCount;
+    while (buffer != nullptr && frameCount > 0) {
+        ApeHeader* apeHeader = nullptr;
+        void* prevBuffer = buffer;
+        buffer = findApeHeader(prevBuffer, frameCount * mFrameSizeBytes, &apeHeader);
+        if (buffer != nullptr && apeHeader != nullptr) {
+            // Frame count does not include the size of the header data.
+            const size_t headerSizeFrames =
+                    (static_cast<uint8_t*>(buffer) - static_cast<uint8_t*>(prevBuffer)) /
+                    mFrameSizeBytes;
+            frameCount -= headerSizeFrames;
+            *actualFrameCount = frameCount;
+            // Stage the clip duration into the DSP worker's queue.
+            const int64_t clipDurationFrames = getApeClipDurationFrames(apeHeader);
+            const int32_t clipSampleRate = apeHeader->sampleRate;
+            LOG(DEBUG) << __func__ << ": found APE clip of " << clipDurationFrames << " frames, "
+                       << "sample rate: " << clipSampleRate;
+            if (clipSampleRate == mState.sampleRate) {
+                std::lock_guard l(mState.lock);
+                mState.clipFramesLeft.push_back(clipDurationFrames);
+            } else {
+                LOG(ERROR) << __func__ << ": clip sample rate " << clipSampleRate
+                           << " does not match stream sample rate " << mState.sampleRate;
+            }
+        } else {
+            frameCount = 0;
+        }
+    }
+    {
+        std::lock_guard l(mState.lock);
+        mState.bufferFramesLeft = *actualFrameCount;
+    }
+    mDspWorker.resume();
+    return ::android::OK;
+}
+
+void DriverOffloadStubImpl::shutdown() {
+    LOG(DEBUG) << __func__ << ": stopping the DSP simulator worker";
+    mDspWorker.stop();
+    DriverStubImpl::shutdown();
+}
+
+::android::status_t DriverOffloadStubImpl::startWorkerIfNeeded() {
+    if (!mDspWorkerStarted) {
+        // This is an "audio service thread," must have elevated priority.
+        if (!mDspWorker.start("dsp_sim", ANDROID_PRIORITY_URGENT_AUDIO)) {
+            return ::android::NO_INIT;
+        }
+        mDspWorkerStarted = true;
+    }
+    return ::android::OK;
+}
+
+// static
+const std::set<std::string>& StreamOffloadStub::getSupportedEncodings() {
+    static const std::set<std::string> kSupportedEncodings = {
+            "audio/x-ape",
+    };
+    return kSupportedEncodings;
+}
+
+StreamOffloadStub::StreamOffloadStub(StreamContext* context, const Metadata& metadata)
+    : StreamCommonImpl(context, metadata), DriverOffloadStubImpl(getContext()) {}
+
+StreamOffloadStub::~StreamOffloadStub() {
+    cleanupWorker();
+}
+
+StreamOutOffloadStub::StreamOutOffloadStub(StreamContext&& context,
+                                           const SourceMetadata& sourceMetadata,
+                                           const std::optional<AudioOffloadInfo>& offloadInfo)
+    : StreamOut(std::move(context), offloadInfo),
+      StreamOffloadStub(&mContextInstance, sourceMetadata) {}
+
+}  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/stub/StreamStub.cpp b/audio/aidl/default/stub/StreamStub.cpp
index f6c87e1..2278880 100644
--- a/audio/aidl/default/stub/StreamStub.cpp
+++ b/audio/aidl/default/stub/StreamStub.cpp
@@ -14,11 +14,8 @@
  * limitations under the License.
  */
 
-#include <cmath>
-
 #define LOG_TAG "AHAL_Stream"
 #include <android-base/logging.h>
-#include <audio_utils/clock.h>
 
 #include "core-impl/Module.h"
 #include "core-impl/StreamStub.h"
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 14e70ef..f855038 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -41,7 +41,6 @@
         "-Wthread-safety",
         "-Wno-error=unused-parameter",
     ],
-    test_config_template: "VtsHalAudioTargetTestTemplate.xml",
     test_suites: [
         "general-tests",
         "vts",
@@ -60,6 +59,7 @@
     srcs: [
         ":effectCommonFile",
     ],
+    test_config_template: "VtsHalAudioEffectTargetTestTemplate.xml",
 }
 
 cc_test {
@@ -77,6 +77,11 @@
         "VtsHalAudioCoreConfigTargetTest.cpp",
         "VtsHalAudioCoreModuleTargetTest.cpp",
     ],
+    data: [
+        "data/sine882hz_44100_3s.ape",
+        "data/sine960hz_48000_3s.ape",
+    ],
+    test_config_template: "VtsHalAudioCoreTargetTestTemplate.xml",
 }
 
 cc_test {
diff --git a/audio/aidl/vts/ModuleConfig.cpp b/audio/aidl/vts/ModuleConfig.cpp
index d24c4c8..7d4cc70 100644
--- a/audio/aidl/vts/ModuleConfig.cpp
+++ b/audio/aidl/vts/ModuleConfig.cpp
@@ -36,12 +36,10 @@
 using aidl::android::media::audio::common::AudioChannelLayout;
 using aidl::android::media::audio::common::AudioDeviceDescription;
 using aidl::android::media::audio::common::AudioDeviceType;
-using aidl::android::media::audio::common::AudioEncapsulationMode;
 using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioInputFlags;
 using aidl::android::media::audio::common::AudioIoFlags;
-using aidl::android::media::audio::common::AudioOffloadInfo;
 using aidl::android::media::audio::common::AudioOutputFlags;
 using aidl::android::media::audio::common::AudioPort;
 using aidl::android::media::audio::common::AudioPortConfig;
@@ -51,26 +49,6 @@
 using aidl::android::media::audio::common::Int;
 
 // static
-std::optional<AudioOffloadInfo> ModuleConfig::generateOffloadInfoIfNeeded(
-        const AudioPortConfig& portConfig) {
-    if (portConfig.flags.has_value() &&
-        portConfig.flags.value().getTag() == AudioIoFlags::Tag::output &&
-        isBitPositionFlagSet(portConfig.flags.value().get<AudioIoFlags::Tag::output>(),
-                             AudioOutputFlags::COMPRESS_OFFLOAD)) {
-        AudioOffloadInfo offloadInfo;
-        offloadInfo.base.sampleRate = portConfig.sampleRate.value().value;
-        offloadInfo.base.channelMask = portConfig.channelMask.value();
-        offloadInfo.base.format = portConfig.format.value();
-        offloadInfo.bitRatePerSecond = 256000;                             // Arbitrary value.
-        offloadInfo.durationUs = std::chrono::microseconds(1min).count();  // Arbitrary value.
-        offloadInfo.usage = AudioUsage::MEDIA;
-        offloadInfo.encapsulationMode = AudioEncapsulationMode::NONE;
-        return offloadInfo;
-    }
-    return {};
-}
-
-// static
 std::vector<aidl::android::media::audio::common::AudioPort>
 ModuleConfig::getAudioPortsForDeviceTypes(
         const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
diff --git a/audio/aidl/vts/ModuleConfig.h b/audio/aidl/vts/ModuleConfig.h
index 27286e5..d45ccda 100644
--- a/audio/aidl/vts/ModuleConfig.h
+++ b/audio/aidl/vts/ModuleConfig.h
@@ -34,10 +34,6 @@
     using SrcSinkGroup =
             std::pair<aidl::android::hardware::audio::core::AudioRoute, std::vector<SrcSinkPair>>;
 
-    static std::optional<aidl::android::media::audio::common::AudioOffloadInfo>
-    generateOffloadInfoIfNeeded(
-            const aidl::android::media::audio::common::AudioPortConfig& portConfig);
-
     static std::vector<aidl::android::media::audio::common::AudioPort> getAudioPortsForDeviceTypes(
             const std::vector<aidl::android::media::audio::common::AudioPort>& ports,
             const std::vector<aidl::android::media::audio::common::AudioDeviceType>& deviceTypes,
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 750e54d..21b7aff 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -19,6 +19,7 @@
 #include <cmath>
 #include <condition_variable>
 #include <forward_list>
+#include <fstream>
 #include <limits>
 #include <memory>
 #include <mutex>
@@ -81,12 +82,15 @@
 using aidl::android::hardware::audio::core::sounddose::ISoundDose;
 using aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioConfigBase;
 using aidl::android::media::audio::common::AudioContentType;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioDeviceAddress;
 using aidl::android::media::audio::common::AudioDeviceDescription;
 using aidl::android::media::audio::common::AudioDeviceType;
 using aidl::android::media::audio::common::AudioDualMonoMode;
+using aidl::android::media::audio::common::AudioEncapsulationMode;
+using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioGainConfig;
 using aidl::android::media::audio::common::AudioInputFlags;
@@ -96,6 +100,7 @@
 using aidl::android::media::audio::common::AudioMMapPolicyInfo;
 using aidl::android::media::audio::common::AudioMMapPolicyType;
 using aidl::android::media::audio::common::AudioMode;
+using aidl::android::media::audio::common::AudioOffloadInfo;
 using aidl::android::media::audio::common::AudioOutputFlags;
 using aidl::android::media::audio::common::AudioPlaybackRate;
 using aidl::android::media::audio::common::AudioPort;
@@ -217,6 +222,59 @@
     return result;
 }
 
+static const AudioFormatDescription kApeFileAudioFormat = {.encoding = "audio/x-ape"};
+static const AudioChannelLayout kApeFileChannelMask =
+        AudioChannelLayout::make<AudioChannelLayout::layoutMask>(AudioChannelLayout::LAYOUT_MONO);
+struct MediaFileInfo {
+    std::string path;
+    int32_t bps;
+    int32_t durationMs;
+};
+static const std::map<AudioConfigBase, MediaFileInfo> kMediaFileDataInfos = {
+        {{44100, kApeFileChannelMask, kApeFileAudioFormat},
+         {"/data/local/tmp/sine882hz_44100_3s.ape", 217704, 3000}},
+        {{48000, kApeFileChannelMask, kApeFileAudioFormat},
+         {"/data/local/tmp/sine960hz_48000_3s.ape", 236256, 3000}},
+};
+
+std::optional<MediaFileInfo> getMediaFileInfoForConfig(const AudioConfigBase& config) {
+    const auto it = kMediaFileDataInfos.find(config);
+    if (it != kMediaFileDataInfos.end()) return it->second;
+    return std::nullopt;
+}
+
+std::optional<MediaFileInfo> getMediaFileInfoForConfig(const AudioPortConfig& config) {
+    if (!config.sampleRate.has_value() || !config.format.has_value() ||
+        !config.channelMask.has_value()) {
+        return std::nullopt;
+    }
+    return getMediaFileInfoForConfig(AudioConfigBase{
+            config.sampleRate->value, config.channelMask.value(), config.format.value()});
+}
+
+std::optional<AudioOffloadInfo> generateOffloadInfoIfNeeded(const AudioPortConfig& portConfig) {
+    if (portConfig.flags.has_value() &&
+        portConfig.flags.value().getTag() == AudioIoFlags::Tag::output &&
+        isBitPositionFlagSet(portConfig.flags.value().get<AudioIoFlags::Tag::output>(),
+                             AudioOutputFlags::COMPRESS_OFFLOAD)) {
+        AudioOffloadInfo offloadInfo;
+        offloadInfo.base.sampleRate = portConfig.sampleRate.value().value;
+        offloadInfo.base.channelMask = portConfig.channelMask.value();
+        offloadInfo.base.format = portConfig.format.value();
+        if (auto info = getMediaFileInfoForConfig(portConfig); info.has_value()) {
+            offloadInfo.bitRatePerSecond = info->bps;
+            offloadInfo.durationUs = info->durationMs * 1000LL;
+        } else {
+            offloadInfo.bitRatePerSecond = 256000;                             // Arbitrary value.
+            offloadInfo.durationUs = std::chrono::microseconds(1min).count();  // Arbitrary value.
+        }
+        offloadInfo.usage = AudioUsage::MEDIA;
+        offloadInfo.encapsulationMode = AudioEncapsulationMode::NONE;
+        return offloadInfo;
+    }
+    return {};
+}
+
 // All 'With*' classes are move-only because they are associated with some
 // resource or state of a HAL module.
 class WithDebugFlags {
@@ -652,11 +710,14 @@
     typedef AidlMessageQueue<StreamDescriptor::Reply, SynchronizedReadWrite> ReplyMQ;
     typedef AidlMessageQueue<int8_t, SynchronizedReadWrite> DataMQ;
 
-    explicit StreamContext(const StreamDescriptor& descriptor)
+    explicit StreamContext(const StreamDescriptor& descriptor, const AudioConfigBase& config,
+                           AudioIoFlags flags)
         : mFrameSizeBytes(descriptor.frameSizeBytes),
+          mConfig(config),
           mCommandMQ(new CommandMQ(descriptor.command)),
           mReplyMQ(new ReplyMQ(descriptor.reply)),
           mBufferSizeFrames(descriptor.bufferSizeFrames),
+          mFlags(flags),
           mDataMQ(maybeCreateDataMQ(descriptor)),
           mIsMmapped(isMmapped(descriptor)),
           mSharedMemoryFd(maybeGetMmapFd(descriptor)) {
@@ -695,9 +756,12 @@
     size_t getBufferSizeBytes() const { return mFrameSizeBytes * mBufferSizeFrames; }
     size_t getBufferSizeFrames() const { return mBufferSizeFrames; }
     CommandMQ* getCommandMQ() const { return mCommandMQ.get(); }
+    const AudioConfigBase& getConfig() const { return mConfig; }
     DataMQ* getDataMQ() const { return mDataMQ.get(); }
+    AudioIoFlags getFlags() const { return mFlags; }
     size_t getFrameSizeBytes() const { return mFrameSizeBytes; }
     ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
+    int getSampleRate() const { return mConfig.sampleRate; }
     bool isMmapped() const { return mIsMmapped; }
     int8_t* getMmapMemory() const { return mSharedMemory; }
 
@@ -722,9 +786,11 @@
     }
 
     const size_t mFrameSizeBytes;
+    const AudioConfigBase mConfig;
     std::unique_ptr<CommandMQ> mCommandMQ;
     std::unique_ptr<ReplyMQ> mReplyMQ;
     const size_t mBufferSizeFrames;
+    const AudioIoFlags mFlags;
     std::unique_ptr<DataMQ> mDataMQ;
     const bool mIsMmapped;
     const int32_t mSharedMemoryFd;
@@ -926,12 +992,19 @@
           mDriver(driver),
           mEventReceiver(eventReceiver),
           mIsMmapped(context.isMmapped()),
-          mSharedMemory(context.getMmapMemory()) {}
+          mSharedMemory(context.getMmapMemory()),
+          mIsCompressOffload(context.getFlags().getTag() == AudioIoFlags::output &&
+                             isBitPositionFlagSet(context.getFlags().get<AudioIoFlags::output>(),
+                                                  AudioOutputFlags::COMPRESS_OFFLOAD)),
+          mConfig(context.getConfig()) {}
     StreamContext::CommandMQ* getCommandMQ() const { return mCommandMQ; }
+    const AudioConfigBase& getConfig() const { return mConfig; }
     StreamContext::ReplyMQ* getReplyMQ() const { return mReplyMQ; }
     StreamContext::DataMQ* getDataMQ() const { return mDataMQ; }
     StreamLogicDriver* getDriver() const { return mDriver; }
     StreamEventReceiver* getEventReceiver() const { return mEventReceiver; }
+    int getSampleRate() const { return mConfig.sampleRate; }
+    bool isCompressOffload() const { return mIsCompressOffload; }
     bool isMmapped() const { return mIsMmapped; }
 
     std::string init() override {
@@ -940,6 +1013,10 @@
     }
     const std::vector<int8_t>& getData() const { return mData; }
     void fillData(int8_t filler) { std::fill(mData.begin(), mData.end(), filler); }
+    void loadData(std::ifstream& is, size_t* size) {
+        *size = std::min(*size, mData.size());
+        is.read(reinterpret_cast<char*>(mData.data()), *size);
+    }
     std::optional<StreamDescriptor::Command> maybeGetNextCommand(int* actualSize = nullptr) {
         TransitionTrigger trigger = mDriver->getNextTrigger(mData.size(), actualSize);
         if (StreamEventReceiver::Event* expEvent =
@@ -1002,6 +1079,8 @@
     int mLastEventSeq = StreamEventReceiver::kEventSeqInit;
     const bool mIsMmapped;
     int8_t* mSharedMemory = nullptr;
+    const bool mIsCompressOffload;
+    const AudioConfigBase mConfig;
 };
 
 class StreamReaderLogic : public StreamCommonLogic {
@@ -1102,6 +1181,24 @@
     const std::vector<int8_t>& getData() const { return StreamCommonLogic::getData(); }
 
   protected:
+    std::string init() override {
+        if (auto status = StreamCommonLogic::init(); !status.empty()) return status;
+        if (isCompressOffload()) {
+            const auto info = getMediaFileInfoForConfig(getConfig());
+            if (info) {
+                mCompressedMedia.open(info->path, std::ios::in | std::ios::binary);
+                if (!mCompressedMedia.is_open()) {
+                    return std::string("failed to open media file \"") + info->path + "\"";
+                }
+                mCompressedMedia.seekg(0, mCompressedMedia.end);
+                mCompressedMediaSize = mCompressedMedia.tellg();
+                mCompressedMedia.seekg(0, mCompressedMedia.beg);
+                LOG(DEBUG) << __func__ << ": using media file \"" << info->path << "\", size "
+                           << mCompressedMediaSize << " bytes";
+            }
+        }
+        return "";
+    }
     Status cycle() override {
         if (getDriver()->done()) {
             LOG(DEBUG) << __func__ << ": clean exit";
@@ -1115,13 +1212,31 @@
             LOG(ERROR) << __func__ << ": no next command";
             return Status::ABORT;
         }
-        if (actualSize != 0) {
+        if (actualSize > 0) {
             if (command.getTag() == StreamDescriptor::Command::burst) {
-                fillData(mBurstIteration);
-                if (mBurstIteration < std::numeric_limits<int8_t>::max()) {
-                    mBurstIteration++;
+                if (!isCompressOffload()) {
+                    fillData(mBurstIteration);
+                    if (mBurstIteration < std::numeric_limits<int8_t>::max()) {
+                        mBurstIteration++;
+                    } else {
+                        mBurstIteration = 0;
+                    }
                 } else {
-                    mBurstIteration = 0;
+                    fillData(0);
+                    size_t size = std::min(static_cast<size_t>(actualSize),
+                                           mCompressedMediaSize - mCompressedMediaPos);
+                    loadData(mCompressedMedia, &size);
+                    if (!mCompressedMedia.good()) {
+                        LOG(ERROR) << __func__ << ": read failed";
+                        return Status::ABORT;
+                    }
+                    LOG(DEBUG) << __func__ << ": read from file " << size << " bytes";
+                    mCompressedMediaPos += size;
+                    if (mCompressedMediaPos >= mCompressedMediaSize) {
+                        mCompressedMedia.seekg(0, mCompressedMedia.beg);
+                        mCompressedMediaPos = 0;
+                        LOG(DEBUG) << __func__ << ": rewound to the beginning of the file";
+                    }
                 }
             }
             if (isMmapped() ? !writeDataToMmap() : !writeDataToMQ()) {
@@ -1185,6 +1300,9 @@
 
   private:
     int8_t mBurstIteration = 1;
+    std::ifstream mCompressedMedia;
+    size_t mCompressedMediaSize = 0;
+    size_t mCompressedMediaPos = 0;
 };
 using StreamWriter = StreamWorker<StreamWriterLogic>;
 
@@ -1293,7 +1411,13 @@
         ASSERT_NE(nullptr, mStream) << "port config id " << getPortId();
         EXPECT_GE(mDescriptor.bufferSizeFrames, bufferSizeFrames)
                 << "actual buffer size must be no less than requested";
-        mContext.emplace(mDescriptor);
+        const auto& config = mPortConfig.get();
+        ASSERT_TRUE(config.channelMask.has_value());
+        ASSERT_TRUE(config.format.has_value());
+        ASSERT_TRUE(config.sampleRate.has_value());
+        ASSERT_TRUE(config.flags.has_value());
+        const AudioConfigBase cfg{config.sampleRate->value, *config.channelMask, *config.format};
+        mContext.emplace(mDescriptor, cfg, config.flags.value());
         ASSERT_NO_FATAL_FAILURE(mContext.value().checkIsValid());
     }
     void SetUp(IModule* module, long bufferSizeFrames) {
@@ -1364,7 +1488,7 @@
     aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
     args.portConfigId = portConfig.id;
     args.sourceMetadata = GenerateSourceMetadata(portConfig);
-    args.offloadInfo = ModuleConfig::generateOffloadInfoIfNeeded(portConfig);
+    args.offloadInfo = generateOffloadInfoIfNeeded(portConfig);
     args.bufferSizeFrames = bufferSizeFrames;
     auto callback = ndk::SharedRefBase::make<DefaultStreamCallback>();
     args.callback = callback;
@@ -3192,10 +3316,12 @@
                                     {AudioInputFlags::MMAP_NOIRQ, AudioInputFlags::VOIP_TX,
                                      AudioInputFlags::HW_HOTWORD, AudioInputFlags::HOTWORD_TAP})) ||
            (portConfig.flags.value().getTag() == AudioIoFlags::output &&
-            isAnyBitPositionFlagSet(
-                    portConfig.flags.value().template get<AudioIoFlags::output>(),
-                    {AudioOutputFlags::MMAP_NOIRQ, AudioOutputFlags::VOIP_RX,
-                     AudioOutputFlags::COMPRESS_OFFLOAD, AudioOutputFlags::INCALL_MUSIC}));
+            (isAnyBitPositionFlagSet(portConfig.flags.value().template get<AudioIoFlags::output>(),
+                                     {AudioOutputFlags::MMAP_NOIRQ, AudioOutputFlags::VOIP_RX,
+                                      AudioOutputFlags::INCALL_MUSIC}) ||
+             (isBitPositionFlagSet(portConfig.flags.value().template get<AudioIoFlags::output>(),
+                                   AudioOutputFlags::COMPRESS_OFFLOAD) &&
+              !getMediaFileInfoForConfig(portConfig))));
 }
 
 // Certain types of devices can not be used without special preconditions.
@@ -3863,7 +3989,7 @@
     aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments args;
     args.portConfigId = portConfig.id;
     args.sourceMetadata = GenerateSourceMetadata(portConfig);
-    args.offloadInfo = ModuleConfig::generateOffloadInfoIfNeeded(portConfig);
+    args.offloadInfo = generateOffloadInfoIfNeeded(portConfig);
     args.bufferSizeFrames = stream.getPatch().minimumStreamBufferSizeFrames;
     aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn ret;
     EXPECT_STATUS(EX_ILLEGAL_ARGUMENT, module->openOutputStream(args, &ret))
@@ -4185,18 +4311,6 @@
                     std::get<NAMED_CMD_DELAY_MS>(std::get<PARAM_CMD_SEQ>(GetParam()));
             ASSERT_NO_FATAL_FAILURE(delayTransientStates.SetUp(module.get()));
             ASSERT_NO_FATAL_FAILURE(runStreamIoCommands(portConfig));
-            if (aidlVersion >= kAidlVersion3 && isNonBlocking && !IOTraits<Stream>::is_input) {
-                // Also try running the same sequence with "aosp.forceDrainToDraining" set.
-                // This will only work with the default implementation. When it works, the stream
-                // tries always to move to the 'DRAINING' state after an "early notify" drain.
-                // This helps to check more paths for our test scenarios.
-                WithModuleParameter forceDrainToDraining("aosp.forceDrainToDraining",
-                                                         Boolean{true});
-                if (forceDrainToDraining.SetUpNoChecks(module.get(), true /*failureExpected*/)
-                            .isOk()) {
-                    ASSERT_NO_FATAL_FAILURE(runStreamIoCommands(portConfig));
-                }
-            }
             if (isNonBlocking) {
                 // Also try running the same sequence with "aosp.forceTransientBurst" set.
                 // This will only work with the default implementation. When it works, the stream
@@ -4744,9 +4858,14 @@
 std::shared_ptr<StateSequence> makeDrainEarlyOutCommands() {
     using State = StreamDescriptor::State;
     auto d = std::make_unique<StateDag>();
-    StateDag::Node last = d->makeFinalNode(State::IDLE);
-    StateDag::Node draining = d->makeNode(State::DRAINING, kDrainReadyEvent, last);
-    draining.children().push_back(d->makeNode(State::DRAINING, kGetStatusCommand, last));
+    // In the "early notify" case, the transition to the `IDLE` state following
+    // the 'onDrainReady' event can take some time. Waiting for an arbitrary amount
+    // of time may make the test fragile. Instead, for successful completion
+    // is registered if the stream has entered `IDLE` or `DRAINING` state.
+    StateDag::Node lastIdle = d->makeFinalNode(State::IDLE);
+    StateDag::Node lastDraining = d->makeFinalNode(State::DRAINING);
+    StateDag::Node draining =
+            d->makeNode(State::DRAINING, kDrainReadyEvent, lastIdle, lastDraining);
     StateDag::Node active = d->makeNode(State::ACTIVE, kDrainOutEarlyCommand, draining);
     StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
     idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
@@ -4893,7 +5012,7 @@
         std::make_tuple(std::string("Pause"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
                         makePauseCommands(false, true), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kPauseOutAsyncSeq =
-        std::make_tuple(std::string("Pause"), kAidlVersion1, kStreamTransientStateTransitionDelayMs,
+        std::make_tuple(std::string("Pause"), kAidlVersion3, kStreamTransientStateTransitionDelayMs,
                         StreamTypeFilter::ASYNC, makePauseCommands(false, false),
                         false /*validatePositionIncrease*/);
 
@@ -4998,9 +5117,8 @@
                                          kDrainOutSyncSeq, kDrainOutAsyncSeq,
                                          kDrainEarlyOutAsyncSeq, kDrainPauseOutSyncSeq,
                                          kDrainPauseOutAsyncSeq, kDrainEarlyPauseOutAsyncSeq,
-                                         kStandbyOutSyncSeq, kStandbyOutAsyncSeq,
-                                         kPauseOutSyncSeq,  // kPauseOutAsyncSeq,
-                                         kFlushOutSyncSeq, kFlushOutAsyncSeq,
+                                         kStandbyOutSyncSeq, kStandbyOutAsyncSeq, kPauseOutSyncSeq,
+                                         kPauseOutAsyncSeq, kFlushOutSyncSeq, kFlushOutAsyncSeq,
                                          kDrainPauseFlushOutSyncSeq, kDrainPauseFlushOutAsyncSeq),
                          testing::Values(false, true)),
         GetStreamIoTestName);
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTestTemplate.xml b/audio/aidl/vts/VtsHalAudioCoreTargetTestTemplate.xml
new file mode 100644
index 0000000..94db58d
--- /dev/null
+++ b/audio/aidl/vts/VtsHalAudioCoreTargetTestTemplate.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs {MODULE}.">
+    <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 class="com.android.tradefed.targetprep.StopServicesSetup"/>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="setprop vts.native_server.on 1"/>
+        <option name="teardown-command" value="setprop vts.native_server.on 0"/>
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
+        <option name="push" value="sine882hz_44100_3s.ape->/data/local/tmp/sine882hz_44100_3s.ape" />
+        <option name="push" value="sine960hz_48000_3s.ape->/data/local/tmp/sine960hz_48000_3s.ape" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="{MODULE}" />
+        <option name="native-test-timeout" value="30m" />
+    </test>
+</configuration>
diff --git a/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml b/audio/aidl/vts/VtsHalAudioEffectTargetTestTemplate.xml
similarity index 100%
rename from audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
rename to audio/aidl/vts/VtsHalAudioEffectTargetTestTemplate.xml
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 0d4c74e..2bb0a72 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -120,6 +120,14 @@
 
     float calculateDb(const std::vector<float>& input, size_t startSamplePos);
 
+    void getMagnitudeValue(const std::vector<float>& output, std::vector<float>& bufferMag);
+
+    void checkInputAndOutputEquality(const std::vector<float>& outputMag);
+
+    void setUpDataTest(const std::vector<int>& testFrequencies, float fullScaleSineDb);
+
+    void createChannelConfig();
+
     // enqueue test parameters
     void addEngineConfig(const DynamicsProcessing::EngineArchitecture& cfg);
     void addPreEqChannelConfig(const std::vector<DynamicsProcessing::ChannelConfig>& cfg);
@@ -137,7 +145,24 @@
     static constexpr int kFrameCount = 2048;
     static constexpr int kInputFrequency = 1000;
     static constexpr size_t kStartIndex = 15 * kSamplingFrequency / 1000;  // skip 15ms
-    static constexpr float kToleranceDb = 0.05;
+    static constexpr float kToleranceDb = 0.5;
+    static constexpr int kNPointFFT = 1024;
+    static constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
+    // Full scale sine wave with 1000 Hz frequency is -3 dB
+    static constexpr float kSineFullScaleDb = -3;
+    // Full scale sine wave with 100 Hz and 1000 Hz frequency is -6 dB
+    static constexpr float kSineMultitoneFullScaleDb = -6;
+    const std::vector<int> kCutoffFreqHz = {200 /*0th band cutoff*/, 2000 /*1st band cutoff*/};
+    std::vector<int> mMultitoneTestFrequencies = {100, 1000};
+    // Calculating normalizing factor by dividing the number of FFT points by half and the number of
+    // test frequencies. The normalization accounts for the FFT splitting the signal into positive
+    // and negative frequencies. Additionally, during multi-tone input generation, sample values are
+    // normalized to the range [-1, 1] by dividing them by the number of test frequencies.
+    float mNormalizingFactor = (kNPointFFT / (2 * mMultitoneTestFrequencies.size()));
+    std::vector<int> mBinOffsets;
+    std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
+    std::vector<float> mInput;
+    float mInputDb;
     std::shared_ptr<IFactory> mFactory;
     std::shared_ptr<IEffect> mEffect;
     Descriptor mDescriptor;
@@ -416,6 +441,38 @@
     }
 }
 
+void DynamicsProcessingTestHelper::getMagnitudeValue(const std::vector<float>& output,
+                                                     std::vector<float>& bufferMag) {
+    std::vector<float> subOutput(output.begin() + kStartIndex, output.end());
+    EXPECT_NO_FATAL_FAILURE(calculateMagnitudeMono(bufferMag, subOutput, mBinOffsets, kNPointFFT));
+}
+
+void DynamicsProcessingTestHelper::checkInputAndOutputEquality(
+        const std::vector<float>& outputMag) {
+    std::vector<float> inputMag(mBinOffsets.size());
+    EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(mInput, inputMag));
+    for (size_t i = 0; i < inputMag.size(); i++) {
+        EXPECT_NEAR(calculateDb({inputMag[i] / mNormalizingFactor}),
+                    calculateDb({outputMag[i] / mNormalizingFactor}), kToleranceDb);
+    }
+}
+
+void DynamicsProcessingTestHelper::setUpDataTest(const std::vector<int>& testFrequencies,
+                                                 float fullScaleSineDb) {
+    ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect());
+    SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+    ASSERT_NO_FATAL_FAILURE(
+            generateSineWave(testFrequencies, mInput, 1.0, kSamplingFrequency, mChannelLayout));
+    mInputDb = calculateDb(mInput);
+    ASSERT_NEAR(mInputDb, fullScaleSineDb, kToleranceDb);
+}
+
+void DynamicsProcessingTestHelper::createChannelConfig() {
+    for (int i = 0; i < mChannelCount; i++) {
+        mChannelConfig.push_back(DynamicsProcessing::ChannelConfig(i, true));
+    }
+}
+
 void DynamicsProcessingTestHelper::addEngineConfig(
         const DynamicsProcessing::EngineArchitecture& cfg) {
     DynamicsProcessing dp;
@@ -527,6 +584,15 @@
                                              .postGainDb = postGainDb};
 }
 
+DynamicsProcessing::EqBandConfig creatEqBandConfig(int channel, int band, float cutOffFreqHz,
+                                                   float gainDb) {
+    return DynamicsProcessing::EqBandConfig{.channel = channel,
+                                            .band = band,
+                                            .enable = true,
+                                            .cutoffFrequencyHz = cutOffFreqHz,
+                                            .gainDb = gainDb};
+}
+
 /**
  * Test DynamicsProcessing Engine Configuration
  */
@@ -649,13 +715,7 @@
         mInput.resize(kFrameCount * mChannelCount);
     }
 
-    void SetUp() override {
-        SetUpDynamicsProcessingEffect();
-        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
-        ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency /*Input Frequency*/, mInput, 1.0,
-                                                 kSamplingFrequency, mChannelLayout));
-        mInputDb = calculateDb(mInput);
-    }
+    void SetUp() override { setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
@@ -665,8 +725,6 @@
     }
 
     std::vector<DynamicsProcessing::InputGain> mInputGain;
-    std::vector<float> mInput;
-    float mInputDb;
 };
 
 TEST_P(DynamicsProcessingInputGainDataTest, SetAndGetInputGain) {
@@ -785,14 +843,7 @@
         mInput.resize(mBufferSize);
     }
 
-    void SetUp() override {
-        SetUpDynamicsProcessingEffect();
-        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
-        ASSERT_NO_FATAL_FAILURE(
-                generateSineWave(kInputFrequency, mInput, 1.0, kSamplingFrequency, mChannelLayout));
-        mInputDb = calculateDb(mInput);
-        ASSERT_NEAR(mInputDb, kSineFullScaleDb, kToleranceDb);
-    }
+    void SetUp() override { setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
@@ -825,11 +876,8 @@
     static constexpr float kDefaultThreshold = -10;
     static constexpr float kDefaultPostGain = 0;
     static constexpr float kInputFrequency = 1000;
-    // Full scale sine wave with 1000 Hz frequency is -3 dB
-    static constexpr float kSineFullScaleDb = -3;
+    static constexpr float kLimiterTestToleranceDb = 0.05;
     std::vector<DynamicsProcessing::LimiterConfig> mLimiterConfigList;
-    std::vector<float> mInput;
-    float mInputDb;
     int mBufferSize;
 };
 
@@ -849,7 +897,7 @@
         }
         float outputDb = calculateDb(output, kStartIndex);
         if (threshold >= mInputDb || kDefaultRatio == 1) {
-            EXPECT_NEAR(mInputDb, outputDb, kToleranceDb);
+            EXPECT_NEAR(mInputDb, outputDb, kLimiterTestToleranceDb);
         } else {
             float calculatedThreshold = 0;
             ASSERT_NO_FATAL_FAILURE(computeThreshold(kDefaultRatio, outputDb, calculatedThreshold));
@@ -876,7 +924,7 @@
         float outputDb = calculateDb(output, kStartIndex);
 
         if (kDefaultThreshold >= mInputDb) {
-            EXPECT_NEAR(mInputDb, outputDb, kToleranceDb);
+            EXPECT_NEAR(mInputDb, outputDb, kLimiterTestToleranceDb);
         } else {
             float calculatedRatio = 0;
             ASSERT_NO_FATAL_FAILURE(computeRatio(kDefaultThreshold, outputDb, calculatedRatio));
@@ -894,7 +942,7 @@
         ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency, mInput, dBToAmplitude(postGainDb),
                                                  kSamplingFrequency, mChannelLayout));
         mInputDb = calculateDb(mInput);
-        EXPECT_NEAR(mInputDb, kSineFullScaleDb - postGainDb, kToleranceDb);
+        EXPECT_NEAR(mInputDb, kSineFullScaleDb - postGainDb, kLimiterTestToleranceDb);
         for (int i = 0; i < mChannelCount; i++) {
             fillLimiterConfig(mLimiterConfigList, i, true, kDefaultLinkerGroup, kDefaultAttackTime,
                               kDefaultReleaseTime, 1, kDefaultThreshold, postGainDb);
@@ -904,7 +952,7 @@
             continue;
         }
         float outputDb = calculateDb(output, kStartIndex);
-        EXPECT_NEAR(outputDb, mInputDb + postGainDb, kToleranceDb)
+        EXPECT_NEAR(outputDb, mInputDb + postGainDb, kLimiterTestToleranceDb)
                 << "PostGain: " << postGainDb << ", OutputDb: " << outputDb;
     }
 }
@@ -927,7 +975,7 @@
         if (isEnabled) {
             EXPECT_NE(mInputDb, calculateDb(output, kStartIndex));
         } else {
-            EXPECT_NEAR(mInputDb, calculateDb(output, kStartIndex), kToleranceDb);
+            EXPECT_NEAR(mInputDb, calculateDb(output, kStartIndex), kLimiterTestToleranceDb);
         }
     }
 }
@@ -1025,13 +1073,9 @@
                       const EqBandConfigTestParams& params) {
     const std::vector<std::pair<int, float>> cutOffFreqs = std::get<EQ_BAND_CUT_OFF_FREQ>(params);
     int bandCount = cutOffFreqs.size();
-    cfgs.resize(bandCount);
     for (int i = 0; i < bandCount; i++) {
-        cfgs[i].channel = std::get<EQ_BAND_CHANNEL>(params);
-        cfgs[i].band = cutOffFreqs[i].first;
-        cfgs[i].enable = true /*Eqband Enable*/;
-        cfgs[i].cutoffFrequencyHz = cutOffFreqs[i].second;
-        cfgs[i].gainDb = std::get<EQ_BAND_GAIN>(params);
+        cfgs.push_back(creatEqBandConfig(std::get<EQ_BAND_CHANNEL>(params), cutOffFreqs[i].first,
+                                         cutOffFreqs[i].second, std::get<EQ_BAND_GAIN>(params)));
     }
 }
 
@@ -1083,7 +1127,12 @@
                 {2, 6000},
                 {3, 10000},
                 {4, 16000},
-        },  // 5 bands
+                {5, 20000},
+                {6, 26000},
+                {7, 30000},
+                {8, 36000},
+                {9, 40000},
+        },  // 10 bands
         {
                 {0, 800},
                 {3, 15000},
@@ -1142,6 +1191,119 @@
         });
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingTestEqBandConfig);
 
+class DynamicsProcessingEqBandConfigDataTest
+    : public ::testing::TestWithParam<std::pair<std::shared_ptr<IFactory>, Descriptor>>,
+      public DynamicsProcessingTestHelper {
+  public:
+    DynamicsProcessingEqBandConfigDataTest()
+        : DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
+        mInput.resize(kFrameCount * mChannelCount);
+        mBinOffsets.resize(mMultitoneTestFrequencies.size());
+    }
+
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(
+                setUpDataTest(mMultitoneTestFrequencies, kSineMultitoneFullScaleDb));
+    }
+
+    void TearDown() override { TearDownDynamicsProcessingEffect(); }
+
+    void addEqParam(bool isPreEq) {
+        createChannelConfig();
+        auto stage = isPreEq ? mEngineConfigPreset.preEqStage : mEngineConfigPreset.postEqStage;
+        stage.bandCount = mCfgs.size();
+        addEngineConfig(mEngineConfigPreset);
+        isPreEq ? addPreEqChannelConfig(mChannelConfig) : addPostEqChannelConfig(mChannelConfig);
+        isPreEq ? addPreEqBandConfigs(mCfgs) : addPostEqBandConfigs(mCfgs);
+    }
+
+    void setEqParamAndProcess(std::vector<float>& output, bool isPreEq) {
+        addEqParam(isPreEq);
+        ASSERT_NO_FATAL_FAILURE(setParamsAndProcess(mInput, output));
+    }
+
+    void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs, int channelIndex,
+                          int bandIndex, int cutOffFreqHz, float gainDb) {
+        cfgs.push_back(creatEqBandConfig(channelIndex, bandIndex, static_cast<float>(cutOffFreqHz),
+                                         gainDb));
+    }
+
+    void validateOutput(const std::vector<float>& output, float gainDb, size_t bandIndex) {
+        std::vector<float> outputMag(mBinOffsets.size());
+        EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(output, outputMag));
+        if (gainDb == 0) {
+            EXPECT_NO_FATAL_FAILURE(checkInputAndOutputEquality(outputMag));
+        } else if (gainDb > 0) {
+            // For positive gain, current band's magnitude is greater than the other band's
+            // magnitude
+            EXPECT_GT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
+        } else {
+            // For negative gain, current band's magnitude is less than the other band's magnitude
+            EXPECT_LT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
+        }
+    }
+
+    void analyseMultiBandOutput(float gainDb, bool isPreEq) {
+        std::vector<float> output(mInput.size());
+        roundToFreqCenteredToFftBin(mMultitoneTestFrequencies, mBinOffsets, kBinWidth);
+        // Set Equalizer values for two bands
+        for (size_t i = 0; i < kCutoffFreqHz.size(); i++) {
+            for (int channelIndex = 0; channelIndex < mChannelCount; channelIndex++) {
+                fillEqBandConfig(mCfgs, channelIndex, i, kCutoffFreqHz[i], gainDb);
+                fillEqBandConfig(mCfgs, channelIndex, i ^ 1, kCutoffFreqHz[i ^ 1], 0);
+            }
+            ASSERT_NO_FATAL_FAILURE(setEqParamAndProcess(output, isPreEq));
+
+            if (isAllParamsValid()) {
+                ASSERT_NO_FATAL_FAILURE(validateOutput(output, gainDb, i));
+            }
+            cleanUpEqConfig();
+        }
+    }
+
+    void cleanUpEqConfig() {
+        CleanUp();
+        mCfgs.clear();
+        mChannelConfig.clear();
+    }
+
+    const std::vector<float> kTestGainDbValues = {-200, -100, 0, 100, 200};
+    std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
+};
+
+TEST_P(DynamicsProcessingEqBandConfigDataTest, IncreasingPreEqGain) {
+    for (float gainDb : kTestGainDbValues) {
+        ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
+                                                 dBToAmplitude(gainDb), kSamplingFrequency,
+                                                 mChannelLayout));
+        cleanUpEqConfig();
+        ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(gainDb, true /*pre-equalizer*/));
+    }
+}
+
+TEST_P(DynamicsProcessingEqBandConfigDataTest, IncreasingPostEqGain) {
+    for (float gainDb : kTestGainDbValues) {
+        ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
+                                                 dBToAmplitude(gainDb), kSamplingFrequency,
+                                                 mChannelLayout));
+        cleanUpEqConfig();
+        ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(gainDb, false /*post-equalizer*/));
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingEqBandConfigDataTest,
+                         testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
+                                 IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
+                         [](const auto& info) {
+                             auto descriptor = info.param;
+                             std::string name = getPrefix(descriptor.second);
+                             std::replace_if(
+                                     name.begin(), name.end(),
+                                     [](const char c) { return !std::isalnum(c); }, '_');
+                             return name;
+                         });
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DynamicsProcessingEqBandConfigDataTest);
+
 /**
  * Test DynamicsProcessing MbcBandConfig
  */
@@ -1254,24 +1416,18 @@
     DynamicsProcessingMbcBandConfigDataTest()
         : DynamicsProcessingTestHelper(GetParam(), AudioChannelLayout::LAYOUT_MONO) {
         mInput.resize(kFrameCount * mChannelCount);
-        mBinOffsets.resize(mTestFrequencies.size());
+        mBinOffsets.resize(mMultitoneTestFrequencies.size());
     }
 
     void SetUp() override {
-        SetUpDynamicsProcessingEffect();
-        SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
-        ASSERT_NO_FATAL_FAILURE(generateSineWave(mTestFrequencies, mInput, 1.0, kSamplingFrequency,
-                                                 mChannelLayout));
-        mInputDb = calculateDb(mInput);
-        ASSERT_NEAR(mInputDb, kFullScaleDb, kToleranceDb);
+        ASSERT_NO_FATAL_FAILURE(
+                setUpDataTest(mMultitoneTestFrequencies, kSineMultitoneFullScaleDb));
     }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     void setMbcParamsAndProcess(std::vector<float>& output) {
-        for (int i = 0; i < mChannelCount; i++) {
-            mChannelConfig.push_back(DynamicsProcessing::ChannelConfig(i, true));
-        }
+        createChannelConfig();
         mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
         addEngineConfig(mEngineConfigPreset);
         addMbcChannelConfig(mChannelConfig);
@@ -1288,23 +1444,12 @@
                                            noiseGate, expanderRatio, preGain, postGain));
     }
 
-    void getMagnitudeValue(const std::vector<float>& output, std::vector<float>& bufferMag) {
-        std::vector<float> subOutput(output.begin() + kStartIndex, output.end());
-        EXPECT_NO_FATAL_FAILURE(
-                calculateMagnitudeMono(bufferMag, subOutput, mBinOffsets, kNPointFFT));
-    }
-
     void validateOutput(const std::vector<float>& output, float threshold, float ratio,
                         size_t bandIndex) {
         std::vector<float> outputMag(mBinOffsets.size());
         EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(output, outputMag));
         if (threshold >= mInputDb || ratio == 1) {
-            std::vector<float> inputMag(mBinOffsets.size());
-            EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(mInput, inputMag));
-            for (size_t i = 0; i < inputMag.size(); i++) {
-                EXPECT_NEAR(calculateDb({inputMag[i] / mNormalizingFactor}),
-                            calculateDb({outputMag[i] / mNormalizingFactor}), kToleranceDb);
-            }
+            EXPECT_NO_FATAL_FAILURE(checkInputAndOutputEquality(outputMag));
         } else {
             // Current band's magnitude is less than the other band's magnitude
             EXPECT_LT(outputMag[bandIndex], outputMag[bandIndex ^ 1]);
@@ -1313,17 +1458,16 @@
 
     void analyseMultiBandOutput(float threshold, float ratio) {
         std::vector<float> output(mInput.size());
-        roundToFreqCenteredToFftBin(mTestFrequencies, mBinOffsets, kBinWidth);
-        std::vector<int> cutoffFreqHz = {200 /*0th band cutoff*/, 2000 /*1st band cutoff*/};
+        roundToFreqCenteredToFftBin(mMultitoneTestFrequencies, mBinOffsets, kBinWidth);
         // Set MBC values for two bands
-        for (size_t i = 0; i < cutoffFreqHz.size(); i++) {
+        for (size_t i = 0; i < kCutoffFreqHz.size(); i++) {
             for (int channelIndex = 0; channelIndex < mChannelCount; channelIndex++) {
                 fillMbcBandConfig(mCfgs, channelIndex, threshold, ratio, kDefaultNoiseGateDb,
-                                  kDefaultExpanderRatio, i, cutoffFreqHz[i], kDefaultPreGainDb,
+                                  kDefaultExpanderRatio, i, kCutoffFreqHz[i], kDefaultPreGainDb,
                                   kDefaultPostGainDb);
                 fillMbcBandConfig(mCfgs, channelIndex, kDefaultThresholdDb, kDefaultRatio,
                                   kDefaultNoiseGateDb, kDefaultExpanderRatio, i ^ 1,
-                                  cutoffFreqHz[i ^ 1], kDefaultPreGainDb, kDefaultPostGainDb);
+                                  kCutoffFreqHz[i ^ 1], kDefaultPreGainDb, kDefaultPostGainDb);
             }
             ASSERT_NO_FATAL_FAILURE(setMbcParamsAndProcess(output));
 
@@ -1340,8 +1484,6 @@
         mChannelConfig.clear();
     }
 
-    static constexpr int kNPointFFT = 1024;
-    static constexpr float kToleranceDb = 0.5;
     static constexpr float kDefaultPostGainDb = 0;
     static constexpr float kDefaultPreGainDb = 0;
     static constexpr float kDefaultAttackTime = 0;
@@ -1351,20 +1493,7 @@
     static constexpr float kDefaultNoiseGateDb = -10;
     static constexpr float kDefaultExpanderRatio = 1;
     static constexpr float kDefaultRatio = 1;
-    static constexpr float kBinWidth = (float)kSamplingFrequency / kNPointFFT;
-    // Full scale sine wave with 100 Hz and 1000 Hz frequency is -6 dB
-    static constexpr float kFullScaleDb = -6;
-    std::vector<int> mTestFrequencies = {100, 1000};
-    // Calculating normalizing factor by dividing the number of FFT points by half and the number of
-    // test frequencies. The normalization accounts for the FFT splitting the signal into positive
-    // and negative frequencies. Additionally, during multi-tone input generation, sample values are
-    // normalized to the range [-1, 1] by dividing them by the number of test frequencies.
-    float mNormalizingFactor = (kNPointFFT / (2 * mTestFrequencies.size()));
     std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
-    std::vector<DynamicsProcessing::ChannelConfig> mChannelConfig;
-    std::vector<int> mBinOffsets;
-    std::vector<float> mInput;
-    float mInputDb;
 };
 
 TEST_P(DynamicsProcessingMbcBandConfigDataTest, IncreasingThreshold) {
@@ -1391,11 +1520,11 @@
     std::vector<float> postGainDbValues = {-55, -30, 0, 30, 55};
     std::vector<float> output(mInput.size());
     for (float postGainDb : postGainDbValues) {
-        ASSERT_NO_FATAL_FAILURE(generateSineWave(mTestFrequencies, mInput,
+        ASSERT_NO_FATAL_FAILURE(generateSineWave(mMultitoneTestFrequencies, mInput,
                                                  dBToAmplitude(postGainDb), kSamplingFrequency,
                                                  mChannelLayout));
         mInputDb = calculateDb(mInput);
-        EXPECT_NEAR(mInputDb, kFullScaleDb - postGainDb, kToleranceDb);
+        EXPECT_NEAR(mInputDb, kSineMultitoneFullScaleDb - postGainDb, kToleranceDb);
         cleanUpMbcConfig();
         for (int i = 0; i < mChannelCount; i++) {
             fillMbcBandConfig(mCfgs, i, kDefaultThresholdDb, kDefaultRatio, kDefaultNoiseGateDb,
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index 2802bf9..1b0b681 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -275,6 +275,9 @@
 enum DataTestParam { EFFECT_INSTANCE, LAYOUT };
 using HapticGeneratorDataTestParam = std::tuple<EffectInstance, int32_t>;
 
+// minimal HAL interface version to run the data path test
+constexpr int32_t kMinDataTestHalVersion = 3;
+
 class HapticGeneratorDataTest : public ::testing::TestWithParam<HapticGeneratorDataTestParam>,
                                 public HapticGeneratorHelper {
   public:
@@ -293,7 +296,14 @@
         mOutput.resize(mHapticSamples + mAudioSamples, 0);
     }
 
-    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpHapticGenerator(mChMask)); }
+    void SetUp() override {
+        ASSERT_NO_FATAL_FAILURE(SetUpHapticGenerator(mChMask));
+        if (int32_t version;
+            mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
+            GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
+        }
+    }
+
     void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownHapticGenerator()); }
 
     void generateSinePeriod() {
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index ace0597..255d2f0 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -95,6 +95,8 @@
         EXPECT_STATUS(expected, mEffect->setParameter(param)) << param.toString();
     }
 
+    void reset() { EXPECT_STATUS(EX_NONE, mEffect->command(CommandId::RESET)); }
+
     void validateParameters(int gain) {
         // get parameter
         LoudnessEnhancer::Id leId;
@@ -218,6 +220,8 @@
         binder_exception_t expected;
         expected = isGainValid(kZeroGain);
         ASSERT_EQ(expected, EX_NONE);
+        // reset state to prevent prior signal history from affecting trial run.
+        ASSERT_NO_FATAL_FAILURE(reset());
         setParameters(kZeroGain, expected);
         ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput());
         baseOutput = mOutputBuffer;
@@ -229,6 +233,8 @@
             if (expected != EX_NONE) {
                 GTEST_SKIP() << "Gains not supported.";
             }
+            // reset state to prevent prior signal history from affecting trial run.
+            ASSERT_NO_FATAL_FAILURE(reset());
             setParameters(gain, expected);
             ASSERT_NO_FATAL_FAILURE(processAndWriteToOutput());
 
diff --git a/audio/aidl/vts/data/sine882hz_44100_3s.ape b/audio/aidl/vts/data/sine882hz_44100_3s.ape
new file mode 100644
index 0000000..1cefb15
--- /dev/null
+++ b/audio/aidl/vts/data/sine882hz_44100_3s.ape
Binary files differ
diff --git a/audio/aidl/vts/data/sine960hz_48000_3s.ape b/audio/aidl/vts/data/sine960hz_48000_3s.ape
new file mode 100644
index 0000000..149c42a
--- /dev/null
+++ b/audio/aidl/vts/data/sine960hz_48000_3s.ape
Binary files differ
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/TEST_MAPPING b/automotive/TEST_MAPPING
index 2b2f6b0..f041ca6 100644
--- a/automotive/TEST_MAPPING
+++ b/automotive/TEST_MAPPING
@@ -4,6 +4,12 @@
       "name": "AndroidCarApiTest"
     },
     {
+      "name": "CarHiddenApiTest"
+    },
+    {
+      "name": "CarExtendedApiTest"
+    },
+    {
       "name": "CarSecurityPermissionTest"
     },
     {
diff --git a/automotive/can/OWNERS b/automotive/can/OWNERS
index ffa4828..b738dac 100644
--- a/automotive/can/OWNERS
+++ b/automotive/can/OWNERS
@@ -1,3 +1,2 @@
-kevinme@google.com
 chrisweir@google.com
 twasilczyk@google.com
diff --git a/automotive/vehicle/OWNERS b/automotive/vehicle/OWNERS
index f099287..066af9a 100644
--- a/automotive/vehicle/OWNERS
+++ b/automotive/vehicle/OWNERS
@@ -1,9 +1,6 @@
 ericjeong@google.com
 shanyu@google.com
 
-# GRPC VHAL
-per-file aidl/impl/grpc/** =egranata@google.com
-
 # Property definition
 per-file aidl_property/** = tylertrephan@google.com
 per-file aidl/generated_lib/** = tylertrephan@google.com
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index 56bc047..cdc6e56 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -48,10 +48,16 @@
       "name": "GRPCVehicleHardwareUnitTest"
     },
     {
+      "name": "GRPCVehicleProxyServerUnitTest"
+    },
+    {
       "name": "CarServiceHalUnitTest"
     },
     {
       "name": "VehicleHalProtoMessageConverterTest"
+    },
+    {
+      "name": "CtsCarTestCases"
     }
   ],
   "postsubmit": [
diff --git a/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/ConfigDeclaration.h b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/ConfigDeclaration.h
index 40ac129..c4b794a 100644
--- a/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/ConfigDeclaration.h
+++ b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/ConfigDeclaration.h
@@ -39,6 +39,9 @@
     std::unordered_map<int32_t, aidl::android::hardware::automotive::vehicle::RawPropValues>
             initialAreaValues;
 
+    // The optional supported values for each areaId.
+    std::unordered_map<int32_t, std::vector<float>> supportedValuesForAreaId;
+
     inline bool operator==(const ConfigDeclaration& other) const {
         return (config == other.config && initialValue == other.initialValue &&
                 initialAreaValues == other.initialAreaValues);
diff --git a/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/JsonConfigLoader.h b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/JsonConfigLoader.h
index 00c497f..9901db2 100644
--- a/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/JsonConfigLoader.h
+++ b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/JsonConfigLoader.h
@@ -108,11 +108,23 @@
     // @param fieldIsOptional Whether the field is optional.
     // @param outPtr The pointer to output to if the field exists and parsing succeeded.
     // @param errors The error array to append error to if errors are found.
-    // @return true if the field is optional and does not exist or parsed successfully.
+    // @param found if not nullptr, this will be set to true if the field is found.
+    // @return true if parsed successfully or the field is optional and is not found.
     template <class T>
     bool tryParseJsonValueToVariable(const Json::Value& parentJsonNode,
                                      const std::string& fieldName, bool fieldIsOptional, T* outPtr,
+                                     std::vector<std::string>* errors, bool* found = nullptr);
+
+    // Tries to parse a JSON value to a specific type.
+    //
+    // This is similar to the previous version except that it tries to find the field in multiple
+    // parent nodes and will return early if the field is found in one parent node. This is useful
+    // when we allow the field to either come from vehicleArea fields or vehicleProperty fields.
+    template <class T>
+    bool tryParseJsonValueToVariable(std::vector<const Json::Value*> parentJsonNodePtrs,
+                                     const std::string& fieldName, bool fieldIsOptional, T* outPtr,
                                      std::vector<std::string>* errors);
+
     // Tries to parse a JSON value to an array of specific type.
     //
     // If fieldIsOptional is True, then if the field specified by "fieldName" does not exist,
@@ -127,7 +139,19 @@
     template <class T>
     bool tryParseJsonArrayToVariable(const Json::Value& parentJsonNode,
                                      const std::string& fieldName, bool fieldIsOptional,
+                                     std::vector<T>* outPtr, std::vector<std::string>* errors,
+                                     bool* found = nullptr);
+
+    // Tries to parse a JSON value to an array of specific type.
+    //
+    // This is similar to the previous version except that it tries to find the field in multiple
+    // parent nodes and will return early if the field is found in one parent node. This is useful
+    // when we allow the field to either come from vehicleArea fields or vehicleProperty fields.
+    template <class T>
+    bool tryParseJsonArrayToVariable(std::vector<const Json::Value*> parentJsonNodePtrs,
+                                     const std::string& fieldName, bool fieldIsOptional,
                                      std::vector<T>* outPtr, std::vector<std::string>* errors);
+
     // Parses a JSON field to VehiclePropertyAccess or VehiclePropertyChangeMode.
     template <class T>
     void parseAccessChangeMode(const Json::Value& parentJsonNode, const std::string& fieldName,
diff --git a/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
index 5b945b2..fdccaec 100644
--- a/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
+++ b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -95,6 +95,12 @@
 using ::android::base::Error;
 using ::android::base::Result;
 
+int32_t COMPATIBLE_API_VERSIONS[] = {
+        // The base version.
+        1,
+        // V2 supports inherit areaId fields from parent property fields.
+        2};
+
 // Defines a map from constant names to constant values, the values defined here corresponds to
 // the "Constants::XXXX" used in JSON config file.
 const std::unordered_map<std::string, int> CONSTANTS_BY_NAME = {
@@ -148,6 +154,17 @@
          toInt(VehicleAreaMirror::DRIVER_LEFT) | toInt(VehicleAreaMirror::DRIVER_RIGHT)},
 };
 
+std::string nodesToStr(const std::vector<const Json::Value*>& nodePtrs) {
+    std::string nodesStr = "";
+    for (const Json::Value* nodePtr : nodePtrs) {
+        if (nodesStr != "") {
+            nodesStr += ", ";
+        }
+        nodesStr += nodePtr->toStyledString();
+    }
+    return nodesStr;
+}
+
 // A class to parse constant values for type T where T is defined as an enum in NDK AIDL backend.
 template <class T>
 class ConstantParser final : public ConstantParserInterface {
@@ -447,10 +464,33 @@
 }
 
 template <class T>
+bool JsonConfigParser::tryParseJsonValueToVariable(
+        std::vector<const Json::Value*> parentJsonNodePtrs, const std::string& fieldName,
+        bool fieldIsOptional, T* outPtr, std::vector<std::string>* errors) {
+    bool found = false;
+    for (const Json::Value* parentJsonNodePtr : parentJsonNodePtrs) {
+        bool result = tryParseJsonValueToVariable(*parentJsonNodePtr, fieldName,
+                                                  /*fieldIsOptional=*/true, outPtr, errors, &found);
+        if (!result) {
+            return result;
+        }
+        if (found) {
+            return true;
+        }
+    }
+    if (!fieldIsOptional && !found) {
+        errors->push_back("Missing required field: " + fieldName +
+                          " in nodes: " + nodesToStr(parentJsonNodePtrs));
+        return false;
+    }
+    return true;
+}
+
+template <class T>
 bool JsonConfigParser::tryParseJsonValueToVariable(const Json::Value& parentJsonNode,
                                                    const std::string& fieldName,
                                                    bool fieldIsOptional, T* outPtr,
-                                                   std::vector<std::string>* errors) {
+                                                   std::vector<std::string>* errors, bool* found) {
     if (!parentJsonNode.isObject()) {
         errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
         return false;
@@ -469,6 +509,32 @@
         return false;
     }
     *outPtr = std::move(result.value());
+    if (found != nullptr) {
+        *found = true;
+    }
+    return true;
+}
+
+template <class T>
+bool JsonConfigParser::tryParseJsonArrayToVariable(
+        std::vector<const Json::Value*> parentJsonNodePtrs, const std::string& fieldName,
+        bool fieldIsOptional, std::vector<T>* outPtr, std::vector<std::string>* errors) {
+    bool found = false;
+    for (const Json::Value* parentJsonNodePtr : parentJsonNodePtrs) {
+        bool result = tryParseJsonArrayToVariable(*parentJsonNodePtr, fieldName,
+                                                  /*fieldIsOptional=*/true, outPtr, errors, &found);
+        if (!result) {
+            return result;
+        }
+        if (found) {
+            return true;
+        }
+    }
+    if (!fieldIsOptional && !found) {
+        errors->push_back("Missing required field: " + fieldName +
+                          " in nodes: " + nodesToStr(parentJsonNodePtrs));
+        return false;
+    }
     return true;
 }
 
@@ -476,7 +542,7 @@
 bool JsonConfigParser::tryParseJsonArrayToVariable(const Json::Value& parentJsonNode,
                                                    const std::string& fieldName,
                                                    bool fieldIsOptional, std::vector<T>* outPtr,
-                                                   std::vector<std::string>* errors) {
+                                                   std::vector<std::string>* errors, bool* found) {
     if (!parentJsonNode.isObject()) {
         errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
         return false;
@@ -495,6 +561,9 @@
         return false;
     }
     *outPtr = std::move(result.value());
+    if (found != nullptr) {
+        *found = true;
+    }
     return true;
 }
 
@@ -574,44 +643,60 @@
         }
         VehicleAreaConfig areaConfig = {};
         areaConfig.areaId = areaId;
+        // We have already parsed the access in parentJsonNode into config, so we do not have to
+        // parse parentNode again here.
         parseAccessChangeMode(jsonAreaConfig, "access", propStr, &(config->config.access),
                               &areaConfig.access, errors);
-        tryParseJsonValueToVariable(jsonAreaConfig, "minInt32Value", /*optional=*/true,
-                                    &areaConfig.minInt32Value, errors);
-        tryParseJsonValueToVariable(jsonAreaConfig, "maxInt32Value", /*optional=*/true,
-                                    &areaConfig.maxInt32Value, errors);
-        tryParseJsonValueToVariable(jsonAreaConfig, "minInt64Value", /*optional=*/true,
-                                    &areaConfig.minInt64Value, errors);
-        tryParseJsonValueToVariable(jsonAreaConfig, "maxInt64Value", /*optional=*/true,
-                                    &areaConfig.maxInt64Value, errors);
-        tryParseJsonValueToVariable(jsonAreaConfig, "minFloatValue", /*optional=*/true,
-                                    &areaConfig.minFloatValue, errors);
-        tryParseJsonValueToVariable(jsonAreaConfig, "maxFloatValue", /*optional=*/true,
-                                    &areaConfig.maxFloatValue, errors);
+        // All the following fields may come from area config or from parent node (property config).
+        tryParseJsonValueToVariable({&jsonAreaConfig, &parentJsonNode}, "minInt32Value",
+                                    /*optional=*/true, &areaConfig.minInt32Value, errors);
+        tryParseJsonValueToVariable({&jsonAreaConfig, &parentJsonNode}, "maxInt32Value",
+                                    /*optional=*/true, &areaConfig.maxInt32Value, errors);
+        tryParseJsonValueToVariable({&jsonAreaConfig, &parentJsonNode}, "minInt64Value",
+                                    /*optional=*/true, &areaConfig.minInt64Value, errors);
+        tryParseJsonValueToVariable({&jsonAreaConfig, &parentJsonNode}, "maxInt64Value",
+                                    /*optional=*/true, &areaConfig.maxInt64Value, errors);
+        tryParseJsonValueToVariable({&jsonAreaConfig, &parentJsonNode}, "minFloatValue",
+                                    /*optional=*/true, &areaConfig.minFloatValue, errors);
+        tryParseJsonValueToVariable({&jsonAreaConfig, &parentJsonNode}, "maxFloatValue",
+                                    /*optional=*/true, &areaConfig.maxFloatValue, errors);
 
         // By default we support variable update rate for all properties except it is explicitly
         // disabled.
         areaConfig.supportVariableUpdateRate = true;
-        tryParseJsonValueToVariable(jsonAreaConfig, "supportVariableUpdateRate", /*optional=*/true,
-                                    &areaConfig.supportVariableUpdateRate, errors);
+        tryParseJsonValueToVariable({&jsonAreaConfig, &parentJsonNode}, "supportVariableUpdateRate",
+                                    /*optional=*/true, &areaConfig.supportVariableUpdateRate,
+                                    errors);
 
         std::vector<int64_t> supportedEnumValues;
-        tryParseJsonArrayToVariable(jsonAreaConfig, "supportedEnumValues", /*optional=*/true,
-                                    &supportedEnumValues, errors);
+        tryParseJsonArrayToVariable({&jsonAreaConfig, &parentJsonNode}, "supportedEnumValues",
+                                    /*optional=*/true, &supportedEnumValues, errors);
         if (!supportedEnumValues.empty()) {
             areaConfig.supportedEnumValues = std::move(supportedEnumValues);
         }
 
+        std::vector<float> supportedValues;
+        tryParseJsonArrayToVariable({&jsonAreaConfig, &parentJsonNode}, "supportedValues",
+                                    /*optional=*/true, &supportedValues, errors);
+        if (!supportedValues.empty()) {
+            config->supportedValuesForAreaId[areaId] = std::move(supportedValues);
+        }
+
+        const Json::Value* jsonHasSupportedValueInfo = nullptr;
         if (jsonAreaConfig.isMember("hasSupportedValueInfo")) {
+            jsonHasSupportedValueInfo = &jsonAreaConfig["hasSupportedValueInfo"];
+        } else if (parentJsonNode.isMember("hasSupportedValueInfo")) {
+            jsonHasSupportedValueInfo = &parentJsonNode["hasSupportedValueInfo"];
+        }
+        if (jsonHasSupportedValueInfo != nullptr) {
             HasSupportedValueInfo hasSupportedValueInfo = HasSupportedValueInfo{};
-            const Json::Value& jsonHasSupportedValueInfo = jsonAreaConfig["hasSupportedValueInfo"];
-            tryParseJsonValueToVariable(jsonHasSupportedValueInfo, "hasMinSupportedValue",
+            tryParseJsonValueToVariable(*jsonHasSupportedValueInfo, "hasMinSupportedValue",
                                         /*optional=*/true,
                                         &hasSupportedValueInfo.hasMinSupportedValue, errors);
-            tryParseJsonValueToVariable(jsonHasSupportedValueInfo, "hasMaxSupportedValue",
+            tryParseJsonValueToVariable(*jsonHasSupportedValueInfo, "hasMaxSupportedValue",
                                         /*optional=*/true,
                                         &hasSupportedValueInfo.hasMaxSupportedValue, errors);
-            tryParseJsonValueToVariable(jsonHasSupportedValueInfo, "hasSupportedValuesList",
+            tryParseJsonValueToVariable(*jsonHasSupportedValueInfo, "hasSupportedValuesList",
                                         /*optional=*/true,
                                         &hasSupportedValueInfo.hasSupportedValuesList, errors);
             areaConfig.hasSupportedValueInfo = std::move(hasSupportedValueInfo);
@@ -622,6 +707,11 @@
         RawPropValues areaValue = {};
         if (parsePropValues(jsonAreaConfig, "defaultValue", &areaValue, errors)) {
             config->initialAreaValues[areaId] = std::move(areaValue);
+        } else {
+            if (config->initialValue != RawPropValues{}) {
+                // Skip empty initial values.
+                config->initialAreaValues[areaId] = config->initialValue;
+            }
         }
     }
 }
@@ -701,6 +791,21 @@
     if (!root.isObject()) {
         return Error() << "root element must be an object";
     }
+    // Default API version is 1.
+    int32_t apiVersion = 1;
+    if (root.isMember("apiVersion")) {
+        apiVersion = static_cast<int32_t>(root["apiVersion"].asInt());
+    }
+    bool compatible = false;
+    for (int32_t compatibleApiVersion : COMPATIBLE_API_VERSIONS) {
+        if (compatibleApiVersion == apiVersion) {
+            compatible = true;
+            break;
+        }
+    }
+    if (!compatible) {
+        return Error() << "The JSON file is not compatible with the JSON loader version";
+    }
     if (!root.isMember("properties") || !root["properties"].isArray()) {
         return Error() << "Missing 'properties' field in root or the field is not an array";
     }
diff --git a/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
index 595c2ed..3b4720b 100644
--- a/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
@@ -314,6 +314,33 @@
     ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
 }
 
+TEST_F(JsonConfigLoaderUnitTest, testAccessAreaOverride) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "areas": [
+                {
+                    "areaId": 0,
+                    "access": "VehiclePropertyAccess::WRITE"
+                }
+            ]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_TRUE(result.ok()) << result.error().message();
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const VehiclePropConfig& propConfig = configs.begin()->second.config;
+    ASSERT_EQ(propConfig.access, VehiclePropertyAccess::READ);
+    ASSERT_EQ(propConfig.areaConfigs[0].access, VehiclePropertyAccess::WRITE);
+    ASSERT_EQ(propConfig.changeMode, VehiclePropertyChangeMode::STATIC);
+}
+
 TEST_F(JsonConfigLoaderUnitTest, testChangeModeOverride) {
     std::istringstream iss(R"(
     {
@@ -564,6 +591,148 @@
     ASSERT_EQ(areaConfig.areaId, HVAC_ALL);
 }
 
+TEST_F(JsonConfigLoaderUnitTest, testAreas_InheritFromProperty) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "minInt32Value": 1,
+            "maxInt32Value": 7,
+            "minInt64Value": 2,
+            "maxInt64Value": 6,
+            "minFloatValue": 1.1,
+            "maxFloatValue": 2.2,
+            "supportVariableUpdateRate": true,
+            "supportedEnumValues": [1, 2, 3],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true,
+                "hasSupportedValuesList": true
+            },
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [{
+                "areaId": "Constants::HVAC_ALL"
+            }]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_RESULT_OK(result);
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const auto& configDecl = configs.begin()->second;
+    const VehiclePropConfig& config = configDecl.config;
+    EXPECT_EQ(config.access, VehiclePropertyAccess::READ);
+    ASSERT_EQ(config.areaConfigs.size(), 1u);
+    const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+    EXPECT_EQ(areaConfig.minInt32Value, 1);
+    EXPECT_EQ(areaConfig.maxInt32Value, 7);
+    EXPECT_EQ(areaConfig.minInt64Value, 2);
+    EXPECT_EQ(areaConfig.maxInt64Value, 6);
+    EXPECT_EQ(areaConfig.minFloatValue, 1.1f);
+    EXPECT_EQ(areaConfig.maxFloatValue, 2.2f);
+    EXPECT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
+    EXPECT_EQ(areaConfig.areaId, HVAC_ALL);
+    EXPECT_EQ(areaConfig.supportVariableUpdateRate, true);
+    ASSERT_TRUE(areaConfig.supportedEnumValues.has_value());
+    EXPECT_EQ(areaConfig.supportedEnumValues.value(), std::vector<int64_t>({1, 2, 3}));
+    ASSERT_TRUE(areaConfig.hasSupportedValueInfo.has_value());
+    EXPECT_TRUE(areaConfig.hasSupportedValueInfo->hasMinSupportedValue);
+    EXPECT_TRUE(areaConfig.hasSupportedValueInfo->hasMaxSupportedValue);
+    EXPECT_TRUE(areaConfig.hasSupportedValueInfo->hasSupportedValuesList);
+    ASSERT_FALSE(configDecl.initialAreaValues.find(HVAC_ALL) == configDecl.initialAreaValues.end());
+    EXPECT_EQ(configDecl.initialAreaValues.find(HVAC_ALL)->second,
+              RawPropValues{.int32Values = {1}});
+}
+
+TEST_F(JsonConfigLoaderUnitTest, testAreas_InheritFromProperty_override) {
+    std::istringstream iss(R"(
+    {
+        "properties": [{
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "minInt32Value": 100,
+            "maxInt32Value": 100,
+            "minInt64Value": 100,
+            "maxInt64Value": 100,
+            "minFloatValue": 100.1,
+            "maxFloatValue": 100.2,
+            "supportVariableUpdateRate": false,
+            "supportedEnumValues": [3, 2, 1],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": false,
+                "hasMaxSupportedValue": false,
+                "hasSupportedValuesList": false
+            },
+            "defaultValue": {
+                "int32Values": [
+                    2
+                ]
+            },
+            "areas": [{
+                "areaId": "Constants::HVAC_ALL",
+                "minInt32Value": 1,
+                "maxInt32Value": 7,
+                "minInt64Value": 2,
+                "maxInt64Value": 6,
+                "minFloatValue": 1.1,
+                "maxFloatValue": 2.2,
+                "supportVariableUpdateRate": true,
+                "supportedEnumValues": [1, 2, 3],
+                "hasSupportedValueInfo": {
+                    "hasMinSupportedValue": true,
+                    "hasMaxSupportedValue": true,
+                    "hasSupportedValuesList": true
+                },
+                "defaultValue": {
+                    "int32Values": [
+                        1
+                    ]
+                }
+            }]
+        }]
+    }
+    )");
+
+    auto result = mLoader.loadPropConfig(iss);
+
+    ASSERT_RESULT_OK(result);
+
+    auto configs = result.value();
+    ASSERT_EQ(configs.size(), 1u);
+
+    const auto& configDecl = configs.begin()->second;
+    const VehiclePropConfig& config = configDecl.config;
+    EXPECT_EQ(config.access, VehiclePropertyAccess::READ);
+    ASSERT_EQ(config.areaConfigs.size(), 1u);
+    const VehicleAreaConfig& areaConfig = config.areaConfigs[0];
+    EXPECT_EQ(areaConfig.minInt32Value, 1);
+    EXPECT_EQ(areaConfig.maxInt32Value, 7);
+    EXPECT_EQ(areaConfig.minInt64Value, 2);
+    EXPECT_EQ(areaConfig.maxInt64Value, 6);
+    EXPECT_EQ(areaConfig.minFloatValue, 1.1f);
+    EXPECT_EQ(areaConfig.maxFloatValue, 2.2f);
+    EXPECT_EQ(areaConfig.access, VehiclePropertyAccess::READ);
+    EXPECT_EQ(areaConfig.areaId, HVAC_ALL);
+    EXPECT_EQ(areaConfig.supportVariableUpdateRate, true);
+    ASSERT_TRUE(areaConfig.supportedEnumValues.has_value());
+    EXPECT_EQ(areaConfig.supportedEnumValues.value(), std::vector<int64_t>({1, 2, 3}));
+    ASSERT_TRUE(areaConfig.hasSupportedValueInfo.has_value());
+    EXPECT_TRUE(areaConfig.hasSupportedValueInfo->hasMinSupportedValue);
+    EXPECT_TRUE(areaConfig.hasSupportedValueInfo->hasMaxSupportedValue);
+    EXPECT_TRUE(areaConfig.hasSupportedValueInfo->hasSupportedValuesList);
+    ASSERT_FALSE(configDecl.initialAreaValues.find(HVAC_ALL) == configDecl.initialAreaValues.end());
+    EXPECT_EQ(configDecl.initialAreaValues.find(HVAC_ALL)->second,
+              RawPropValues{.int32Values = {1}});
+}
+
 TEST_F(JsonConfigLoaderUnitTest, testAreas_DefaultValueForEachArea) {
     std::istringstream iss(R"(
     {
diff --git a/automotive/vehicle/aidl/impl/current/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/current/default_config/config/DefaultProperties.json
index f71dead..c3e12f6 100644
--- a/automotive/vehicle/aidl/impl/current/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/current/default_config/config/DefaultProperties.json
@@ -1,5 +1,5 @@
 {
-    "apiVersion": 1,
+    "apiVersion": 2,
     "properties": [
         {
             "property": "VehicleProperty::INFO_FUEL_CAPACITY",
@@ -162,63 +162,49 @@
         },
         {
             "property": "VehicleProperty::SEAT_MEMORY_SELECT",
-            "defaultValue": {
-                "int32Values": [
-                    1
-                ]
-            },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::SEAT_MEMORY_SET",
-            "defaultValue": {
-                "int32Values": [
-                    1
-                ]
-            },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::SEAT_BELT_BUCKLED",
@@ -254,31 +240,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_BELT_HEIGHT_MOVE",
@@ -289,31 +271,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_FORE_AFT_POS",
@@ -324,31 +302,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_FORE_AFT_MOVE",
@@ -359,31 +333,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_POS",
@@ -394,31 +364,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE",
@@ -429,31 +395,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_POS",
@@ -464,31 +426,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE",
@@ -499,31 +457,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_HEIGHT_POS",
@@ -534,31 +488,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_HEIGHT_MOVE",
@@ -569,31 +519,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_DEPTH_POS",
@@ -604,31 +550,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_DEPTH_MOVE",
@@ -639,31 +581,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_TILT_POS",
@@ -674,31 +612,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_TILT_MOVE",
@@ -709,31 +643,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS",
@@ -744,31 +674,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE",
@@ -779,31 +705,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS",
@@ -814,31 +736,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE",
@@ -849,31 +767,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2",
@@ -884,31 +798,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE",
@@ -919,31 +829,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_ANGLE_POS",
@@ -954,31 +860,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_ANGLE_MOVE",
@@ -989,31 +891,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_POS",
@@ -1024,31 +922,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE",
@@ -1059,31 +953,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE",
@@ -1094,26 +984,21 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "supportedEnumValues": [
-                        "Constants::LIGHT_STATE_OFF",
-                        "Constants::LIGHT_STATE_ON"
-                    ]
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "supportedEnumValues": [
-                        "Constants::LIGHT_STATE_OFF",
-                        "Constants::LIGHT_STATE_ON"
-                    ]
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
-                    "supportedEnumValues": [
-                        "Constants::LIGHT_STATE_OFF",
-                        "Constants::LIGHT_STATE_ON"
-                    ]
+                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER"
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "Constants::LIGHT_STATE_OFF",
+                "Constants::LIGHT_STATE_ON"
             ]
         },
         {
@@ -1125,29 +1010,22 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "supportedEnumValues": [
-                        "Constants::LIGHT_SWITCH_OFF",
-                        "Constants::LIGHT_SWITCH_ON",
-                        "Constants::LIGHT_SWITCH_AUTO"
-                    ]
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "supportedEnumValues": [
-                        "Constants::LIGHT_SWITCH_OFF",
-                        "Constants::LIGHT_SWITCH_ON",
-                        "Constants::LIGHT_SWITCH_AUTO"
-                    ]
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
-                    "supportedEnumValues": [
-                        "Constants::LIGHT_SWITCH_OFF",
-                        "Constants::LIGHT_SWITCH_ON",
-                        "Constants::LIGHT_SWITCH_AUTO"
-                    ]
+                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER"
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "Constants::LIGHT_SWITCH_OFF",
+                "Constants::LIGHT_SWITCH_ON",
+                "Constants::LIGHT_SWITCH_AUTO"
             ]
         },
         {
@@ -1191,31 +1069,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE",
@@ -1226,31 +1100,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_POS",
@@ -1261,31 +1131,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE",
@@ -1296,31 +1162,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_WALK_IN_POS",
@@ -1331,16 +1193,18 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 5
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 5
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 5
         },
         {
             "property": "VehicleProperty::SEAT_AIRBAGS_DEPLOYED",
@@ -1358,7 +1222,10 @@
                         "VehicleAirbagLocation::LEFT_SIDE",
                         "VehicleAirbagLocation::RIGHT_SIDE",
                         "VehicleAirbagLocation::CURTAIN"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 },
                 {
                     "areaId": "Constants::SEAT_1_RIGHT",
@@ -1368,21 +1235,30 @@
                         "VehicleAirbagLocation::LEFT_SIDE",
                         "VehicleAirbagLocation::RIGHT_SIDE",
                         "VehicleAirbagLocation::CURTAIN"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 },
                 {
                     "areaId": "Constants::SEAT_2_LEFT",
                     "supportedEnumValues": [
                         "VehicleAirbagLocation::FRONT",
                         "VehicleAirbagLocation::CURTAIN"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 },
                 {
                     "areaId": "Constants::SEAT_2_RIGHT",
                     "supportedEnumValues": [
                         "VehicleAirbagLocation::FRONT",
                         "VehicleAirbagLocation::CURTAIN"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 }
             ]
         },
@@ -1596,6 +1472,21 @@
                 60,
                 80,
                 100
+            ],
+            "areas": [
+                {
+                    "areaId": 0
+                }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedValues": [
+                20,
+                40,
+                60,
+                80,
+                100
             ]
         },
         {
@@ -1682,29 +1573,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::WHEEL_FRONT_LEFT",
-                    "minFloatValue": 193.0,
-                    "maxFloatValue": 300.0
+                    "areaId": "Constants::WHEEL_FRONT_LEFT"
                 },
                 {
-                    "areaId": "Constants::WHEEL_FRONT_RIGHT",
-                    "minFloatValue": 193.0,
-                    "maxFloatValue": 300.0
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT"
                 },
                 {
-                    "areaId": "Constants::WHEEL_REAR_LEFT",
-                    "minFloatValue": 193.0,
-                    "maxFloatValue": 300.0
+                    "areaId": "Constants::WHEEL_REAR_LEFT"
                 },
                 {
-                    "areaId": "Constants::WHEEL_REAR_RIGHT",
-                    "minFloatValue": 193.0,
-                    "maxFloatValue": 300.0
+                    "areaId": "Constants::WHEEL_REAR_RIGHT"
                 }
             ],
             "comment": "Units in kpa",
             "maxSampleRate": 2.0,
-            "minSampleRate": 1.0
+            "minSampleRate": 1.0,
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minFloatValue": 193.0,
+            "maxFloatValue": 300.0
         },
         {
             "property": "VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE",
@@ -1817,9 +1706,7 @@
                             0
                         ]
                     },
-                    "areaId": "Constants::WHEEL_FRONT_LEFT",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100
+                    "areaId": "Constants::WHEEL_FRONT_LEFT"
                 },
                 {
                     "defaultValue": {
@@ -1827,9 +1714,7 @@
                             0
                         ]
                     },
-                    "areaId": "Constants::WHEEL_FRONT_RIGHT",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT"
                 },
                 {
                     "defaultValue": {
@@ -1837,9 +1722,7 @@
                             0
                         ]
                     },
-                    "areaId": "Constants::WHEEL_REAR_RIGHT",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100
+                    "areaId": "Constants::WHEEL_REAR_RIGHT"
                 },
                 {
                     "defaultValue": {
@@ -1847,13 +1730,17 @@
                             0
                         ]
                     },
-                    "areaId": "Constants::WHEEL_REAR_LEFT",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100
+                    "areaId": "Constants::WHEEL_REAR_LEFT"
                 }
             ],
             "maxSampleRate": 10.0,
-            "minSampleRate": 1.0
+            "minSampleRate": 1.0,
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -100,
+            "maxInt32Value": 100
         },
         {
             "property": "VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS",
@@ -1911,11 +1798,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::EV_STOPPING_MODE",
@@ -1926,13 +1817,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "Constants::EV_STOPPING_MODE_CREEP",
-                        "Constants::EV_STOPPING_MODE_ROLL",
-                        "Constants::EV_STOPPING_MODE_HOLD"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "Constants::EV_STOPPING_MODE_CREEP",
+                "Constants::EV_STOPPING_MODE_ROLL",
+                "Constants::EV_STOPPING_MODE_HOLD"
             ]
         },
         {
@@ -2334,31 +2228,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 1,
+            "maxInt32Value": 7
         },
         {
             "property": "VehicleProperty::HVAC_FAN_DIRECTION",
@@ -2426,32 +2316,28 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
             ],
-            "comment": "0 is off and +ve values indicate ventilation level."
+            "comment": "0 is off and +ve values indicate ventilation level.",
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::HVAC_STEERING_WHEEL_HEAT",
@@ -2462,12 +2348,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2
+                    "areaId": 0
                 }
             ],
-            "comment": "+ve values for heating and -ve for cooling"
+            "comment": "+ve values for heating and -ve for cooling",
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -2,
+            "maxInt32Value": 2
         },
         {
             "property": "VehicleProperty::HVAC_SEAT_TEMPERATURE",
@@ -2478,32 +2368,28 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
             ],
-            "comment": "+ve values for heating and -ve for cooling"
+            "comment": "+ve values for heating and -ve for cooling",
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -2,
+            "maxInt32Value": 2
         },
         {
             "property": "VehicleProperty::HVAC_SIDE_MIRROR_HEAT",
@@ -2514,11 +2400,15 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 2
+                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 2
         },
         {
             "property": "VehicleProperty::HVAC_TEMPERATURE_CURRENT",
@@ -2554,29 +2444,19 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
             ],
             "comment":
@@ -2588,6 +2468,46 @@
                 600,
                 900,
                 10
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true,
+                "hasSupportedValuesList": true
+            },
+            "minFloatValue": 17.5,
+            "maxFloatValue": 32.5,
+            "supportedValues": [
+                17.5,
+                18,
+                18.5,
+                19,
+                19.5,
+                20,
+                20.5,
+                21,
+                21.5,
+                22,
+                22.5,
+                23,
+                23.5,
+                24,
+                24.5,
+                25,
+                25.5,
+                26,
+                26.5,
+                27,
+                27.5,
+                28,
+                28.5,
+                29,
+                29.5,
+                30,
+                30.5,
+                31,
+                31.5,
+                32,
+                32.5
             ]
         },
         {
@@ -2728,16 +2648,19 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ImpactSensorLocation::FRONT",
-                        "ImpactSensorLocation::FRONT_LEFT_DOOR_SIDE",
-                        "ImpactSensorLocation::FRONT_RIGHT_DOOR_SIDE",
-                        "ImpactSensorLocation::REAR_LEFT_DOOR_SIDE",
-                        "ImpactSensorLocation::REAR_RIGHT_DOOR_SIDE",
-                        "ImpactSensorLocation::REAR"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ImpactSensorLocation::FRONT",
+                "ImpactSensorLocation::FRONT_LEFT_DOOR_SIDE",
+                "ImpactSensorLocation::FRONT_RIGHT_DOOR_SIDE",
+                "ImpactSensorLocation::REAR_LEFT_DOOR_SIDE",
+                "ImpactSensorLocation::REAR_RIGHT_DOOR_SIDE",
+                "ImpactSensorLocation::REAR"
             ]
         },
         {
@@ -2810,31 +2733,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::DOOR_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::DOOR_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::DOOR_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::DOOR_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::DOOR_REAR",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_REAR"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::DOOR_MOVE",
@@ -2845,26 +2764,24 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::DOOR_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::DOOR_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::DOOR_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::DOOR_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::DOOR_2_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::MIRROR_Z_POS",
@@ -2875,21 +2792,21 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -3,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::MIRROR_Z_MOVE",
@@ -2900,21 +2817,21 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::MIRROR_Y_POS",
@@ -2925,21 +2842,21 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -3,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::MIRROR_Y_MOVE",
@@ -2950,21 +2867,21 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::MIRROR_LOCK",
@@ -3032,27 +2949,47 @@
                 {
                     "areaId": "Constants::WINDOW_1_LEFT",
                     "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "maxInt32Value": 10,
+                    "hasSupportedValueInfo": {
+                        "hasMinSupportedValue": true,
+                        "hasMaxSupportedValue": true
+                    }
                 },
                 {
                     "areaId": "Constants::WINDOW_1_RIGHT",
                     "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "maxInt32Value": 10,
+                    "hasSupportedValueInfo": {
+                        "hasMinSupportedValue": true,
+                        "hasMaxSupportedValue": true
+                    }
                 },
                 {
                     "areaId": "Constants::WINDOW_2_LEFT",
                     "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "maxInt32Value": 10,
+                    "hasSupportedValueInfo": {
+                        "hasMinSupportedValue": true,
+                        "hasMaxSupportedValue": true
+                    }
                 },
                 {
                     "areaId": "Constants::WINDOW_2_RIGHT",
                     "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "maxInt32Value": 10,
+                    "hasSupportedValueInfo": {
+                        "hasMinSupportedValue": true,
+                        "hasMaxSupportedValue": true
+                    }
                 },
                 {
                     "areaId": "Constants::WINDOW_ROOF_TOP_1",
                     "minInt32Value": -10,
-                    "maxInt32Value": 10
+                    "maxInt32Value": 10,
+                    "hasSupportedValueInfo": {
+                        "hasMinSupportedValue": true,
+                        "hasMaxSupportedValue": true
+                    }
                 }
             ]
         },
@@ -3065,31 +3002,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::WINDOW_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::WINDOW_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::WINDOW_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::WINDOW_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::WINDOW_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::WINDOW_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::WINDOW_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::WINDOW_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::WINDOW_ROOF_TOP_1",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1
+                    "areaId": "Constants::WINDOW_ROOF_TOP_1"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::WINDSHIELD_WIPERS_PERIOD",
@@ -3100,16 +3033,18 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3000
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
                 },
                 {
-                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3000
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3000
         },
         {
             "property": "VehicleProperty::WINDSHIELD_WIPERS_STATE",
@@ -3125,14 +3060,20 @@
                         "WindshieldWipersState::OFF",
                         "WindshieldWipersState::ON",
                         "WindshieldWipersState::SERVICE"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 },
                 {
                     "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
                     "supportedEnumValues": [
                         "WindshieldWipersState::OFF",
                         "WindshieldWipersState::ON"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 }
             ]
         },
@@ -3161,7 +3102,10 @@
                         "WindshieldWipersSwitch::CONTINUOUS_LEVEL_5",
                         "WindshieldWipersSwitch::AUTO",
                         "WindshieldWipersSwitch::SERVICE"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 },
                 {
                     "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
@@ -3173,7 +3117,10 @@
                         "WindshieldWipersSwitch::CONTINUOUS_LEVEL_2",
                         "WindshieldWipersSwitch::AUTO",
                         "WindshieldWipersSwitch::SERVICE"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 }
             ]
         },
@@ -3186,11 +3133,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::STEERING_WHEEL_DEPTH_MOVE",
@@ -3201,11 +3152,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -2,
+            "maxInt32Value": 2
         },
         {
             "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_POS",
@@ -3216,11 +3171,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE",
@@ -3231,11 +3190,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -2,
+            "maxInt32Value": 2
         },
         {
             "property": "VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED",
@@ -3270,11 +3233,15 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::GLOVE_BOX_LOCKED",
@@ -3493,12 +3460,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "Constants::LIGHT_STATE_OFF",
-                        "Constants::LIGHT_STATE_ON"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "Constants::LIGHT_STATE_OFF",
+                "Constants::LIGHT_STATE_ON"
             ]
         },
         {
@@ -3583,13 +3553,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "Constants::LIGHT_SWITCH_OFF",
-                        "Constants::LIGHT_SWITCH_ON",
-                        "Constants::LIGHT_SWITCH_AUTO"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "Constants::LIGHT_SWITCH_OFF",
+                "Constants::LIGHT_SWITCH_ON",
+                "Constants::LIGHT_SWITCH_AUTO"
             ]
         },
         {
@@ -4478,20 +4451,23 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "EmergencyLaneKeepAssistState::ENABLED",
-                        "EmergencyLaneKeepAssistState::WARNING_LEFT",
-                        "EmergencyLaneKeepAssistState::WARNING_RIGHT",
-                        "EmergencyLaneKeepAssistState::ACTIVATED_STEER_LEFT",
-                        "EmergencyLaneKeepAssistState::ACTIVATED_STEER_RIGHT",
-                        "EmergencyLaneKeepAssistState::USER_OVERRIDE"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "EmergencyLaneKeepAssistState::ENABLED",
+                "EmergencyLaneKeepAssistState::WARNING_LEFT",
+                "EmergencyLaneKeepAssistState::WARNING_RIGHT",
+                "EmergencyLaneKeepAssistState::ACTIVATED_STEER_LEFT",
+                "EmergencyLaneKeepAssistState::ACTIVATED_STEER_RIGHT",
+                "EmergencyLaneKeepAssistState::USER_OVERRIDE"
             ]
         },
         {
@@ -4511,17 +4487,20 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "CruiseControlType::STANDARD",
-                        "CruiseControlType::ADAPTIVE",
-                        "CruiseControlType::PREDICTIVE"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "CruiseControlType::STANDARD",
+                "CruiseControlType::ADAPTIVE",
+                "CruiseControlType::PREDICTIVE"
             ]
         },
         {
@@ -4533,35 +4512,41 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "CruiseControlState::ENABLED",
-                        "CruiseControlState::ACTIVATED",
-                        "CruiseControlState::USER_OVERRIDE",
-                        "CruiseControlState::SUSPENDED",
-                        "CruiseControlState::FORCED_DEACTIVATION_WARNING"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "CruiseControlState::ENABLED",
+                "CruiseControlState::ACTIVATED",
+                "CruiseControlState::USER_OVERRIDE",
+                "CruiseControlState::SUSPENDED",
+                "CruiseControlState::FORCED_DEACTIVATION_WARNING"
             ]
         },
         {
             "property": "VehicleProperty::CRUISE_CONTROL_COMMAND",
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "CruiseControlCommand::ACTIVATE",
-                        "CruiseControlCommand::SUSPEND",
-                        "CruiseControlCommand::INCREASE_TARGET_SPEED",
-                        "CruiseControlCommand::DECREASE_TARGET_SPEED",
-                        "CruiseControlCommand::INCREASE_TARGET_TIME_GAP",
-                        "CruiseControlCommand::DECREASE_TARGET_TIME_GAP"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "CruiseControlCommand::ACTIVATE",
+                "CruiseControlCommand::SUSPEND",
+                "CruiseControlCommand::INCREASE_TARGET_SPEED",
+                "CruiseControlCommand::DECREASE_TARGET_SPEED",
+                "CruiseControlCommand::INCREASE_TARGET_TIME_GAP",
+                "CruiseControlCommand::DECREASE_TARGET_TIME_GAP"
             ]
         },
         {
@@ -4573,11 +4558,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minFloatValue": 20.0,
-                    "maxFloatValue": 35.0
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minFloatValue": 20.0,
+            "maxFloatValue": 35.0
         },
         {
             "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP",
@@ -4604,13 +4593,17 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": 0,
-                    "maxInt32Value": 200000
+                    "areaId": 0
                 }
             ],
             "maxSampleRate": 10.0,
-            "minSampleRate": 1.0
+            "minSampleRate": 1.0,
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 200000
         },
         {
             "property": "VehicleProperty::HANDS_ON_DETECTION_ENABLED",
@@ -4629,13 +4622,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "HandsOnDetectionDriverState::HANDS_ON",
-                        "HandsOnDetectionDriverState::HANDS_OFF"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "HandsOnDetectionDriverState::HANDS_ON",
+                "HandsOnDetectionDriverState::HANDS_OFF"
             ]
         },
         {
@@ -4647,13 +4643,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "HandsOnDetectionWarning::NO_WARNING",
-                        "HandsOnDetectionWarning::WARNING"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "HandsOnDetectionWarning::NO_WARNING",
+                "HandsOnDetectionWarning::WARNING"
             ]
         },
         {
@@ -4673,20 +4672,23 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "DriverDrowsinessAttentionState::KSS_RATING_1_EXTREMELY_ALERT",
-                        "DriverDrowsinessAttentionState::KSS_RATING_2_VERY_ALERT",
-                        "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT",
-                        "DriverDrowsinessAttentionState::KSS_RATING_4_RATHER_ALERT",
-                        "DriverDrowsinessAttentionState::KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY",
-                        "DriverDrowsinessAttentionState::KSS_RATING_6_SOME_SLEEPINESS",
-                        "DriverDrowsinessAttentionState::KSS_RATING_7_SLEEPY_NO_EFFORT",
-                        "DriverDrowsinessAttentionState::KSS_RATING_8_SLEEPY_SOME_EFFORT",
-                        "DriverDrowsinessAttentionState::KSS_RATING_9_VERY_SLEEPY"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "DriverDrowsinessAttentionState::KSS_RATING_1_EXTREMELY_ALERT",
+                "DriverDrowsinessAttentionState::KSS_RATING_2_VERY_ALERT",
+                "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT",
+                "DriverDrowsinessAttentionState::KSS_RATING_4_RATHER_ALERT",
+                "DriverDrowsinessAttentionState::KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY",
+                "DriverDrowsinessAttentionState::KSS_RATING_6_SOME_SLEEPINESS",
+                "DriverDrowsinessAttentionState::KSS_RATING_7_SLEEPY_NO_EFFORT",
+                "DriverDrowsinessAttentionState::KSS_RATING_8_SLEEPY_SOME_EFFORT",
+                "DriverDrowsinessAttentionState::KSS_RATING_9_VERY_SLEEPY"
             ]
         },
         {
@@ -4706,13 +4708,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "DriverDrowsinessAttentionWarning::NO_WARNING",
-                        "DriverDrowsinessAttentionWarning::WARNING"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "DriverDrowsinessAttentionWarning::NO_WARNING",
+                "DriverDrowsinessAttentionWarning::WARNING"
             ]
         },
         {
@@ -4732,13 +4737,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "DriverDistractionState::NOT_DISTRACTED",
-                        "DriverDistractionState::DISTRACTED"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "DriverDistractionState::NOT_DISTRACTED",
+                "DriverDistractionState::DISTRACTED"
             ]
         },
         {
@@ -4758,13 +4766,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "DriverDistractionWarning::NO_WARNING",
-                        "DriverDistractionWarning::WARNING"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "DriverDistractionWarning::NO_WARNING",
+                "DriverDistractionWarning::WARNING"
             ]
         },
         {
@@ -4804,10 +4815,10 @@
             "property": "VehicleProperty::VHAL_HEARTBEAT",
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportVariableUpdateRate": false
+                    "areaId": 0
                 }
-            ]
+            ],
+            "supportVariableUpdateRate": false
         },
         {
             "property": "VehicleProperty::CLUSTER_SWITCH_UI",
@@ -4871,11 +4882,11 @@
             ],
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportVariableUpdateRate": false
+                    "areaId": 0
                 }
             ],
-            "comment": "configArray specifies it consists of int64[2] and byte[16]."
+            "comment": "configArray specifies it consists of int64[2] and byte[16].",
+            "supportVariableUpdateRate": false
         },
         {
             "property": "VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT",
@@ -4929,18 +4940,21 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "AutomaticEmergencyBrakingState::ENABLED",
-                        "AutomaticEmergencyBrakingState::ACTIVATED",
-                        "AutomaticEmergencyBrakingState::USER_OVERRIDE"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "AutomaticEmergencyBrakingState::ENABLED",
+                "AutomaticEmergencyBrakingState::ACTIVATED",
+                "AutomaticEmergencyBrakingState::USER_OVERRIDE"
             ]
         },
         {
@@ -4960,17 +4974,20 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "ForwardCollisionWarningState::NO_WARNING",
-                        "ForwardCollisionWarningState::WARNING"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "ForwardCollisionWarningState::NO_WARNING",
+                "ForwardCollisionWarningState::WARNING"
             ]
         },
         {
@@ -4990,29 +5007,23 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "BlindSpotWarningState::NO_WARNING",
-                        "BlindSpotWarningState::WARNING"
-                    ]
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "BlindSpotWarningState::NO_WARNING",
-                        "BlindSpotWarningState::WARNING"
-                    ]
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "BlindSpotWarningState::NO_WARNING",
+                "BlindSpotWarningState::WARNING"
             ]
         },
         {
@@ -5032,17 +5043,20 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "LaneDepartureWarningState::NO_WARNING",
-                        "LaneDepartureWarningState::WARNING_LEFT",
-                        "LaneDepartureWarningState::WARNING_RIGHT"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "LaneDepartureWarningState::NO_WARNING",
+                "LaneDepartureWarningState::WARNING_LEFT",
+                "LaneDepartureWarningState::WARNING_RIGHT"
             ]
         },
         {
@@ -5062,18 +5076,21 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "LaneKeepAssistState::ENABLED",
-                        "LaneKeepAssistState::ACTIVATED_STEER_LEFT",
-                        "LaneKeepAssistState::ACTIVATED_STEER_RIGHT",
-                        "LaneKeepAssistState::USER_OVERRIDE"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "LaneKeepAssistState::ENABLED",
+                "LaneKeepAssistState::ACTIVATED_STEER_LEFT",
+                "LaneKeepAssistState::ACTIVATED_STEER_RIGHT",
+                "LaneKeepAssistState::USER_OVERRIDE"
             ]
         },
         {
@@ -5096,19 +5113,22 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "LaneCenteringAssistState::ENABLED",
-                        "LaneCenteringAssistState::ACTIVATION_REQUESTED",
-                        "LaneCenteringAssistState::ACTIVATED",
-                        "LaneCenteringAssistState::USER_OVERRIDE",
-                        "LaneCenteringAssistState::FORCED_DEACTIVATION_WARNING"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "LaneCenteringAssistState::ENABLED",
+                "LaneCenteringAssistState::ACTIVATION_REQUESTED",
+                "LaneCenteringAssistState::ACTIVATED",
+                "LaneCenteringAssistState::USER_OVERRIDE",
+                "LaneCenteringAssistState::FORCED_DEACTIVATION_WARNING"
             ]
         },
         {
@@ -5128,16 +5148,19 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "LowSpeedCollisionWarningState::NO_WARNING",
-                        "LowSpeedCollisionWarningState::WARNING"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "LowSpeedCollisionWarningState::NO_WARNING",
+                "LowSpeedCollisionWarningState::WARNING"
             ]
         },
         {
@@ -5157,16 +5180,19 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_SPEED_LOW",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "ElectronicStabilityControlState::ENABLED",
-                        "ElectronicStabilityControlState::ACTIVATED"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_SPEED_LOW",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "ElectronicStabilityControlState::ENABLED",
+                "ElectronicStabilityControlState::ACTIVATED"
             ]
         },
         {
@@ -5186,21 +5212,24 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "CrossTrafficMonitoringWarningState::NO_WARNING",
-                        "CrossTrafficMonitoringWarningState::WARNING_FRONT_LEFT",
-                        "CrossTrafficMonitoringWarningState::WARNING_FRONT_RIGHT",
-                        "CrossTrafficMonitoringWarningState::WARNING_FRONT_BOTH",
-                        "CrossTrafficMonitoringWarningState::WARNING_REAR_LEFT",
-                        "CrossTrafficMonitoringWarningState::WARNING_REAR_RIGHT",
-                        "CrossTrafficMonitoringWarningState::WARNING_REAR_BOTH"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "CrossTrafficMonitoringWarningState::NO_WARNING",
+                "CrossTrafficMonitoringWarningState::WARNING_FRONT_LEFT",
+                "CrossTrafficMonitoringWarningState::WARNING_FRONT_RIGHT",
+                "CrossTrafficMonitoringWarningState::WARNING_FRONT_BOTH",
+                "CrossTrafficMonitoringWarningState::WARNING_REAR_LEFT",
+                "CrossTrafficMonitoringWarningState::WARNING_REAR_RIGHT",
+                "CrossTrafficMonitoringWarningState::WARNING_REAR_BOTH"
             ]
         },
         {
@@ -5220,33 +5249,24 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportedEnumValues": [
-                        "ErrorState::NOT_AVAILABLE_SAFETY",
-                        "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
-                        "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
-                        "ErrorState::NOT_AVAILABLE_DISABLED",
-                        "LowSpeedAutomaticEmergencyBrakingState::ENABLED",
-                        "LowSpeedAutomaticEmergencyBrakingState::ACTIVATED",
-                        "LowSpeedAutomaticEmergencyBrakingState::USER_OVERRIDE"
-                    ]
+                    "areaId": 0
                 }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedEnumValues": [
+                "ErrorState::NOT_AVAILABLE_SAFETY",
+                "ErrorState::NOT_AVAILABLE_POOR_VISIBILITY",
+                "ErrorState::NOT_AVAILABLE_SPEED_HIGH",
+                "ErrorState::NOT_AVAILABLE_DISABLED",
+                "LowSpeedAutomaticEmergencyBrakingState::ENABLED",
+                "LowSpeedAutomaticEmergencyBrakingState::ACTIVATED",
+                "LowSpeedAutomaticEmergencyBrakingState::USER_OVERRIDE"
             ]
         },
         {
-            "property": "VehicleProperty::CAMERA_SERVICE_CURRENT_STATE",
-            "defaultValue": {
-                "int32Values": [
-                    "CameraServiceState::UNAVAILABLE",
-                    "CameraServiceState::UNAVAILABLE",
-                    "CameraServiceState::UNAVAILABLE",
-                    "CameraServiceState::UNAVAILABLE",
-                    "CameraServiceState::UNAVAILABLE",
-                    "CameraServiceState::UNAVAILABLE",
-                    "CameraServiceState::UNAVAILABLE",
-                    "CameraServiceState::UNAVAILABLE"
-                ]
-            }
+            "property": "VehicleProperty::CAMERA_SERVICE_CURRENT_STATE"
         }
     ]
 }
diff --git a/automotive/vehicle/aidl/impl/current/default_config/config/TestProperties.json b/automotive/vehicle/aidl/impl/current/default_config/config/TestProperties.json
index 83debf7..e3da23b 100644
--- a/automotive/vehicle/aidl/impl/current/default_config/config/TestProperties.json
+++ b/automotive/vehicle/aidl/impl/current/default_config/config/TestProperties.json
@@ -1,4 +1,5 @@
 {
+    "apiVersion": 2,
     "properties": [
         {
             "property": "TestVendorProperty::MIXED_TYPE_PROPERTY_FOR_TEST",
@@ -75,9 +76,7 @@
                             1.0
                         ]
                     },
-                    "areaId": "Constants::HVAC_LEFT",
-                    "minFloatValue": -10.0,
-                    "maxFloatValue": 10.0
+                    "areaId": "Constants::HVAC_LEFT"
                 },
                 {
                     "defaultValue": {
@@ -85,13 +84,17 @@
                             2.0
                         ]
                     },
-                    "areaId": "Constants::HVAC_RIGHT",
-                    "minFloatValue": -10.0,
-                    "maxFloatValue": 10.0
+                    "areaId": "Constants::HVAC_RIGHT"
                 }
             ],
             "access": "VehiclePropertyAccess::READ_WRITE",
-            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE",
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minFloatValue": -10.0,
+            "maxFloatValue": 10.0
         },
         {
             "property": "TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY",
@@ -102,12 +105,7 @@
                             2
                         ]
                     },
-                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true,
-                        "hasSupportedValuesList": true
-                    }
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
                 },
                 {
                     "defaultValue": {
@@ -115,9 +113,7 @@
                             0
                         ]
                     },
-                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
                 },
                 {
                     "defaultValue": {
@@ -125,13 +121,23 @@
                             -1
                         ]
                     },
-                    "areaId": "VehicleAreaWindow::ROOF_TOP_1",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100
+                    "areaId": "VehicleAreaWindow::ROOF_TOP_1"
                 }
             ],
             "access": "VehiclePropertyAccess::READ_WRITE",
-            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE"
+            "changeMode": "VehiclePropertyChangeMode::ON_CHANGE",
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true,
+                "hasSupportedValuesList": true
+            },
+            "minInt32Value": -100,
+            "maxInt32Value": 100,
+            "supportedValues": [
+                1,
+                2,
+                3
+            ]
         },
         {
             "property": "TestVendorProperty::VENDOR_EXTENSION_STRING_PROPERTY",
@@ -209,4 +215,4 @@
             ]
         }
     ]
-}
\ No newline at end of file
+}
diff --git a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h
index e20befc..d51e430 100644
--- a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -170,6 +170,13 @@
         std::shared_ptr<RecurrentTimer::Callback> recurrentAction;
     };
 
+    struct DumpOptionPropIdAreaIdInfo {
+        int32_t propId;
+        int32_t areaId;
+        std::string propIdStr;
+        std::string areaIdStr;
+    };
+
     const std::unique_ptr<obd2frame::FakeObd2Frame> mFakeObd2Frame;
     const std::unique_ptr<FakeUserHal> mFakeUserHal;
     // RecurrentTimer is thread-safe.
@@ -189,9 +196,17 @@
     std::unordered_map<PropIdAreaId, VehiclePropValuePool::RecyclableType, PropIdAreaIdHash>
             mSavedProps GUARDED_BY(mLock);
     std::unordered_set<PropIdAreaId, PropIdAreaIdHash> mSubOnChangePropIdAreaIds GUARDED_BY(mLock);
-    int32_t mMinSupportedValueForTestIntProp GUARDED_BY(mLock) = 0;
-    int32_t mMaxSupportedValueForTestIntProp GUARDED_BY(mLock) = 10;
-    std::vector<int32_t> mSupportedValuesListForTestIntProp GUARDED_BY(mLock) = {0, 2, 4, 6, 8, 10};
+
+    std::unordered_map<PropIdAreaId, aidl::android::hardware::automotive::vehicle::RawPropValues,
+                       PropIdAreaIdHash>
+            mMinSupportedValueByPropIdAreaId GUARDED_BY(mLock);
+    std::unordered_map<PropIdAreaId, aidl::android::hardware::automotive::vehicle::RawPropValues,
+                       PropIdAreaIdHash>
+            mMaxSupportedValueByPropIdAreaId GUARDED_BY(mLock);
+    std::unordered_map<PropIdAreaId,
+                       std::vector<aidl::android::hardware::automotive::vehicle::RawPropValues>,
+                       PropIdAreaIdHash>
+            mSupportedValuesByPropIdAreaId GUARDED_BY(mLock);
 
     // PendingRequestHandler is thread-safe.
     mutable PendingRequestHandler<GetValuesCallback,
@@ -320,9 +335,17 @@
                                float sampleRateHz) REQUIRES(mLock);
     void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock);
     void refreshTimestampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
-    void triggerSupportedValueChange(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& config)
-            EXCLUDES(mLock);
+    void triggerSupportedValueChange(int32_t propId, int32_t areaId) EXCLUDES(mLock);
+    template <class T>
+    void setMinSupportedValueLocked(int32_t propId, int32_t areaId, T minValue) REQUIRES(mLock);
+    template <class T>
+    void setMaxSupportedValueLocked(int32_t propId, int32_t areaId, T maxValue) REQUIRES(mLock);
+    template <class T>
+    android::base::Result<void> parseAndSetMinMaxValue(int32_t propId, int32_t areaId,
+                                                       const std::vector<std::string>& options,
+                                                       size_t index) EXCLUDES(mLock);
+    android::base::Result<DumpOptionPropIdAreaIdInfo> parseDumpOptionPropIdAreaId(
+            const std::vector<std::string>& options, size_t& index);
 
     static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
             aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
@@ -355,6 +378,14 @@
                                                       size_t index);
     static android::base::Result<int32_t> parseAreaId(const std::vector<std::string>& options,
                                                       size_t index, int32_t propId);
+    template <class T>
+    static android::base::Result<std::vector<T>> parseOptionValues(
+            const std::vector<std::string>& options, size_t index, size_t count);
+
+    template <class T>
+    static android::base::Result<
+            std::vector<aidl::android::hardware::automotive::vehicle::RawPropValues>>
+    parseOptionsToSupportedValuesList(const std::vector<std::string>& options, size_t index);
 };
 
 }  // namespace fake
diff --git a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 01e40fb..4eb84dd 100644
--- a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -297,6 +297,24 @@
     return ss.str();
 }
 
+template <class T>
+RawPropValues createRawPropValues(T value);
+
+template <>
+RawPropValues createRawPropValues(int32_t value) {
+    return RawPropValues{.int32Values = {value}};
+}
+
+template <>
+RawPropValues createRawPropValues(int64_t value) {
+    return RawPropValues{.int64Values = {value}};
+}
+
+template <>
+RawPropValues createRawPropValues(float value) {
+    return RawPropValues{.floatValues = {value}};
+}
+
 }  // namespace
 
 void FakeVehicleHardware::storePropInitialValue(const ConfigDeclaration& config) {
@@ -398,26 +416,152 @@
     return configsByPropId;
 }
 
+template <class T>
+void FakeVehicleHardware::setMinSupportedValueLocked(int32_t propId, int32_t areaId, T minValue) {
+    mMinSupportedValueByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
+            createRawPropValues<T>(minValue);
+}
+
+template <class T>
+void FakeVehicleHardware::setMaxSupportedValueLocked(int32_t propId, int32_t areaId, T maxValue) {
+    mMaxSupportedValueByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
+            createRawPropValues<T>(maxValue);
+}
+
 void FakeVehicleHardware::init(int32_t s2rS2dConfig) {
     maybeGetGrpcServiceInfo(&mPowerControllerServiceAddress);
 
-    for (auto& [_, configDeclaration] : loadConfigDeclarations()) {
-        VehiclePropConfig cfg = configDeclaration.config;
-        VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        for (auto& [_, configDeclaration] : loadConfigDeclarations()) {
+            VehiclePropConfig cfg = configDeclaration.config;
+            VehiclePropertyStore::TokenFunction tokenFunction = nullptr;
 
-        if (cfg.prop == toInt(VehicleProperty::AP_POWER_STATE_REQ)) {
-            cfg.configArray[0] = s2rS2dConfig;
-        } else if (cfg.prop == OBD2_FREEZE_FRAME) {
-            tokenFunction = [](const VehiclePropValue& propValue) { return propValue.timestamp; };
-        }
+            if (cfg.prop == toInt(VehicleProperty::AP_POWER_STATE_REQ)) {
+                cfg.configArray[0] = s2rS2dConfig;
+            } else if (cfg.prop == OBD2_FREEZE_FRAME) {
+                tokenFunction = [](const VehiclePropValue& propValue) {
+                    return propValue.timestamp;
+                };
+            }
 
-        mServerSidePropStore->registerProperty(cfg, tokenFunction);
-        if (obd2frame::FakeObd2Frame::isDiagnosticProperty(cfg)) {
-            // Ignore storing default value for diagnostic property. They have special get/set
-            // logic.
-            continue;
+            mServerSidePropStore->registerProperty(cfg, tokenFunction);
+            if (obd2frame::FakeObd2Frame::isDiagnosticProperty(cfg)) {
+                // Ignore storing default value for diagnostic property. They have special get/set
+                // logic.
+                continue;
+            }
+            storePropInitialValue(configDeclaration);
+
+            int32_t propertyType = cfg.prop & toInt(VehiclePropertyType::MASK);
+            for (const auto& areaConfig : cfg.areaConfigs) {
+                if (!areaConfig.hasSupportedValueInfo.has_value()) {
+                    continue;
+                }
+                if (areaConfig.hasSupportedValueInfo->hasMinSupportedValue) {
+                    switch (propertyType) {
+                        case toInt(VehiclePropertyType::INT32):
+                            setMinSupportedValueLocked(cfg.prop, areaConfig.areaId,
+                                                       areaConfig.minInt32Value);
+                            break;
+                        case toInt(VehiclePropertyType::INT64):
+                            setMinSupportedValueLocked(cfg.prop, areaConfig.areaId,
+                                                       areaConfig.minInt64Value);
+                            break;
+                        case toInt(VehiclePropertyType::FLOAT):
+                            setMinSupportedValueLocked(cfg.prop, areaConfig.areaId,
+                                                       areaConfig.minFloatValue);
+                            break;
+                        default:
+                            ALOGE("hasMinSupportedValue must only be true for INT32, INT64 or "
+                                  "FLOAT "
+                                  "type property");
+                            continue;
+                    }
+                }
+                if (areaConfig.hasSupportedValueInfo->hasMaxSupportedValue) {
+                    switch (propertyType) {
+                        case toInt(VehiclePropertyType::INT32):
+                            setMaxSupportedValueLocked(cfg.prop, areaConfig.areaId,
+                                                       areaConfig.maxInt32Value);
+                            break;
+                        case toInt(VehiclePropertyType::INT64):
+                            setMaxSupportedValueLocked(cfg.prop, areaConfig.areaId,
+                                                       areaConfig.maxInt64Value);
+                            break;
+                        case toInt(VehiclePropertyType::FLOAT):
+                            setMaxSupportedValueLocked(cfg.prop, areaConfig.areaId,
+                                                       areaConfig.maxFloatValue);
+                            break;
+                        default:
+                            ALOGE("hasMaxSupportedValue must only be true for INT32, INT64 or "
+                                  "FLOAT type property");
+                            continue;
+                    }
+                }
+                if (areaConfig.hasSupportedValueInfo->hasSupportedValuesList) {
+                    std::vector<RawPropValues> supportedValuesList;
+                    // We first check "supportedValues" field to populate supported values list.
+                    const auto& supportedValuesForAreaId =
+                            configDeclaration.supportedValuesForAreaId;
+                    const auto it = supportedValuesForAreaId.find(areaConfig.areaId);
+                    if (it != supportedValuesForAreaId.end()) {
+                        for (float supportedValueFloat : it->second) {
+                            switch (propertyType) {
+                                case toInt(VehiclePropertyType::INT32):
+                                    supportedValuesList.push_back(createRawPropValues(
+                                            static_cast<int32_t>(supportedValueFloat)));
+                                    break;
+                                case toInt(VehiclePropertyType::INT64):
+                                    supportedValuesList.push_back(createRawPropValues(
+                                            static_cast<int64_t>(supportedValueFloat)));
+                                    break;
+                                case toInt(VehiclePropertyType::FLOAT):
+                                    supportedValuesList.push_back(
+                                            createRawPropValues(supportedValueFloat));
+                                    break;
+                                default:
+                                    ALOGE("supportedValues field is only supported for INT32, "
+                                          "INT64 or FLOAT type "
+                                          "property");
+                            }
+                        }
+                    } else {
+                        // If "supportedValues" is not specified, try to use "supportedEnumValues".
+                        switch (propertyType) {
+                            case toInt(VehiclePropertyType::INT32):
+                                if (areaConfig.supportedEnumValues.has_value()) {
+                                    for (int64_t supportedEnumValue :
+                                         *areaConfig.supportedEnumValues) {
+                                        int32_t supportedValue =
+                                                static_cast<int32_t>(supportedEnumValue);
+                                        supportedValuesList.push_back(
+                                                createRawPropValues(supportedValue));
+                                    }
+                                }
+                                break;
+                            case toInt(VehiclePropertyType::INT64):
+                                if (areaConfig.supportedEnumValues.has_value()) {
+                                    for (int64_t supportedEnumValue :
+                                         *areaConfig.supportedEnumValues) {
+                                        supportedValuesList.push_back(
+                                                createRawPropValues(supportedEnumValue));
+                                    }
+                                }
+                                break;
+                            default:
+                                // Do nothing
+                                break;
+                        }
+                    }
+                    if (!supportedValuesList.empty()) {
+                        mSupportedValuesByPropIdAreaId[PropIdAreaId{.propId = cfg.prop,
+                                                                    .areaId = areaConfig.areaId}] =
+                                std::move(supportedValuesList);
+                    }
+                }
+            }
         }
-        storePropInitialValue(configDeclaration);
     }
 
     // OBD2_LIVE_FRAME and OBD2_FREEZE_FRAME must be configured in default configs.
@@ -1799,119 +1943,252 @@
     return result;
 }
 
-std::string FakeVehicleHardware::dumpSetMinMaxValue(const std::vector<std::string>& options) {
-    if (auto result = checkArgumentsSize(options, /*minSize=*/3); !result.ok()) {
-        return getErrorMsg(result);
+Result<FakeVehicleHardware::DumpOptionPropIdAreaIdInfo>
+FakeVehicleHardware::parseDumpOptionPropIdAreaId(const std::vector<std::string>& options,
+                                                 size_t& index) {
+    const std::string& propIdStr = options[index];
+    auto maybePropId = parsePropId(options, index);
+    index++;
+    if (!maybePropId.ok()) {
+        return Error() << "propId not valid: " << propIdStr;
     }
-    int testPropId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY);
-    auto configResult = mServerSidePropStore->getPropConfig(testPropId);
+    int32_t propId = maybePropId.value();
+    auto configResult = mServerSidePropStore->getPropConfig(propId);
     if (!configResult.ok()) {
-        return "Failed to set min/max supported value: VENDOR_EXTENSION_INT_PROPERTY not supported";
+        return Error() << "property not supported";
     }
-    int32_t values[2];
-    for (size_t i = 1; i < 3; i++) {
-        auto int32Result = safelyParseInt<int32_t>(i, options[i]);
-        if (!int32Result.ok()) {
-            return StringPrintf(
-                    "Failed to set min/max supported value: Value: \"%s\" is not a valid int: %s\n",
-                    options[i].c_str(), getErrorMsg(int32Result).c_str());
+    std::string areaIdStr = "0";
+    int32_t areaId = 0;
+    if (EqualsIgnoreCase(options[index], "-a")) {
+        index++;
+        if (index >= options.size()) {
+            return Error() << "Not enough arguments";
         }
-        values[i - 1] = int32Result.value();
+        areaIdStr = options[index];
+        auto maybeAreaId = parseAreaId(options, index, propId);
+        if (!maybeAreaId.ok()) {
+            return Error() << "areaId not valid: " << areaIdStr;
+        }
+        areaId = maybeAreaId.value();
+        index++;
     }
-    int32_t minValue = values[0];
-    int32_t maxValue = values[1];
+    return DumpOptionPropIdAreaIdInfo{
+            .propId = propId, .areaId = areaId, .propIdStr = propIdStr, .areaIdStr = areaIdStr};
+}
+
+template <class T>
+Result<void> FakeVehicleHardware::parseAndSetMinMaxValue(int32_t propId, int32_t areaId,
+                                                         const std::vector<std::string>& options,
+                                                         size_t index) {
+    auto valuesResult = parseOptionValues<T>(options, index, /*count= */ 2);
+    if (!valuesResult.ok()) {
+        return Error() << "Failed to set min/max supported value: "
+                       << valuesResult.error().message();
+    }
+    T minValue = (*valuesResult)[0];
+    T maxValue = (*valuesResult)[1];
     if (minValue > maxValue) {
-        return StringPrintf("Failed to set min/max supported value: MinValue: %" PRId32
-                            " must not > MaxValue: %" PRId32,
-                            minValue, maxValue);
+        return Error() << "Failed to set min/max supported value: MinValue: " << minValue
+                       << " must not > MaxValue: " << maxValue;
     }
     {
         std::scoped_lock<std::mutex> lockGuard(mLock);
-        mMinSupportedValueForTestIntProp = minValue;
-        mMaxSupportedValueForTestIntProp = maxValue;
+        setMinSupportedValueLocked(propId, areaId, minValue);
+        setMaxSupportedValueLocked(propId, areaId, maxValue);
     }
-    triggerSupportedValueChange(configResult.value());
-    return "Min/Max supported value for VENDOR_EXTENSION_INT_PROPERTY set";
+    return {};
+}
+
+template <class T>
+Result<std::vector<T>> FakeVehicleHardware::parseOptionValues(
+        const std::vector<std::string>& options, size_t index, size_t count) {
+    if (index + count > options.size()) {
+        return Error() << "Not enough arguments";
+    }
+    std::vector<T> values;
+    for (size_t i = index; i < index + count; i++) {
+        auto result = safelyParseInt<T>(i, options[i]);
+        if (!result.ok()) {
+            return Error() << StringPrintf("Value: \"%s\" is not a valid int: %s",
+                                           options[i].c_str(), getErrorMsg(result).c_str());
+        }
+        values.push_back(result.value());
+    }
+    return values;
+}
+
+// This is a special version of parseOptionValues for float type.
+template <>
+Result<std::vector<float>> FakeVehicleHardware::parseOptionValues(
+        const std::vector<std::string>& options, size_t index, size_t count) {
+    if (index + count > options.size()) {
+        return Error() << "Not enough arguments";
+    }
+    std::vector<float> values;
+    for (size_t i = index; i < index + count; i++) {
+        auto result = safelyParseFloat(i, options[i]);
+        if (!result.ok()) {
+            return Error() << StringPrintf("Value: \"%s\" is not a valid float: %s",
+                                           options[i].c_str(), getErrorMsg(result).c_str());
+        }
+        values.push_back(result.value());
+    }
+    return values;
+}
+
+template <class T>
+Result<std::vector<RawPropValues>> FakeVehicleHardware::parseOptionsToSupportedValuesList(
+        const std::vector<std::string>& options, size_t index) {
+    std::vector<RawPropValues> supportedValuesList;
+    auto valuesResult = parseOptionValues<T>(options, index, options.size() - index);
+    if (!valuesResult.ok()) {
+        return Error() << valuesResult.error().message();
+    }
+    std::vector<T> values = *valuesResult;
+    if (values.size() == 0) {
+        return Error() << "Not enough arguments";
+    }
+    for (T value : *valuesResult) {
+        supportedValuesList.push_back(createRawPropValues(value));
+    }
+    return supportedValuesList;
+}
+
+std::string FakeVehicleHardware::dumpSetMinMaxValue(const std::vector<std::string>& options) {
+    // Requires at least --set-minmaxvalue <PropId> <MinValue> <MaxValue>
+    if (auto result = checkArgumentsSize(options, /*minSize=*/4); !result.ok()) {
+        return "Failed to set min/max supported value: Not enough arguments\n";
+    }
+    size_t index = 1;
+    Result<DumpOptionPropIdAreaIdInfo> maybeInfo = parseDumpOptionPropIdAreaId(options, index);
+    if (!maybeInfo.ok()) {
+        return StringPrintf("Failed to set min/max supported value: %s\n",
+                            maybeInfo.error().message().c_str());
+    }
+    int32_t propId = maybeInfo->propId;
+    int32_t areaId = maybeInfo->areaId;
+
+    Result<void> parseAndSetValueResult = {};
+    switch (propId & toInt(VehiclePropertyType::MASK)) {
+        case toInt(VehiclePropertyType::INT32):
+            parseAndSetValueResult =
+                    parseAndSetMinMaxValue<int32_t>(propId, areaId, options, index);
+            break;
+        case toInt(VehiclePropertyType::INT64):
+            parseAndSetValueResult =
+                    parseAndSetMinMaxValue<int64_t>(propId, areaId, options, index);
+            break;
+        case toInt(VehiclePropertyType::FLOAT):
+            parseAndSetValueResult = parseAndSetMinMaxValue<float>(propId, areaId, options, index);
+            break;
+        default:
+            return StringPrintf(
+                    "Failed to set min/max supported value: only int32/int64/float type"
+                    " property is supported\n");
+    }
+    if (!parseAndSetValueResult.ok()) {
+        return parseAndSetValueResult.error().message();
+    }
+
+    triggerSupportedValueChange(propId, areaId);
+    return StringPrintf("Min/Max supported value for propId: %s, areaId: %s set",
+                        maybeInfo->propIdStr.c_str(), maybeInfo->propIdStr.c_str());
 }
 
 std::string FakeVehicleHardware::dumpSetSupportedValues(const std::vector<std::string>& options) {
-    if (auto result = checkArgumentsSize(options, /*minSize=*/2); !result.ok()) {
-        return getErrorMsg(result);
-    }
-    int testPropId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY);
-    auto configResult = mServerSidePropStore->getPropConfig(testPropId);
-    if (!configResult.ok()) {
-        return "Failed to set min/max supported value: VENDOR_EXTENSION_INT_PROPERTY not supported";
-    }
-    std::vector<int32_t> values;
-    for (size_t i = 1; i < options.size(); i++) {
-        auto int32Result = safelyParseInt<int32_t>(i, options[i]);
-        if (!int32Result.ok()) {
-            return StringPrintf(
-                    "Failed to set supported values: Value: \"%s\" is not a valid int: %s\n",
-                    options[i].c_str(), getErrorMsg(int32Result).c_str());
-        }
-        values.push_back(int32Result.value());
+    // We at least requires set-supportedvalues <PROP> <SUPPORTED_VALUE>
+    if (auto result = checkArgumentsSize(options, /*minSize=*/3); !result.ok()) {
+        return "Failed to set supported values list: Not enough arguments\n";
     }
 
-    {
-        std::scoped_lock<std::mutex> lockGuard(mLock);
-        mSupportedValuesListForTestIntProp = values;
+    size_t index = 1;
+    Result<DumpOptionPropIdAreaIdInfo> maybeInfo = parseDumpOptionPropIdAreaId(options, index);
+    if (!maybeInfo.ok()) {
+        return StringPrintf("Failed to set supported values list: %s\n",
+                            maybeInfo.error().message().c_str());
     }
-    triggerSupportedValueChange(configResult.value());
-    return "Supported values list for VENDOR_EXTENSION_INT_PROPERTY set";
+    int32_t propId = maybeInfo->propId;
+    int32_t areaId = maybeInfo->areaId;
+    Result<std::vector<RawPropValues>> maybeSupportedValues;
+    switch (propId & toInt(VehiclePropertyType::MASK)) {
+        case toInt(VehiclePropertyType::INT32):
+            maybeSupportedValues = parseOptionsToSupportedValuesList<int32_t>(options, index);
+            break;
+        case toInt(VehiclePropertyType::INT64):
+            maybeSupportedValues = parseOptionsToSupportedValuesList<int64_t>(options, index);
+            break;
+        case toInt(VehiclePropertyType::FLOAT):
+            maybeSupportedValues = parseOptionsToSupportedValuesList<float>(options, index);
+            break;
+        default:
+            return StringPrintf(
+                    "Failed to set supported values list: only int32/int64/float type"
+                    " property is supported\n");
+    }
+    if (!maybeSupportedValues.ok()) {
+        return StringPrintf("Failed to set supported values list: %s\n",
+                            maybeSupportedValues.error().message().c_str());
+    }
+    {
+        std::lock_guard<std::mutex> lock(mLock);
+        mSupportedValuesByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
+                *maybeSupportedValues;
+    }
+    triggerSupportedValueChange(maybeInfo->propId, maybeInfo->areaId);
+    return StringPrintf("Supported values list for propId: %s, areaId: %s set",
+                        maybeInfo->propIdStr.c_str(), maybeInfo->propIdStr.c_str());
 }
 
-// Triggers supported value change for all areaIds that specify hasSupportedValueInfo.
-void FakeVehicleHardware::triggerSupportedValueChange(const VehiclePropConfig& config) {
+void FakeVehicleHardware::triggerSupportedValueChange(int32_t propId, int32_t areaId) {
     if (mOnSupportedValueChangeCallback == nullptr) {
         ALOGE("onSupportedValueChangeCallback is not registered, ignore event");
         return;
     }
 
-    std::vector<PropIdAreaId> propIdAreaIds;
-    for (const VehicleAreaConfig& areaConfig : config.areaConfigs) {
-        if (areaConfig.hasSupportedValueInfo != std::nullopt) {
-            propIdAreaIds.push_back({
-                    .propId = config.prop,
-                    .areaId = areaConfig.areaId,
-            });
-        }
-    }
-    (*mOnSupportedValueChangeCallback)(std::move(propIdAreaIds));
+    (*mOnSupportedValueChangeCallback)({PropIdAreaId{
+            .propId = propId,
+            .areaId = areaId,
+    }});
 }
 
 std::string FakeVehicleHardware::dumpHelp() {
-    return "Usage: \n\n"
-           "[no args]: dumps (id and value) all supported properties \n"
-           "--help: shows this help\n"
-           "--list: lists the property IDs and their supported area IDs for all supported "
-           "properties\n"
-           "--get <PROP_ID_1> [PROP_ID_2] [PROP_ID_N]: dumps the value of specific properties. \n"
-           "--getWithArg <PROP_ID> [ValueArguments]: gets the value for a specific property. "
-           "The value arguments constructs a VehiclePropValue used in the getValue request. \n"
-           "--set <PROP_ID> [ValueArguments]: sets the value of property PROP_ID, the value "
-           "arguments constructs a VehiclePropValue used in the setValue request. \n"
-           "--set-minmaxvalue <MIN_VALUE(int)> <MAX_VALUE(int)>: sets the min max supported value "
-           "for VENDOR_EXTENSION_INT_PROPERTY\n"
-           "--set-supportedvalues <VALUE_1(int)> [VALUE_2(int) ...]: sets the supported values list"
-           "for VENDOR_EXTENSION_INT_PROPERTY\n"
-           "--save-prop <PROP_ID> [-a AREA_ID]: saves the current value for PROP_ID, integration "
-           "tests that modify prop value must call this before test and restore-prop after test. \n"
-           "--restore-prop <PROP_ID> [-a AREA_ID]: restores a previously saved property value. \n"
-           "--inject-event <PROP_ID> [ValueArguments]: inject a property update event from car\n\n"
-           "ValueArguments are in the format of [-a OPTIONAL_AREA_ID] "
-           "[-i INT_VALUE_1 [INT_VALUE_2 ...]] "
-           "[-i64 INT64_VALUE_1 [INT64_VALUE_2 ...]] "
-           "[-f FLOAT_VALUE_1 [FLOAT_VALUE_2 ...]] "
-           "[-s STR_VALUE] "
-           "[-b BYTES_VALUE].\n"
-           "For example: to set property ID 0x1234, areaId 0x1 to int32 values: [1, 2, 3], "
-           "use \"--set 0x1234 -a 0x1 -i 1 2 3\"\n"
-           "Note that the string, bytes and area value can be set just once, while the other can"
-           " have multiple values (so they're used in the respective array), "
-           "BYTES_VALUE is in the form of 0xXXXX, e.g. 0xdeadbeef.\n" +
-           genFakeDataHelp() + "Fake user HAL usage: \n" + mFakeUserHal->showDumpHelp();
+    return R"(Usage:
+[no args]: dumps (id and value) all supported properties
+
+--help: shows this help
+
+--list: lists the property IDs and their supported area IDs for all supported properties
+
+--get <PROP_ID_1> [PROP_ID_2] [PROP_ID_N]: dumps the value of specific properties.
+
+--getWithArg <PROP_ID> [ValueArguments]: gets the value for a specific property.
+The value arguments constructs a VehiclePropValue used in the getValue request.
+
+--set <PROP_ID> [ValueArguments]: sets the value of property PROP_ID
+The value arguments constructs a VehiclePropValue used in the setValue request.
+
+--set-minmaxvalue <PROP_ID> [-a AREA_ID] <MIN_VALUE> <MAX_VALUE>: sets the min max supported value
+e.g. --set-minmaxvalue HVAC_TEMPERATURE_SET -a ROW_1_LEFT 17 32
+
+--set-supportedvalues <PROP_ID> [-a AREA_ID] <VALUE_1> [VALUE_2 ...]: sets the supported values list
+e.g. --set-supportedvalues HVAC_TEMPERATURE_SET -a ROW_1_LEFT 17 17.5 18 18.5
+
+--save-prop <PROP_ID> [-a AREA_ID]: saves the current value for PROP_ID, integration tests that
+modify prop value must call this before test and restore-prop after test.
+
+--restore-prop <PROP_ID> [-a AREA_ID]: restores a previously saved property value.
+
+--inject-event <PROP_ID> [ValueArguments]: inject a property update event from car
+ValueArguments are in the format of
+[-a OPTIONAL_AREA_ID] [-i INT_VALUE_1 [INT_VALUE_2 ...]] [-i64 INT64_VALUE_1 [INT64_VALUE_2 ...]]
+[-f FLOAT_VALUE_1 [FLOAT_VALUE_2 ...]] [-s STR_VALUE] [-b BYTES_VALUE].
+For example: to set property ID 0x1234, areaId 0x1 to int32 values: [1, 2, 3]
+use "--set 0x1234 -a 0x1 -i 1 2 3"
+Note that the string, bytes and area value can be set just once, while the other can have multiple
+values (so they're used in the respective array), BYTES_VALUE is in the form of 0xXXXX,
+e.g. 0xdeadbeef.
+)" + genFakeDataHelp() +
+           "Fake user HAL usage: \n" + mFakeUserHal->showDumpHelp();
 }
 
 std::string FakeVehicleHardware::dumpAllProperties() {
@@ -2405,27 +2682,24 @@
         const std::vector<PropIdAreaId>& propIdAreaIds) {
     std::scoped_lock<std::mutex> lockGuard(mLock);
     std::vector<MinMaxSupportedValueResult> results;
-    // We only support VENDOR_EXTENSION_INT_PROPERTY
     for (const auto& propIdAreaId : propIdAreaIds) {
-        int propId = propIdAreaId.propId;
-        int areaId = propIdAreaId.areaId;
-        if (propId != toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY)) {
+        const auto minIt = mMinSupportedValueByPropIdAreaId.find(propIdAreaId);
+        const auto maxIt = mMaxSupportedValueByPropIdAreaId.find(propIdAreaId);
+        if (minIt == mMinSupportedValueByPropIdAreaId.end() &&
+            maxIt == mMaxSupportedValueByPropIdAreaId.end()) {
             results.push_back(MinMaxSupportedValueResult{
                     .status = StatusCode::INVALID_ARG,
             });
             continue;
         }
-        results.push_back(MinMaxSupportedValueResult{
-                .status = StatusCode::OK,
-                .minSupportedValue =
-                        RawPropValues{
-                                .int32Values = {mMinSupportedValueForTestIntProp},
-                        },
-                .maxSupportedValue =
-                        RawPropValues{
-                                .int32Values = {mMaxSupportedValueForTestIntProp},
-                        },
-        });
+        auto result = MinMaxSupportedValueResult{.status = StatusCode::OK};
+        if (minIt != mMinSupportedValueByPropIdAreaId.end()) {
+            result.minSupportedValue = minIt->second;
+        }
+        if (maxIt != mMaxSupportedValueByPropIdAreaId.end()) {
+            result.maxSupportedValue = maxIt->second;
+        }
+        results.push_back(std::move(result));
     }
     return results;
 }
@@ -2434,19 +2708,17 @@
         const std::vector<PropIdAreaId>& propIdAreaIds) {
     std::scoped_lock<std::mutex> lockGuard(mLock);
     std::vector<SupportedValuesListResult> results;
-    // We only support VENDOR_EXTENSION_INT_PROPERTY
     for (const auto& propIdAreaId : propIdAreaIds) {
-        int propId = propIdAreaId.propId;
-        int areaId = propIdAreaId.areaId;
-        if (propId != toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY)) {
+        const auto it = mSupportedValuesByPropIdAreaId.find(propIdAreaId);
+        if (it == mSupportedValuesByPropIdAreaId.end()) {
             results.push_back(SupportedValuesListResult{
                     .status = StatusCode::INVALID_ARG,
             });
             continue;
         }
         std::vector<std::optional<RawPropValues>> supportedValuesList;
-        for (int32_t value : mSupportedValuesListForTestIntProp) {
-            supportedValuesList.push_back(RawPropValues{.int32Values = {value}});
+        for (const RawPropValues& supportedValue : it->second) {
+            supportedValuesList.push_back(supportedValue);
         }
         results.push_back(SupportedValuesListResult{
                 .status = StatusCode::OK,
diff --git a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index df5c2a3..8262098 100644
--- a/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -80,6 +80,7 @@
 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateShutdownParam;
 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaSeat;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
 using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
@@ -399,15 +400,15 @@
         };
 
         VehiclePropValue leftHvacTemp = {
+                .areaId = SEAT_1_LEFT,
                 .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_CURRENT),
                 .value = {.floatValues = {170.0}},
-                .areaId = SEAT_1_LEFT,
         };
 
         VehiclePropValue rightHvacTemp = {
+                .areaId = SEAT_1_RIGHT,
                 .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_CURRENT),
                 .value = {.floatValues = {180.0}},
-                .areaId = SEAT_1_RIGHT,
         };
 
         return {oilLevel, leftHvacTemp, rightHvacTemp};
@@ -534,8 +535,8 @@
         for (auto areaConfig : config.config.areaConfigs) {
             StatusCode status = StatusCode::OK;
             VehiclePropValue propValue{
-                    .prop = propId,
                     .areaId = areaConfig.areaId,
+                    .prop = propId,
             };
             if (config.initialAreaValues.empty()) {
                 if (config.initialValue == RawPropValues{}) {
@@ -790,12 +791,12 @@
 
     // If we set the value, it should update despite the override.
     ASSERT_EQ(setValue(VehiclePropValue{
+                      .timestamp = elapsedRealtimeNano(),
                       .prop = gearProp,
                       .value =
                               {
                                       .int32Values = {5},
                               },
-                      .timestamp = elapsedRealtimeNano(),
               }),
               StatusCode::OK)
             << "expect to set the overridden property ok";
@@ -821,8 +822,8 @@
     int hvacProp = toInt(VehicleProperty::HVAC_TEMPERATURE_SET);
 
     auto result = getValue(VehiclePropValue{
-            .prop = hvacProp,
             .areaId = HVAC_LEFT,
+            .prop = hvacProp,
     });
 
     ASSERT_TRUE(result.ok()) << "expect to get the overridden property ok: " << getStatus(result);
@@ -1247,16 +1248,16 @@
                                             .value.int32Values = {0},
                                     },
                                     VehiclePropValue{
+                                            .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
                                             .prop = toInt(
                                                     VehicleProperty::BLIND_SPOT_WARNING_STATE),
-                                            .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
                                             .value.int32Values = {toInt(
                                                     ErrorState::NOT_AVAILABLE_DISABLED)},
                                     },
                                     VehiclePropValue{
+                                            .areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
                                             .prop = toInt(
                                                     VehicleProperty::BLIND_SPOT_WARNING_STATE),
-                                            .areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
                                             .value.int32Values = {toInt(
                                                     ErrorState::NOT_AVAILABLE_DISABLED)},
                                     },
@@ -1280,15 +1281,15 @@
                                             .value.int32Values = {1},
                                     },
                                     VehiclePropValue{
+                                            .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
                                             .prop = toInt(
                                                     VehicleProperty::BLIND_SPOT_WARNING_STATE),
-                                            .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
                                             .value.int32Values = {1},
                                     },
                                     VehiclePropValue{
+                                            .areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
                                             .prop = toInt(
                                                     VehicleProperty::BLIND_SPOT_WARNING_STATE),
-                                            .areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
                                             .value.int32Values = {1},
                                     },
                             },
@@ -1757,7 +1758,7 @@
     std::vector<VehiclePropValue> gotValues;
 
     for (const auto& value : tc.expectedValuesToGet) {
-        auto result = getValue(VehiclePropValue{.prop = value.prop, .areaId = value.areaId});
+        auto result = getValue(VehiclePropValue{.areaId = value.areaId, .prop = value.prop});
 
         ASSERT_TRUE(result.ok()) << "failed to get property " << value.prop
                                  << " status:" << getStatus(result);
@@ -1880,8 +1881,8 @@
     for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
         int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
         // Turn off HVAC_POWER_ON for only 1 area ID
-        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
-                                                      .areaId = hvacPowerAreaId,
+        StatusCode status = setValue(VehiclePropValue{.areaId = hvacPowerAreaId,
+                                                      .prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                                       .value.int32Values = {0}});
         EXPECT_EQ(status, StatusCode::OK);
 
@@ -1895,8 +1896,8 @@
             for (auto& powerPropAreaConfig : powerPropConfig->areaConfigs) {
                 int powerDependentAreaId = powerPropAreaConfig.areaId;
                 auto getValueResult = getValue(VehiclePropValue{
-                        .prop = powerPropId,
                         .areaId = powerDependentAreaId,
+                        .prop = powerPropId,
                 });
 
                 // If the current area ID is contained within the HVAC_POWER_ON area ID
@@ -1914,8 +1915,8 @@
         // Resetting HVAC_POWER_ON at areaId back to ON state to ensure that there's no dependence
         // on this value from any power dependent property values other than those with the same
         // areaId.
-        setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
-                                  .areaId = hvacPowerAreaId,
+        setValue(VehiclePropValue{.areaId = hvacPowerAreaId,
+                                  .prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                   .value.int32Values = {1}});
     }
 }
@@ -1927,8 +1928,8 @@
     for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
         int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
         // Turn off HVAC_POWER_ON for only 1 area ID
-        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
-                                                      .areaId = hvacPowerAreaId,
+        StatusCode status = setValue(VehiclePropValue{.areaId = hvacPowerAreaId,
+                                                      .prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                                       .value.int32Values = {0}});
         EXPECT_EQ(status, StatusCode::OK);
 
@@ -1942,7 +1943,7 @@
             // Try setting a value at each area ID supported by the power dependent property
             for (auto& powerPropAreaConfig : powerPropConfig->areaConfigs) {
                 int powerDependentAreaId = powerPropAreaConfig.areaId;
-                auto val = VehiclePropValue{.prop = powerPropId, .areaId = powerDependentAreaId};
+                auto val = VehiclePropValue{.areaId = powerDependentAreaId, .prop = powerPropId};
                 if (propType == VehiclePropertyType::FLOAT) {
                     val.value.floatValues.emplace_back(20);
                 } else {
@@ -1964,8 +1965,8 @@
         // Resetting HVAC_POWER_ON at areaId back to ON state to ensure that there's no dependence
         // on this value from any power dependent property values other than those with the same
         // areaId.
-        setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
-                                  .areaId = hvacPowerAreaId,
+        setValue(VehiclePropValue{.areaId = hvacPowerAreaId,
+                                  .prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                   .value.int32Values = {1}});
     }
 }
@@ -1976,8 +1977,8 @@
     EXPECT_NE(hvacPowerOnConfig, nullptr);
     for (auto& hvacPowerOnAreaConfig : hvacPowerOnConfig->areaConfigs) {
         int hvacPowerAreaId = hvacPowerOnAreaConfig.areaId;
-        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
-                                                      .areaId = hvacPowerAreaId,
+        StatusCode status = setValue(VehiclePropValue{.areaId = hvacPowerAreaId,
+                                                      .prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                                       .value.int32Values = {0}});
         EXPECT_EQ(status, StatusCode::OK);
         auto events = getChangedProperties();
@@ -1992,8 +1993,8 @@
         }
         clearChangedProperties();
 
-        status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_POWER_ON),
-                                           .areaId = hvacPowerAreaId,
+        status = setValue(VehiclePropValue{.areaId = hvacPowerAreaId,
+                                           .prop = toInt(VehicleProperty::HVAC_POWER_ON),
                                            .value.int32Values = {1}});
         EXPECT_EQ(status, StatusCode::OK);
         events = getChangedProperties();
@@ -2024,8 +2025,8 @@
     for (auto& hvacDualOnConfig : hvacDualOnConfig->areaConfigs) {
         int32_t hvacDualOnAreaId = hvacDualOnConfig.areaId;
         subscribe(toInt(VehicleProperty::HVAC_DUAL_ON), hvacDualOnAreaId, /*sampleRateHz*/ 0);
-        StatusCode status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_DUAL_ON),
-                                                      .areaId = hvacDualOnAreaId,
+        StatusCode status = setValue(VehiclePropValue{.areaId = hvacDualOnAreaId,
+                                                      .prop = toInt(VehicleProperty::HVAC_DUAL_ON),
                                                       .value.int32Values = {1}});
         EXPECT_EQ(status, StatusCode::OK);
 
@@ -2056,8 +2057,8 @@
                 continue;
             }
             float expectedValue = 25;
-            status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
-                                               .areaId = hvacTemperatureSetAreaId,
+            status = setValue(VehiclePropValue{.areaId = hvacTemperatureSetAreaId,
+                                               .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
                                                .value.floatValues = {expectedValue}});
             EXPECT_EQ(status, StatusCode::OK);
             events = getChangedProperties();
@@ -2069,8 +2070,8 @@
             clearChangedProperties();
         }
 
-        status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_DUAL_ON),
-                                           .areaId = hvacDualOnAreaId,
+        status = setValue(VehiclePropValue{.areaId = hvacDualOnAreaId,
+                                           .prop = toInt(VehicleProperty::HVAC_DUAL_ON),
                                            .value.int32Values = {0}});
         EXPECT_EQ(status, StatusCode::OK);
 
@@ -2090,8 +2091,8 @@
                 continue;
             }
             float expectedValue = 24;
-            status = setValue(VehiclePropValue{.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
-                                               .areaId = hvacTemperatureSetAreaId,
+            status = setValue(VehiclePropValue{.areaId = hvacTemperatureSetAreaId,
+                                               .prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
                                                .value.floatValues = {expectedValue}});
             EXPECT_EQ(status, StatusCode::OK);
             events = getChangedProperties();
@@ -2354,8 +2355,8 @@
 
     // This is the same example as used in User HAL Emulation doc.
     VehiclePropValue valueToSet = {
-            .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION),
             .areaId = 1,
+            .prop = toInt(VehicleProperty::USER_IDENTIFICATION_ASSOCIATION),
             .value.int32Values = {666, 1, 1, 2},
     };
 
@@ -2390,8 +2391,8 @@
 
     // This is the same example as used in User HAL Emulation doc.
     VehiclePropValue valueToSet = {
-            .prop = propSwitchUser,
             .areaId = 1,
+            .prop = propSwitchUser,
             .value.int32Values = {666, 3, 2},
     };
 
@@ -2401,8 +2402,8 @@
 
     // Simulate a request from Android side.
     VehiclePropValue switchUserRequest = {
-            .prop = propSwitchUser,
             .areaId = 0,
+            .prop = propSwitchUser,
             .value.int32Values = {666, 3},
     };
     // Clear existing events.
@@ -2455,8 +2456,8 @@
 
     // This is the same example as used in User HAL Emulation doc.
     VehiclePropValue valueToSet = {
-            .prop = toInt(VehicleProperty::CREATE_USER),
             .areaId = 1,
+            .prop = toInt(VehicleProperty::CREATE_USER),
             .value.int32Values = {666, 2},
     };
 
@@ -2466,8 +2467,8 @@
 
     // Simulate a request from Android side.
     VehiclePropValue createUserRequest = {
-            .prop = propCreateUser,
             .areaId = 0,
+            .prop = propCreateUser,
             .value.int32Values = {666},
     };
     // Clear existing events.
@@ -2517,8 +2518,8 @@
 
     // This is the same example as used in User HAL Emulation doc.
     VehiclePropValue valueToSet = {
-            .prop = propInitialUserInfo,
             .areaId = 1,
+            .prop = propInitialUserInfo,
             .value.int32Values = {666, 1, 11},
     };
 
@@ -2528,8 +2529,8 @@
 
     // Simulate a request from Android side.
     VehiclePropValue initialUserInfoRequest = {
-            .prop = propInitialUserInfo,
             .areaId = 0,
+            .prop = propInitialUserInfo,
             .value.int32Values = {3},
     };
     // Clear existing events.
@@ -2591,7 +2592,7 @@
     DumpResult result = getHardware()->dump(options);
     ASSERT_FALSE(result.callerShouldDumpState);
     ASSERT_NE(result.buffer, "");
-    ASSERT_THAT(result.buffer, ContainsRegex("Usage: "));
+    ASSERT_THAT(result.buffer, ContainsRegex("Usage:"));
 }
 
 TEST_F(FakeVehicleHardwareTest, testDumpListProperties) {
@@ -2697,8 +2698,8 @@
     ASSERT_THAT(result.buffer, ContainsRegex("saved"));
 
     ASSERT_EQ(setValue(VehiclePropValue{
-                      .prop = prop,
                       .areaId = WHEEL_FRONT_LEFT,
+                      .prop = prop,
                       .value =
                               {
                                       .floatValues = {210.0},
@@ -2711,7 +2712,7 @@
     ASSERT_FALSE(result.callerShouldDumpState);
     ASSERT_THAT(result.buffer, ContainsRegex("restored"));
 
-    auto getResult = getValue(VehiclePropValue{.prop = prop, .areaId = WHEEL_FRONT_LEFT});
+    auto getResult = getValue(VehiclePropValue{.areaId = WHEEL_FRONT_LEFT, .prop = prop});
 
     ASSERT_TRUE(getResult.ok());
     // The default value is 200.0.
@@ -2761,8 +2762,9 @@
                               "response\nNo SetUserIdentificationAssociation response\n"));
 }
 
-TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue) {
-    std::vector<std::string> options = {"--set-minmaxvalue", "1", "100"};
+TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_Int) {
+    std::vector<std::string> options = {
+            "--set-minmaxvalue", "SEAT_MEMORY_SELECT", "-a", "ROW_1_LEFT", "1", "4"};
     std::vector<PropIdAreaId> changedPropIdAreaIds;
 
     getHardware()->registerSupportedValueChangeCallback(
@@ -2776,37 +2778,124 @@
     ASSERT_THAT(result.buffer, ContainsRegex("Min/Max supported value .* set"));
 
     ASSERT_EQ(changedPropIdAreaIds.size(), 1u);
+    EXPECT_EQ(changedPropIdAreaIds[0], (PropIdAreaId{
+                                               .propId = toInt(VehicleProperty::SEAT_MEMORY_SELECT),
+                                               .areaId = toInt(VehicleAreaSeat::ROW_1_LEFT),
+                                       }));
 
-    auto results = getHardware()->getMinMaxSupportedValues({PropIdAreaId{
-            .propId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY), .areaId = 0}});
+    auto results = getHardware()->getMinMaxSupportedValues({changedPropIdAreaIds[0]});
 
     ASSERT_EQ(results.size(), 1u);
     EXPECT_EQ(results[0].status, StatusCode::OK);
     EXPECT_EQ(results[0].minSupportedValue.value(), RawPropValues{.int32Values = {1}});
-    EXPECT_EQ(results[0].maxSupportedValue.value(), RawPropValues{.int32Values = {100}});
+    EXPECT_EQ(results[0].maxSupportedValue.value(), RawPropValues{.int32Values = {4}});
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_forGlobalProperty) {
+    // -a can be emitted for global property
+    std::vector<std::string> options = {"--set-minmaxvalue", "EV_BRAKE_REGENERATION_LEVEL", "1",
+                                        "4"};
+    std::vector<PropIdAreaId> changedPropIdAreaIds;
+
+    getHardware()->registerSupportedValueChangeCallback(
+            std::make_unique<IVehicleHardware::SupportedValueChangeCallback>(
+                    [&changedPropIdAreaIds](std::vector<PropIdAreaId> propIdAreaIds) {
+                        changedPropIdAreaIds = propIdAreaIds;
+                    }));
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, ContainsRegex("Min/Max supported value .* set"));
+
+    ASSERT_EQ(changedPropIdAreaIds.size(), 1u);
+    EXPECT_EQ(changedPropIdAreaIds[0],
+              (PropIdAreaId{
+                      .propId = toInt(VehicleProperty::EV_BRAKE_REGENERATION_LEVEL),
+                      .areaId = 0,
+              }));
+
+    auto results = getHardware()->getMinMaxSupportedValues({changedPropIdAreaIds[0]});
+
+    ASSERT_EQ(results.size(), 1u);
+    EXPECT_EQ(results[0].status, StatusCode::OK);
+    EXPECT_EQ(results[0].minSupportedValue.value(), RawPropValues{.int32Values = {1}});
+    EXPECT_EQ(results[0].maxSupportedValue.value(), RawPropValues{.int32Values = {4}});
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_Float) {
+    std::vector<std::string> options = {
+            "--set-minmaxvalue", "HVAC_TEMPERATURE_SET", "-a", "ROW_1_LEFT", "-5.1", "5.1"};
+    std::vector<PropIdAreaId> changedPropIdAreaIds;
+
+    getHardware()->registerSupportedValueChangeCallback(
+            std::make_unique<IVehicleHardware::SupportedValueChangeCallback>(
+                    [&changedPropIdAreaIds](std::vector<PropIdAreaId> propIdAreaIds) {
+                        changedPropIdAreaIds = propIdAreaIds;
+                    }));
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, ContainsRegex("Min/Max supported value .* set"));
+
+    ASSERT_EQ(changedPropIdAreaIds.size(), 1u);
+    EXPECT_EQ(changedPropIdAreaIds[0],
+              (PropIdAreaId{
+                      .propId = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
+                      .areaId = toInt(VehicleAreaSeat::ROW_1_LEFT),
+              }));
+
+    auto results = getHardware()->getMinMaxSupportedValues({changedPropIdAreaIds[0]});
+
+    ASSERT_EQ(results.size(), 1u);
+    EXPECT_EQ(results[0].status, StatusCode::OK);
+    EXPECT_EQ(results[0].minSupportedValue.value(), RawPropValues{.floatValues = {-5.1}});
+    EXPECT_EQ(results[0].maxSupportedValue.value(), RawPropValues{.floatValues = {5.1}});
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_notEnoughArguments) {
+    std::vector<std::string> options = {"--set-minmaxvalue", "SEAT_MEMORY_SELECT"};
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_THAT(result.buffer, ContainsRegex("Not enough arguments"));
+
+    options = {"--set-minmaxvalue", "SEAT_MEMORY_SELECT", "2"};
+
+    result = getHardware()->dump(options);
+    ASSERT_THAT(result.buffer, ContainsRegex("Not enough arguments"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_notEnoughArguments_missingMax) {
+    std::vector<std::string> options = {"--set-minmaxvalue", "SEAT_MEMORY_SELECT", "-a",
+                                        "ROW_1_LEFT", "2"};
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_THAT(result.buffer, ContainsRegex("Not enough arguments"));
 }
 
 TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_invalidInt) {
-    std::vector<std::string> options = {"--set-minmaxvalue", "abc", "100"};
+    std::vector<std::string> options = {
+            "--set-minmaxvalue", "HVAC_TEMPERATURE_SET", "-a", "ROW_1_LEFT", "abc", "100"};
 
     DumpResult result = getHardware()->dump(options);
     ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
 
-    options = {"--set-minmaxvalue", "1", "abc"};
+    options = {"--set-minmaxvalue", "HVAC_TEMPERATURE_SET", "-a", "ROW_1_LEFT", "100", "abc"};
 
     result = getHardware()->dump(options);
     ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
 }
 
 TEST_F(FakeVehicleHardwareTest, testDumpSetMinMaxValue_minLargerThanMax) {
-    std::vector<std::string> options = {"--set-minmaxvalue", "2", "1"};
+    std::vector<std::string> options = {
+            "--set-minmaxvalue", "SEAT_MEMORY_SELECT", "-a", "ROW_1_LEFT", "2", "1"};
 
     DumpResult result = getHardware()->dump(options);
     ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
 }
 
-TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues) {
-    std::vector<std::string> options = {"--set-supportedvalues", "1", "2", "3"};
+TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_Int) {
+    std::vector<std::string> options = {
+            "--set-supportedvalues", "EV_STOPPING_MODE", "-a", "0", "1", "2", "3"};
     std::vector<PropIdAreaId> changedPropIdAreaIds;
 
     getHardware()->registerSupportedValueChangeCallback(
@@ -2820,11 +2909,13 @@
     ASSERT_THAT(result.buffer, ContainsRegex("Supported values list .* set"));
 
     ASSERT_EQ(changedPropIdAreaIds.size(), 1u);
+    EXPECT_EQ(changedPropIdAreaIds[0], (PropIdAreaId{
+                                               .propId = toInt(VehicleProperty::EV_STOPPING_MODE),
+                                               .areaId = 0,
+                                       }));
 
-    auto results = getHardware()->getSupportedValuesLists({PropIdAreaId{
-            .propId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY), .areaId = 0}});
+    auto results = getHardware()->getSupportedValuesLists({changedPropIdAreaIds[0]});
 
-    ASSERT_EQ(results.size(), 1u);
     EXPECT_EQ(results[0].status, StatusCode::OK);
     EXPECT_NE(results[0].supportedValuesList, std::nullopt);
     EXPECT_EQ(results[0].supportedValuesList.value(), std::vector<std::optional<RawPropValues>>({
@@ -2834,13 +2925,108 @@
                                                       }));
 }
 
+TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_forGlobalPropertySkipArea) {
+    std::vector<std::string> options = {"--set-supportedvalues", "EV_STOPPING_MODE", "1", "2", "3"};
+    std::vector<PropIdAreaId> changedPropIdAreaIds;
+
+    getHardware()->registerSupportedValueChangeCallback(
+            std::make_unique<IVehicleHardware::SupportedValueChangeCallback>(
+                    [&changedPropIdAreaIds](std::vector<PropIdAreaId> propIdAreaIds) {
+                        changedPropIdAreaIds = propIdAreaIds;
+                    }));
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, ContainsRegex("Supported values list .* set"));
+
+    ASSERT_EQ(changedPropIdAreaIds.size(), 1u);
+    EXPECT_EQ(changedPropIdAreaIds[0], (PropIdAreaId{
+                                               .propId = toInt(VehicleProperty::EV_STOPPING_MODE),
+                                               .areaId = 0,
+                                       }));
+
+    auto results = getHardware()->getSupportedValuesLists({changedPropIdAreaIds[0]});
+
+    EXPECT_EQ(results[0].status, StatusCode::OK);
+    EXPECT_NE(results[0].supportedValuesList, std::nullopt);
+    EXPECT_EQ(results[0].supportedValuesList.value(), std::vector<std::optional<RawPropValues>>({
+                                                              RawPropValues{.int32Values = {1}},
+                                                              RawPropValues{.int32Values = {2}},
+                                                              RawPropValues{.int32Values = {3}},
+                                                      }));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_Float) {
+    std::vector<std::string> options = {"--set-supportedvalues",
+                                        "HVAC_TEMPERATURE_SET",
+                                        "-a",
+                                        "ROW_1_LEFT",
+                                        "1.1",
+                                        "2.2",
+                                        "3.3"};
+    std::vector<PropIdAreaId> changedPropIdAreaIds;
+
+    getHardware()->registerSupportedValueChangeCallback(
+            std::make_unique<IVehicleHardware::SupportedValueChangeCallback>(
+                    [&changedPropIdAreaIds](std::vector<PropIdAreaId> propIdAreaIds) {
+                        changedPropIdAreaIds = propIdAreaIds;
+                    }));
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_FALSE(result.callerShouldDumpState);
+    ASSERT_THAT(result.buffer, ContainsRegex("Supported values list .* set"));
+
+    ASSERT_EQ(changedPropIdAreaIds.size(), 1u);
+    EXPECT_EQ(changedPropIdAreaIds[0],
+              (PropIdAreaId{
+                      .propId = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
+                      .areaId = toInt(VehicleAreaSeat::ROW_1_LEFT),
+              }));
+
+    auto results = getHardware()->getSupportedValuesLists({changedPropIdAreaIds[0]});
+
+    EXPECT_EQ(results[0].status, StatusCode::OK);
+    EXPECT_NE(results[0].supportedValuesList, std::nullopt);
+    EXPECT_EQ(results[0].supportedValuesList.value(), std::vector<std::optional<RawPropValues>>({
+                                                              RawPropValues{.floatValues = {1.1}},
+                                                              RawPropValues{.floatValues = {2.2}},
+                                                              RawPropValues{.floatValues = {3.3}},
+                                                      }));
+}
+
 TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_invalidInt) {
-    std::vector<std::string> options = {"--set-supportedvalues", "1", "2", "ab", "3"};
+    std::vector<std::string> options = {
+            "--set-supportedvalues", "EV_STOPPING_MODE", "1", "2", "ab", "3"};
 
     DumpResult result = getHardware()->dump(options);
     ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
 }
 
+TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_notEnoughArguments) {
+    std::vector<std::string> options = {"--set-supportedvalues", "EV_STOPPING_MODE"};
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
+    ASSERT_THAT(result.buffer, ContainsRegex("Not enough arguments"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_withAreaId_notEnoughArguments) {
+    std::vector<std::string> options = {"--set-supportedvalues", "EV_STOPPING_MODE", "-a", "0"};
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
+    ASSERT_THAT(result.buffer, ContainsRegex("Not enough arguments"));
+}
+
+TEST_F(FakeVehicleHardwareTest, testDumpSetSupportedValues_invalidAreaId) {
+    std::vector<std::string> options = {"--set-supportedvalues", "EV_STOPPING_MODE", "-a", "blah",
+                                        "1"};
+
+    DumpResult result = getHardware()->dump(options);
+    ASSERT_THAT(result.buffer, ContainsRegex("Failed"));
+    ASSERT_THAT(result.buffer, ContainsRegex("areaId not valid"));
+}
+
 struct SetPropTestCase {
     std::string test_name;
     std::vector<std::string> options;
@@ -3569,15 +3755,15 @@
     ASSERT_EQ(status, StatusCode::OK) << "failed to subscribe";
 
     status = setValue({
-            .prop = propSpeed,
             .areaId = 0,
+            .prop = propSpeed,
             .value.floatValues = {1.1f},
     });
     ASSERT_EQ(status, StatusCode::OK) << "failed to set speed";
 
     status = setValue({
-            .prop = propSpeed,
             .areaId = 0,
+            .prop = propSpeed,
             .value.floatValues = {1.2f},
     });
     ASSERT_EQ(status, StatusCode::OK) << "failed to set speed";
@@ -3604,8 +3790,8 @@
     ASSERT_EQ(status, StatusCode::OK) << "failed to subscribe";
 
     status = setValue({
-            .prop = propHvac,
             .areaId = areaId,
+            .prop = propHvac,
             .value.floatValues = {20.0f},
     });
     ASSERT_EQ(status, StatusCode::OK) << "failed to set hvac value";
@@ -3615,8 +3801,8 @@
     clearChangedProperties();
 
     status = setValue({
-            .prop = propHvac,
             .areaId = areaId,
+            .prop = propHvac,
             .value.floatValues = {21.0f},
     });
     ASSERT_EQ(status, StatusCode::OK) << "failed to set hvac value";
@@ -3629,8 +3815,8 @@
     ASSERT_EQ(status, StatusCode::OK);
 
     status = setValue({
-            .prop = propHvac,
             .areaId = areaId,
+            .prop = propHvac,
             .value.floatValues = {22.0f},
     });
     ASSERT_EQ(status, StatusCode::OK) << "failed to set hvac value";
@@ -3655,31 +3841,31 @@
     subscribe(propHvacTempValueSuggest, HVAC_ALL, /*sampleRateHz*/ 0);
 
     VehiclePropValue floatArraySizeFour = {
-            .prop = propHvacTempValueSuggest,
             .areaId = HVAC_ALL,
+            .prop = propHvacTempValueSuggest,
             .value.floatValues = {0, CELSIUS, 0, 0},
     };
     StatusCode status = setValue(floatArraySizeFour);
     EXPECT_EQ(status, StatusCode::OK);
 
     VehiclePropValue floatArraySizeZero = {
-            .prop = propHvacTempValueSuggest,
             .areaId = HVAC_ALL,
+            .prop = propHvacTempValueSuggest,
     };
     status = setValue(floatArraySizeZero);
     EXPECT_EQ(status, StatusCode::INVALID_ARG);
 
     VehiclePropValue floatArraySizeFive = {
-            .prop = propHvacTempValueSuggest,
             .areaId = HVAC_ALL,
+            .prop = propHvacTempValueSuggest,
             .value.floatValues = {0, CELSIUS, 0, 0, 0},
     };
     status = setValue(floatArraySizeFive);
     EXPECT_EQ(status, StatusCode::INVALID_ARG);
 
     VehiclePropValue invalidUnit = {
-            .prop = propHvacTempValueSuggest,
             .areaId = HVAC_ALL,
+            .prop = propHvacTempValueSuggest,
             .value.floatValues = {0, 0, 0, 0},
     };
     status = setValue(invalidUnit);
@@ -3709,16 +3895,16 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInCelsius, CELSIUS, 0, 0},
                                     },
                             },
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInCelsius, CELSIUS,
                                                                   minTempInCelsius,
                                                                   minTempInFahrenheit},
@@ -3730,8 +3916,8 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInFahrenheit, FAHRENHEIT,
                                                                   0, 0},
                                     },
@@ -3739,8 +3925,8 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInFahrenheit, FAHRENHEIT,
                                                                   minTempInCelsius,
                                                                   minTempInFahrenheit},
@@ -3752,16 +3938,16 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {maxTempInCelsius, CELSIUS, 0, 0},
                                     },
                             },
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {maxTempInCelsius, CELSIUS,
                                                                   maxTempInCelsius,
                                                                   maxTempInFahrenheit},
@@ -3773,8 +3959,8 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {maxTempInFahrenheit, FAHRENHEIT,
                                                                   0, 0},
                                     },
@@ -3782,8 +3968,8 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {maxTempInFahrenheit, FAHRENHEIT,
                                                                   maxTempInCelsius,
                                                                   maxTempInFahrenheit},
@@ -3795,8 +3981,8 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInCelsius - 1, CELSIUS, 0,
                                                                   0},
                                     },
@@ -3804,8 +3990,8 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInCelsius - 1, CELSIUS,
                                                                   minTempInCelsius,
                                                                   minTempInFahrenheit},
@@ -3817,8 +4003,8 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInFahrenheit - 1,
                                                                   FAHRENHEIT, 0, 0},
                                     },
@@ -3826,8 +4012,8 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInFahrenheit - 1,
                                                                   FAHRENHEIT, minTempInCelsius,
                                                                   minTempInFahrenheit},
@@ -3839,8 +4025,8 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {maxTempInCelsius + 1, CELSIUS, 0,
                                                                   0},
                                     },
@@ -3848,8 +4034,8 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {maxTempInCelsius + 1, CELSIUS,
                                                                   maxTempInCelsius,
                                                                   maxTempInFahrenheit},
@@ -3861,8 +4047,8 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {maxTempInFahrenheit + 1,
                                                                   FAHRENHEIT, 0, 0},
                                     },
@@ -3870,8 +4056,8 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {maxTempInFahrenheit + 1,
                                                                   FAHRENHEIT, maxTempInCelsius,
                                                                   maxTempInFahrenheit},
@@ -3883,8 +4069,8 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInCelsius +
                                                                           incrementInCelsius * 2.5f,
                                                                   CELSIUS, 0, 0},
@@ -3893,8 +4079,8 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues =
                                                     {minTempInCelsius + incrementInCelsius * 2.5f,
                                                      CELSIUS,
@@ -3909,8 +4095,8 @@
                     .valuesToSet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues = {minTempInFahrenheit +
                                                                           incrementInFahrenheit *
                                                                                   2.5f,
@@ -3920,8 +4106,8 @@
                     .expectedValuesToGet =
                             {
                                     VehiclePropValue{
-                                            .prop = propHvacTempValueSuggest,
                                             .areaId = HVAC_ALL,
+                                            .prop = propHvacTempValueSuggest,
                                             .value.floatValues =
                                                     {minTempInFahrenheit +
                                                              incrementInFahrenheit * 2.5f,
@@ -3968,9 +4154,10 @@
 
 TEST_F(FakeVehicleHardwareTest, testGetMinMaxSupportedValues) {
     auto results = getHardware()->getMinMaxSupportedValues({
-            PropIdAreaId{.propId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY),
-                         .areaId = 0},
-            PropIdAreaId{.propId = toInt(VehicleProperty::HVAC_TEMPERATURE_SET), .areaId = 0},
+            PropIdAreaId{.propId = toInt(VehicleProperty::SEAT_MEMORY_SELECT),
+                         .areaId = toInt(VehicleAreaSeat::ROW_1_LEFT)},
+            // This property does not specify min/max value
+            PropIdAreaId{.propId = toInt(VehicleProperty::EV_BATTERY_DISPLAY_UNITS), .areaId = 0},
     });
 
     ASSERT_EQ(results.size(), 2u);
@@ -3978,32 +4165,39 @@
     EXPECT_NE(results[0].minSupportedValue, std::nullopt);
     EXPECT_EQ(results[0].minSupportedValue.value(), RawPropValues{.int32Values = {0}});
     EXPECT_NE(results[0].maxSupportedValue, std::nullopt);
-    EXPECT_EQ(results[0].maxSupportedValue.value(), RawPropValues{.int32Values = {10}});
+    EXPECT_EQ(results[0].maxSupportedValue.value(), RawPropValues{.int32Values = {3}});
     EXPECT_EQ(results[1].status, StatusCode::INVALID_ARG);
 }
 
 TEST_F(FakeVehicleHardwareTest, testGetSupportedValuesLists) {
     auto results = getHardware()->getSupportedValuesLists({
             PropIdAreaId{.propId = toInt(TestVendorProperty::VENDOR_EXTENSION_INT_PROPERTY),
-                         .areaId = 0},
-            PropIdAreaId{.propId = toInt(VehicleProperty::HVAC_TEMPERATURE_SET), .areaId = 0},
+                         .areaId = toInt(VehicleAreaWindow::FRONT_WINDSHIELD)},
+            // This property does not specify supported values list.
+            PropIdAreaId{.propId = toInt(VehicleProperty::INFO_EV_BATTERY_CAPACITY), .areaId = 0},
     });
 
     ASSERT_EQ(results.size(), 2u);
     EXPECT_EQ(results[0].status, StatusCode::OK);
     EXPECT_NE(results[0].supportedValuesList, std::nullopt);
     EXPECT_NE((results[0].supportedValuesList)->size(), 0u);
-    EXPECT_EQ(results[0].supportedValuesList.value(), std::vector<std::optional<RawPropValues>>({
-                                                              RawPropValues{.int32Values = {0}},
-                                                              RawPropValues{.int32Values = {2}},
-                                                              RawPropValues{.int32Values = {4}},
-                                                              RawPropValues{.int32Values = {6}},
-                                                              RawPropValues{.int32Values = {8}},
-                                                              RawPropValues{.int32Values = {10}},
-                                                      }));
+    EXPECT_EQ(results[0].supportedValuesList.value(),
+              std::vector<std::optional<RawPropValues>>({RawPropValues{.int32Values = {1}},
+                                                         RawPropValues{.int32Values = {2}},
+                                                         RawPropValues{.int32Values = {3}}}));
     EXPECT_EQ(results[1].status, StatusCode::INVALID_ARG);
 }
 
+TEST_F(FakeVehicleHardwareTest, testGetSupportedValuesLists_populateFromSupportedEnumValues) {
+    auto results = getHardware()->getSupportedValuesLists({PropIdAreaId{
+            .propId = toInt(VehicleProperty::FORWARD_COLLISION_WARNING_STATE), .areaId = 0}});
+
+    ASSERT_EQ(results.size(), 1u);
+    EXPECT_EQ(results[0].status, StatusCode::OK);
+    ASSERT_NE(results[0].supportedValuesList, std::nullopt);
+    ASSERT_THAT(results[0].supportedValuesList.value(), ::testing::Not(::testing::IsEmpty()));
+}
+
 }  // namespace fake
 }  // namespace vehicle
 }  // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.cpp
index 8750375..e64c696 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.cpp
@@ -29,19 +29,45 @@
 
 namespace android::hardware::automotive::vehicle::virtualization {
 
+using ::grpc::ChannelCredentials;
+using ::grpc::ClientContext;
+using ::grpc::CreateChannel;
+using ::grpc::InsecureChannelCredentials;
+using ::grpc::Status;
+
 namespace {
 
 constexpr size_t MAX_RETRY_COUNT = 5;
 
-std::shared_ptr<::grpc::ChannelCredentials> getChannelCredentials() {
-    return ::grpc::InsecureChannelCredentials();
+std::shared_ptr<ChannelCredentials> getChannelCredentials() {
+    return InsecureChannelCredentials();
+}
+
+template <class ProtoRequestType>
+void fillPropIdAreaIdsToProtoRequest(const std::vector<PropIdAreaId>& propIdAreaIds,
+                                     ProtoRequestType* protoRequest) {
+    for (const auto& propIdAreaId : propIdAreaIds) {
+        proto_msg_converter::aidlToProto(propIdAreaId, protoRequest->add_prop_id_area_id());
+    }
+}
+
+template <class AidlResultType, class ProtoResultType>
+std::vector<AidlResultType> convertSupportedValueProtoResultToAidlResults(
+        const std::vector<PropIdAreaId>& propIdAreaIds, const ProtoResultType& protoResult) {
+    std::vector<AidlResultType> aidlResults;
+    for (const auto& protoResultPerRequest : protoResult.result()) {
+        AidlResultType aidlResult = {};
+        proto_msg_converter::protoToAidl(protoResultPerRequest, &aidlResult);
+        aidlResults.push_back(std::move(aidlResult));
+    }
+    return aidlResults;
 }
 
 }  // namespace
 
 GRPCVehicleHardware::GRPCVehicleHardware(std::string service_addr)
     : mServiceAddr(std::move(service_addr)),
-      mGrpcChannel(::grpc::CreateChannel(mServiceAddr, getChannelCredentials())),
+      mGrpcChannel(CreateChannel(mServiceAddr, getChannelCredentials())),
       mGrpcStub(proto::VehicleServer::NewStub(mGrpcChannel)),
       mValuePollingThread([this] { ValuePollingLoop(); }) {}
 
@@ -67,7 +93,7 @@
 
 std::vector<aidlvhal::VehiclePropConfig> GRPCVehicleHardware::getAllPropertyConfigs() const {
     std::vector<aidlvhal::VehiclePropConfig> configs;
-    ::grpc::ClientContext context;
+    ClientContext context;
     auto config_stream = mGrpcStub->GetAllPropertyConfig(&context, ::google::protobuf::Empty());
     proto::VehiclePropConfig protoConfig;
     while (config_stream->Read(&protoConfig)) {
@@ -97,7 +123,7 @@
 aidlvhal::StatusCode GRPCVehicleHardware::setValues(
         std::shared_ptr<const SetValuesCallback> callback,
         const std::vector<aidlvhal::SetValueRequest>& requests) {
-    ::grpc::ClientContext context;
+    ClientContext context;
     proto::VehiclePropValueRequests protoRequests;
     proto::SetValueResults protoResults;
     for (const auto& request : requests) {
@@ -160,7 +186,7 @@
     }
 
     // TODO(chenhaosjtuacm): Make it Async.
-    ::grpc::ClientContext context;
+    ClientContext context;
     proto::GetValueResults protoResults;
     auto grpc_status = mGrpcStub->GetValues(&context, protoRequests, &protoResults);
     if (!grpc_status.ok()) {
@@ -262,7 +288,7 @@
 }
 
 DumpResult GRPCVehicleHardware::dump(const std::vector<std::string>& options) {
-    ::grpc::ClientContext context;
+    ClientContext context;
     proto::DumpOptions protoDumpOptions;
     proto::DumpResult protoDumpResult;
     for (const auto& option : options) {
@@ -281,7 +307,7 @@
 }
 
 aidlvhal::StatusCode GRPCVehicleHardware::checkHealth() {
-    ::grpc::ClientContext context;
+    ClientContext context;
     proto::VehicleHalCallStatus protoStatus;
     auto grpc_status = mGrpcStub->CheckHealth(&context, ::google::protobuf::Empty(), &protoStatus);
     if (!grpc_status.ok()) {
@@ -293,7 +319,7 @@
 
 aidlvhal::StatusCode GRPCVehicleHardware::subscribe(aidlvhal::SubscribeOptions options) {
     proto::SubscribeRequest request;
-    ::grpc::ClientContext context;
+    ClientContext context;
     proto::VehicleHalCallStatus protoStatus;
     proto_msg_converter::aidlToProto(options, request.mutable_options());
     auto grpc_status = mGrpcStub->Subscribe(&context, request, &protoStatus);
@@ -311,7 +337,7 @@
 
 aidlvhal::StatusCode GRPCVehicleHardware::unsubscribe(int32_t propId, int32_t areaId) {
     proto::UnsubscribeRequest request;
-    ::grpc::ClientContext context;
+    ClientContext context;
     proto::VehicleHalCallStatus protoStatus;
     request.set_prop_id(propId);
     request.set_area_id(areaId);
@@ -330,7 +356,7 @@
 
 aidlvhal::StatusCode GRPCVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId,
                                                            float sampleRate) {
-    ::grpc::ClientContext context;
+    ClientContext context;
     proto::UpdateSampleRateRequest request;
     proto::VehicleHalCallStatus protoStatus;
     request.set_prop(propId);
@@ -357,7 +383,7 @@
 }
 
 void GRPCVehicleHardware::pollValue() {
-    ::grpc::ClientContext context;
+    ClientContext context;
 
     bool rpc_stopped{false};
     std::thread shuttingdown_watcher([this, &rpc_stopped, &context]() {
@@ -408,4 +434,56 @@
     LOG(ERROR) << __func__ << ": GRPC Value Streaming Failed: " << grpc_status.error_message();
 }
 
+std::vector<aidlvhal::MinMaxSupportedValueResult> GRPCVehicleHardware::getMinMaxSupportedValues(
+        const std::vector<PropIdAreaId>& propIdAreaIds) {
+    ClientContext context;
+    proto::GetMinMaxSupportedValuesRequest protoRequest = {};
+    proto::GetMinMaxSupportedValuesResult protoResult = {};
+    fillPropIdAreaIdsToProtoRequest(propIdAreaIds, &protoRequest);
+
+    auto grpc_status = mGrpcStub->GetMinMaxSupportedValues(&context, protoRequest, &protoResult);
+    std::vector<aidlvhal::MinMaxSupportedValueResult> aidlResults;
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__
+                   << ": GRPC GetMinMaxSupportedValues Failed: " << grpc_status.error_message();
+        for (const auto& propIdAreaId : propIdAreaIds) {
+            aidlResults.push_back({
+                    .status = aidlvhal::StatusCode::INTERNAL_ERROR,
+            });
+        }
+        return aidlResults;
+    }
+    aidlResults =
+            convertSupportedValueProtoResultToAidlResults<aidlvhal::MinMaxSupportedValueResult,
+                                                          proto::GetMinMaxSupportedValuesResult>(
+                    propIdAreaIds, protoResult);
+    return aidlResults;
+}
+
+std::vector<aidlvhal::SupportedValuesListResult> GRPCVehicleHardware::getSupportedValuesLists(
+        const std::vector<PropIdAreaId>& propIdAreaIds) {
+    ClientContext context;
+    proto::GetSupportedValuesListsRequest protoRequest = {};
+    proto::GetSupportedValuesListsResult protoResult = {};
+    fillPropIdAreaIdsToProtoRequest(propIdAreaIds, &protoRequest);
+
+    auto grpc_status = mGrpcStub->GetSupportedValuesLists(&context, protoRequest, &protoResult);
+    std::vector<aidlvhal::SupportedValuesListResult> aidlResults;
+    if (!grpc_status.ok()) {
+        LOG(ERROR) << __func__
+                   << ": GRPC GetSupportedValuesLists Failed: " << grpc_status.error_message();
+        for (const auto& propIdAreaId : propIdAreaIds) {
+            aidlResults.push_back({
+                    .status = aidlvhal::StatusCode::INTERNAL_ERROR,
+            });
+        }
+        return aidlResults;
+    }
+    aidlResults =
+            convertSupportedValueProtoResultToAidlResults<aidlvhal::SupportedValuesListResult,
+                                                          proto::GetSupportedValuesListsResult>(
+                    propIdAreaIds, protoResult);
+    return aidlResults;
+}
+
 }  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.h
index ad2f512..7fc3d79 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.h
@@ -90,6 +90,12 @@
 
     aidlvhal::StatusCode unsubscribe(int32_t propId, int32_t areaId) override;
 
+    std::vector<aidlvhal::MinMaxSupportedValueResult> getMinMaxSupportedValues(
+            const std::vector<PropIdAreaId>& propIdAreaIds) override;
+
+    std::vector<aidlvhal::SupportedValuesListResult> getSupportedValuesLists(
+            const std::vector<PropIdAreaId>& propIdAreaIds) override;
+
     bool waitForConnected(std::chrono::milliseconds waitTime);
 
   protected:
diff --git a/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.cpp
index 927a595..f216683 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.cpp
+++ b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.cpp
@@ -31,13 +31,33 @@
 
 namespace android::hardware::automotive::vehicle::virtualization {
 
-std::atomic<uint64_t> GrpcVehicleProxyServer::ConnectionDescriptor::connection_id_counter_{0};
-
-static std::shared_ptr<::grpc::ServerCredentials> getServerCredentials() {
-    // TODO(chenhaosjtuacm): get secured credentials here
+namespace {
+std::shared_ptr<::grpc::ServerCredentials> getServerCredentials() {
     return ::grpc::InsecureServerCredentials();
 }
 
+template <class ProtoRequestType>
+std::vector<PropIdAreaId> getPropIdAreaIdsFromProtoRequest(const ProtoRequestType* request) {
+    std::vector<PropIdAreaId> propIdAreaIds;
+    for (const proto::PropIdAreaId& protoPropIdAreaId : request->prop_id_area_id()) {
+        PropIdAreaId aidlPropIdAreaId = {};
+        proto_msg_converter::protoToAidl(protoPropIdAreaId, &aidlPropIdAreaId);
+        propIdAreaIds.push_back(aidlPropIdAreaId);
+    }
+    return propIdAreaIds;
+}
+
+template <class AidlResultType, class ProtoResultType>
+void aidlResultsToProtoResults(const AidlResultType& aidlResults, ProtoResultType* result) {
+    for (const auto& aidlResult : aidlResults) {
+        auto* protoResult = result->add_result();
+        proto_msg_converter::aidlToProto(aidlResult, protoResult);
+    }
+}
+}  // namespace
+
+std::atomic<uint64_t> GrpcVehicleProxyServer::ConnectionDescriptor::connection_id_counter_{0};
+
 GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::string serverAddr,
                                                std::unique_ptr<IVehicleHardware>&& hardware)
     : GrpcVehicleProxyServer(std::vector<std::string>({serverAddr}), std::move(hardware)) {};
@@ -243,6 +263,26 @@
     return ::grpc::Status(::grpc::StatusCode::ABORTED, "Connection lost.");
 }
 
+::grpc::Status GrpcVehicleProxyServer::GetMinMaxSupportedValues(
+        ::grpc::ServerContext* context, const proto::GetMinMaxSupportedValuesRequest* request,
+        proto::GetMinMaxSupportedValuesResult* result) {
+    std::vector<PropIdAreaId> propIdAreaIds = getPropIdAreaIdsFromProtoRequest(request);
+    std::vector<aidlvhal::MinMaxSupportedValueResult> minMaxSupportedValueResults =
+            mHardware->getMinMaxSupportedValues(propIdAreaIds);
+    aidlResultsToProtoResults(minMaxSupportedValueResults, result);
+    return ::grpc::Status::OK;
+}
+
+::grpc::Status GrpcVehicleProxyServer::GetSupportedValuesLists(
+        ::grpc::ServerContext* context, const proto::GetSupportedValuesListsRequest* request,
+        proto::GetSupportedValuesListsResult* result) {
+    std::vector<PropIdAreaId> propIdAreaIds = getPropIdAreaIdsFromProtoRequest(request);
+    std::vector<aidlvhal::SupportedValuesListResult> supportedValuesListResults =
+            mHardware->getSupportedValuesLists(propIdAreaIds);
+    aidlResultsToProtoResults(supportedValuesListResults, result);
+    return ::grpc::Status::OK;
+}
+
 void GrpcVehicleProxyServer::OnVehiclePropChange(
         const std::vector<aidlvhal::VehiclePropValue>& values) {
     std::unordered_set<uint64_t> brokenConn;
diff --git a/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.h b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.h
index 5ffb531..eb261ca 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.h
+++ b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.h
@@ -77,6 +77,14 @@
             ::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
             ::grpc::ServerWriter<proto::VehiclePropValues>* stream) override;
 
+    ::grpc::Status GetMinMaxSupportedValues(
+            ::grpc::ServerContext* context, const proto::GetMinMaxSupportedValuesRequest* requests,
+            proto::GetMinMaxSupportedValuesResult* results) override;
+
+    ::grpc::Status GetSupportedValuesLists(::grpc::ServerContext* context,
+                                           const proto::GetSupportedValuesListsRequest* requests,
+                                           proto::GetSupportedValuesListsResult* results) override;
+
     GrpcVehicleProxyServer& Start();
 
     GrpcVehicleProxyServer& Shutdown();
diff --git a/automotive/vehicle/aidl/impl/current/grpc/proto/VehicleServer.proto b/automotive/vehicle/aidl/impl/current/grpc/proto/VehicleServer.proto
index 732957f..3364ed7 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/proto/VehicleServer.proto
+++ b/automotive/vehicle/aidl/impl/current/grpc/proto/VehicleServer.proto
@@ -20,6 +20,8 @@
 
 import "android/hardware/automotive/vehicle/DumpOptions.proto";
 import "android/hardware/automotive/vehicle/DumpResult.proto";
+import "android/hardware/automotive/vehicle/GetMinMaxSupportedValuesTypes.proto";
+import "android/hardware/automotive/vehicle/GetSupportedValuesListsTypes.proto";
 import "android/hardware/automotive/vehicle/SubscribeRequest.proto";
 import "android/hardware/automotive/vehicle/StatusCode.proto";
 import "android/hardware/automotive/vehicle/UnsubscribeRequest.proto";
@@ -46,4 +48,10 @@
     rpc Subscribe(SubscribeRequest) returns (VehicleHalCallStatus) {}
 
     rpc Unsubscribe(UnsubscribeRequest) returns (VehicleHalCallStatus) {}
+
+    rpc GetMinMaxSupportedValues(GetMinMaxSupportedValuesRequest)
+            returns (GetMinMaxSupportedValuesResult) {}
+
+    rpc GetSupportedValuesLists(GetSupportedValuesListsRequest)
+            returns (GetSupportedValuesListsResult) {}
 }
diff --git a/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleHardwareUnitTest.cpp b/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleHardwareUnitTest.cpp
index 20af231..343e5b2 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleHardwareUnitTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleHardwareUnitTest.cpp
@@ -442,4 +442,119 @@
     EXPECT_LT(gotResults[0].prop->timestamp, elapsedRealtimeNano());
 }
 
+TEST_F(GRPCVehicleHardwareUnitTest, testGetMinMaxSupportedValues) {
+    int32_t testPropId = 1234;
+    int32_t testAreaId = 4321;
+    int32_t testValue1 = 12345;
+    int32_t testValue2 = 123456;
+    std::vector<PropIdAreaId> propIdAreaIds = {{.propId = testPropId, .areaId = testAreaId}};
+
+    EXPECT_CALL(*mGrpcStub, GetMinMaxSupportedValues(_, _, _))
+            .WillOnce([=](::grpc::ClientContext* context,
+                          const proto::GetMinMaxSupportedValuesRequest& request,
+                          proto::GetMinMaxSupportedValuesResult* response) {
+                for (const auto& propIdAreaId : request.prop_id_area_id()) {
+                    proto::MinMaxSupportedValueResult* individualResult = response->add_result();
+                    individualResult->set_status(proto::StatusCode::OK);
+                    individualResult->mutable_min_supported_value()->add_int32_values(testValue1);
+                    individualResult->mutable_max_supported_value()->add_int32_values(testValue2);
+                }
+                return ::grpc::Status::OK;
+            });
+
+    auto results = mHardware->getMinMaxSupportedValues(propIdAreaIds);
+
+    ASSERT_THAT(results, ::testing::SizeIs(1));
+    EXPECT_EQ(results[0].status, aidlvhal::StatusCode::OK);
+    ASSERT_TRUE(results[0].minSupportedValue.has_value());
+    EXPECT_EQ(results[0].minSupportedValue.value(),
+              aidlvhal::RawPropValues{.int32Values = {testValue1}});
+    ASSERT_TRUE(results[0].maxSupportedValue.has_value());
+    EXPECT_EQ(results[0].maxSupportedValue.value(),
+              aidlvhal::RawPropValues{.int32Values = {testValue2}});
+}
+
+TEST_F(GRPCVehicleHardwareUnitTest, testGetMinMaxSupportedValues_noMaxValue) {
+    int32_t testPropId = 1234;
+    int32_t testAreaId = 4321;
+    int32_t testValue1 = 12345;
+    std::vector<PropIdAreaId> propIdAreaIds = {{.propId = testPropId, .areaId = testAreaId}};
+
+    EXPECT_CALL(*mGrpcStub, GetMinMaxSupportedValues(_, _, _))
+            .WillOnce([=](::grpc::ClientContext* context,
+                          const proto::GetMinMaxSupportedValuesRequest& request,
+                          proto::GetMinMaxSupportedValuesResult* response) {
+                for (const auto& propIdAreaId : request.prop_id_area_id()) {
+                    proto::MinMaxSupportedValueResult* individualResult = response->add_result();
+                    individualResult->set_status(proto::StatusCode::OK);
+                    individualResult->mutable_min_supported_value()->add_int32_values(testValue1);
+                }
+                return ::grpc::Status::OK;
+            });
+
+    auto results = mHardware->getMinMaxSupportedValues(propIdAreaIds);
+
+    ASSERT_THAT(results, ::testing::SizeIs(1));
+    EXPECT_EQ(results[0].status, aidlvhal::StatusCode::OK);
+    ASSERT_TRUE(results[0].minSupportedValue.has_value());
+    EXPECT_EQ(results[0].minSupportedValue.value(),
+              aidlvhal::RawPropValues{.int32Values = {testValue1}});
+    ASSERT_FALSE(results[0].maxSupportedValue.has_value());
+}
+
+TEST_F(GRPCVehicleHardwareUnitTest, testGetSupportedValuesLists) {
+    int32_t testPropId = 1234;
+    int32_t testAreaId = 4321;
+    int32_t testValue1 = 12345;
+    int32_t testValue2 = 123456;
+    std::vector<PropIdAreaId> propIdAreaIds = {{.propId = testPropId, .areaId = testAreaId}};
+
+    EXPECT_CALL(*mGrpcStub, GetSupportedValuesLists(_, _, _))
+            .WillOnce([=](::grpc::ClientContext* context,
+                          const proto::GetSupportedValuesListsRequest& request,
+                          proto::GetSupportedValuesListsResult* response) {
+                for (const auto& propIdAreaId : request.prop_id_area_id()) {
+                    proto::SupportedValuesListResult* individualResult = response->add_result();
+                    individualResult->set_status(proto::StatusCode::OK);
+                    individualResult->add_supported_values_list()->add_int32_values(testValue1);
+                    individualResult->add_supported_values_list()->add_int32_values(testValue2);
+                }
+                return ::grpc::Status::OK;
+            });
+
+    auto results = mHardware->getSupportedValuesLists(propIdAreaIds);
+
+    ASSERT_THAT(results, ::testing::SizeIs(1));
+    EXPECT_EQ(results[0].status, aidlvhal::StatusCode::OK);
+    ASSERT_TRUE(results[0].supportedValuesList.has_value());
+    ASSERT_THAT(results[0].supportedValuesList.value(), ::testing::SizeIs(2));
+    EXPECT_EQ(results[0].supportedValuesList.value()[0],
+              aidlvhal::RawPropValues{.int32Values = {testValue1}});
+    EXPECT_EQ(results[0].supportedValuesList.value()[1],
+              aidlvhal::RawPropValues{.int32Values = {testValue2}});
+}
+
+TEST_F(GRPCVehicleHardwareUnitTest, testGetSupportedValuesLists_noSupportedValue) {
+    int32_t testPropId = 1234;
+    int32_t testAreaId = 4321;
+    std::vector<PropIdAreaId> propIdAreaIds = {{.propId = testPropId, .areaId = testAreaId}};
+
+    EXPECT_CALL(*mGrpcStub, GetSupportedValuesLists(_, _, _))
+            .WillOnce([=](::grpc::ClientContext* context,
+                          const proto::GetSupportedValuesListsRequest& request,
+                          proto::GetSupportedValuesListsResult* response) {
+                for (const auto& propIdAreaId : request.prop_id_area_id()) {
+                    proto::SupportedValuesListResult* individualResult = response->add_result();
+                    individualResult->set_status(proto::StatusCode::INTERNAL_ERROR);
+                }
+                return ::grpc::Status::OK;
+            });
+
+    auto results = mHardware->getSupportedValuesLists(propIdAreaIds);
+
+    ASSERT_THAT(results, ::testing::SizeIs(1));
+    EXPECT_EQ(results[0].status, aidlvhal::StatusCode::INTERNAL_ERROR);
+    ASSERT_FALSE(results[0].supportedValuesList.has_value());
+}
+
 }  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleProxyServerUnitTest.cpp b/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
index ca5c2d5..c07c629 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
@@ -105,6 +105,10 @@
     MOCK_METHOD(aidlvhal::StatusCode, unsubscribe, (int32_t propId, int32_t areaId), (override));
     MOCK_METHOD(aidlvhal::StatusCode, updateSampleRate,
                 (int32_t propId, int32_t areaId, float sampleRate), (override));
+    MOCK_METHOD(std::vector<aidlvhal::MinMaxSupportedValueResult>, getMinMaxSupportedValues,
+                (const std::vector<PropIdAreaId>& propIdAreaIds), (override));
+    MOCK_METHOD(std::vector<aidlvhal::SupportedValuesListResult>, getSupportedValuesLists,
+                (const std::vector<PropIdAreaId>& propIdAreaIds), (override));
 };
 
 TEST(GRPCVehicleProxyServerUnitTest, ClientConnectDisconnect) {
@@ -117,7 +121,7 @@
 
     constexpr auto kWaitForConnectionMaxTime = std::chrono::seconds(5);
     constexpr auto kWaitForStreamStartTime = std::chrono::seconds(1);
-    constexpr auto kWaitForUpdateDeliveryTime = std::chrono::milliseconds(100);
+    constexpr auto kWaitForUpdateDeliveryTime = std::chrono::seconds(1);
 
     auto updateReceived1 = std::make_shared<bool>(false);
     auto vehicleHardware1 = std::make_unique<GRPCVehicleHardware>(kFakeServerAddr);
@@ -129,7 +133,7 @@
 
     // Client hardware 1 received update from the server.
     EXPECT_FALSE(*updateReceived1);
-    testHardwareRaw->onPropertyEvent({});
+    testHardwareRaw->onPropertyEvent({aidlvhal::VehiclePropValue{.prop = 1}});
     // Wait for the update delivery.
     std::this_thread::sleep_for(kWaitForUpdateDeliveryTime);
     EXPECT_TRUE(*updateReceived1);
@@ -148,7 +152,7 @@
     // Both client hardware 1 and 2 received update from the server.
     EXPECT_FALSE(*updateReceived1);
     EXPECT_FALSE(*updateReceived2);
-    testHardwareRaw->onPropertyEvent({});
+    testHardwareRaw->onPropertyEvent({aidlvhal::VehiclePropValue{.prop = 1}});
     // Wait for the update delivery.
     std::this_thread::sleep_for(kWaitForUpdateDeliveryTime);
     EXPECT_TRUE(*updateReceived1);
@@ -163,7 +167,7 @@
     // Client 1 exited, only client hardware 2 received update from the server.
     EXPECT_FALSE(*updateReceived1);
     EXPECT_FALSE(*updateReceived2);
-    testHardwareRaw->onPropertyEvent({});
+    testHardwareRaw->onPropertyEvent({aidlvhal::VehiclePropValue{.prop = 1}});
     // Wait for the update delivery.
     std::this_thread::sleep_for(kWaitForUpdateDeliveryTime);
     EXPECT_FALSE(*updateReceived1);
@@ -238,4 +242,85 @@
     EXPECT_EQ(returnStatus.status_code(), proto::StatusCode::OK);
 }
 
+TEST(GRPCVehicleProxyServerUnitTest, testGetMinMaxSupportedValues) {
+    int32_t testPropId = 1234;
+    int32_t testAreaId = 4321;
+    int32_t testValue1 = 12345;
+    int32_t testValue2 = 54321;
+    auto mockHardware = std::make_unique<MockVehicleHardware>();
+    // We make sure this is alive inside the function scope.
+    MockVehicleHardware* mockHardwarePtr = mockHardware.get();
+    GrpcVehicleProxyServer server = GrpcVehicleProxyServer("", std::move(mockHardware));
+    ::grpc::ServerContext context;
+    proto::GetMinMaxSupportedValuesRequest request;
+    proto::GetMinMaxSupportedValuesResult result;
+    auto* requestPropIdAreaId = request.add_prop_id_area_id();
+    requestPropIdAreaId->set_prop_id(testPropId);
+    requestPropIdAreaId->set_area_id(testAreaId);
+    std::vector<PropIdAreaId> propIdAreaIds;
+    std::vector<aidlvhal::MinMaxSupportedValueResult> resultFromHardware = {{
+            .status = aidlvhal::StatusCode::OK,
+            .minSupportedValue = aidlvhal::RawPropValues{.int32Values = {testValue1}},
+            .maxSupportedValue = aidlvhal::RawPropValues{.int32Values = {testValue2}},
+    }};
+
+    EXPECT_CALL(*mockHardwarePtr, getMinMaxSupportedValues(_))
+            .WillOnce(DoAll(SaveArg<0>(&propIdAreaIds), Return(resultFromHardware)));
+
+    auto grpcStatus = server.GetMinMaxSupportedValues(&context, &request, &result);
+
+    ASSERT_THAT(propIdAreaIds, ::testing::SizeIs(1));
+    EXPECT_EQ(propIdAreaIds[0], PropIdAreaId({.propId = testPropId, .areaId = testAreaId}));
+
+    ASSERT_TRUE(grpcStatus.ok());
+    ASSERT_THAT(result.result(), ::testing::SizeIs(1));
+    EXPECT_EQ(result.result()[0].status(), proto::StatusCode::OK);
+    ASSERT_THAT(result.result()[0].min_supported_value().int32_values(), ::testing::SizeIs(1));
+    EXPECT_EQ(result.result()[0].min_supported_value().int32_values()[0], testValue1);
+    ASSERT_THAT(result.result()[0].max_supported_value().int32_values(), ::testing::SizeIs(1));
+    EXPECT_EQ(result.result()[0].max_supported_value().int32_values()[0], testValue2);
+}
+
+TEST(GRPCVehicleProxyServerUnitTest, testGetSupportedValuesLists) {
+    int32_t testPropId = 1234;
+    int32_t testAreaId = 4321;
+    int32_t testValue1 = 12345;
+    int32_t testValue2 = 54321;
+    auto mockHardware = std::make_unique<MockVehicleHardware>();
+    // We make sure this is alive inside the function scope.
+    MockVehicleHardware* mockHardwarePtr = mockHardware.get();
+    GrpcVehicleProxyServer server = GrpcVehicleProxyServer("", std::move(mockHardware));
+    ::grpc::ServerContext context;
+    proto::GetSupportedValuesListsRequest request;
+    proto::GetSupportedValuesListsResult result;
+    auto* requestPropIdAreaId = request.add_prop_id_area_id();
+    requestPropIdAreaId->set_prop_id(testPropId);
+    requestPropIdAreaId->set_area_id(testAreaId);
+    std::vector<PropIdAreaId> propIdAreaIds;
+    std::vector<aidlvhal::SupportedValuesListResult> resultFromHardware = {{
+            .status = aidlvhal::StatusCode::OK,
+            .supportedValuesList = std::vector<std::optional<aidlvhal::RawPropValues>>({
+                    aidlvhal::RawPropValues{.int32Values = {testValue1}},
+                    aidlvhal::RawPropValues{.int32Values = {testValue2}},
+            }),
+    }};
+
+    EXPECT_CALL(*mockHardwarePtr, getSupportedValuesLists(_))
+            .WillOnce(DoAll(SaveArg<0>(&propIdAreaIds), Return(resultFromHardware)));
+
+    auto grpcStatus = server.GetSupportedValuesLists(&context, &request, &result);
+
+    ASSERT_THAT(propIdAreaIds, ::testing::SizeIs(1));
+    EXPECT_EQ(propIdAreaIds[0], PropIdAreaId({.propId = testPropId, .areaId = testAreaId}));
+
+    ASSERT_TRUE(grpcStatus.ok());
+    ASSERT_THAT(result.result(), ::testing::SizeIs(1));
+    EXPECT_EQ(result.result()[0].status(), proto::StatusCode::OK);
+    ASSERT_THAT(result.result()[0].supported_values_list(), ::testing::SizeIs(2));
+    ASSERT_THAT(result.result()[0].supported_values_list()[0].int32_values(), ::testing::SizeIs(1));
+    EXPECT_THAT(result.result()[0].supported_values_list()[0].int32_values()[0], testValue1);
+    ASSERT_THAT(result.result()[0].supported_values_list()[1].int32_values(), ::testing::SizeIs(1));
+    EXPECT_THAT(result.result()[0].supported_values_list()[1].int32_values()[0], testValue2);
+}
+
 }  // namespace android::hardware::automotive::vehicle::virtualization
diff --git a/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
index 25c07ef..1cac067 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
+++ b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
@@ -18,6 +18,11 @@
 #define android_hardware_automotive_vehicle_aidl_impl_grpc_utils_proto_message_converter_include_ProtoMessageConverter_H_
 
 #include <VehicleHalTypes.h>
+#include <VehicleUtils.h>
+#include <android/hardware/automotive/vehicle/GetMinMaxSupportedValuesTypes.pb.h>
+#include <android/hardware/automotive/vehicle/GetSupportedValuesListsTypes.pb.h>
+#include <android/hardware/automotive/vehicle/PropIdAreaId.pb.h>
+#include <android/hardware/automotive/vehicle/RawPropValues.pb.h>
 #include <android/hardware/automotive/vehicle/SubscribeOptions.pb.h>
 #include <android/hardware/automotive/vehicle/VehicleAreaConfig.pb.h>
 #include <android/hardware/automotive/vehicle/VehiclePropConfig.pb.h>
@@ -53,6 +58,34 @@
 // Convert Protobuf SubscribeOptions to AIDL SubscribeOptions.
 void protoToAidl(const ::android::hardware::automotive::vehicle::proto::SubscribeOptions& in,
                  ::aidl::android::hardware::automotive::vehicle::SubscribeOptions* out);
+// Convert VehicleUtils PropIdAreaId to Protobuf PropIdAreaId.
+void aidlToProto(const PropIdAreaId& in,
+                 ::android::hardware::automotive::vehicle::proto::PropIdAreaId* out);
+// Convert Protobuf PropIdAreaId to VehicleUtils PropIdAreaId.
+void protoToAidl(const ::android::hardware::automotive::vehicle::proto::PropIdAreaId& in,
+                 PropIdAreaId* out);
+// Convert AIDL RawPropValues to Protobuf RawPropValues.
+void aidlToProto(const ::aidl::android::hardware::automotive::vehicle::RawPropValues& in,
+                 ::android::hardware::automotive::vehicle::proto::RawPropValues* out);
+// Convert Protobuf RawPropValues to AIDL RawPropValues.
+void protoToAidl(const ::android::hardware::automotive::vehicle::proto::RawPropValues& in,
+                 ::aidl::android::hardware::automotive::vehicle::RawPropValues* out);
+// Convert AIDL MinMaxSupportedValueResult to Protobuf MinMaxSupportedValueResult.
+void aidlToProto(
+        const ::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResult& in,
+        ::android::hardware::automotive::vehicle::proto::MinMaxSupportedValueResult* out);
+// Convert Protobuf MinMaxSupportedValueResult to AIDL MinMaxSupportedValueResult.
+void protoToAidl(
+        const ::android::hardware::automotive::vehicle::proto::MinMaxSupportedValueResult& in,
+        ::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResult* out);
+// Convert AIDL SupportedValuesListResult to Protobuf SupportedValuesListResult.
+void aidlToProto(
+        const ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResult& in,
+        ::android::hardware::automotive::vehicle::proto::SupportedValuesListResult* out);
+// Convert Protobuf SupportedValuesListResult to AIDL SupportedValuesListResult.
+void protoToAidl(
+        const ::android::hardware::automotive::vehicle::proto::SupportedValuesListResult& in,
+        ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResult* out);
 
 }  // namespace proto_msg_converter
 }  // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
index c40004a..bb16da4 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
+++ b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
@@ -80,6 +80,17 @@
             }
         }
         protoACfg->set_support_variable_update_rate(areaConfig.supportVariableUpdateRate);
+        if (areaConfig.hasSupportedValueInfo.has_value()) {
+            // Creates the has_supported_value_info field.
+            proto::HasSupportedValueInfo* hasSupportedValueInfoProto =
+                    protoACfg->mutable_has_supported_value_info();
+            hasSupportedValueInfoProto->set_has_min_supported_value(
+                    areaConfig.hasSupportedValueInfo->hasMinSupportedValue);
+            hasSupportedValueInfoProto->set_has_max_supported_value(
+                    areaConfig.hasSupportedValueInfo->hasMaxSupportedValue);
+            hasSupportedValueInfoProto->set_has_supported_values_list(
+                    areaConfig.hasSupportedValueInfo->hasSupportedValuesList);
+        }
     }
 }
 
@@ -96,13 +107,13 @@
     auto cast_to_acfg = [](const proto::VehicleAreaConfig& protoAcfg) {
         auto vehicleAreaConfig = aidl_vehicle::VehicleAreaConfig{
                 .areaId = protoAcfg.area_id(),
-                .access = static_cast<aidl_vehicle::VehiclePropertyAccess>(protoAcfg.access()),
                 .minInt32Value = protoAcfg.min_int32_value(),
                 .maxInt32Value = protoAcfg.max_int32_value(),
                 .minInt64Value = protoAcfg.min_int64_value(),
                 .maxInt64Value = protoAcfg.max_int64_value(),
                 .minFloatValue = protoAcfg.min_float_value(),
                 .maxFloatValue = protoAcfg.max_float_value(),
+                .access = static_cast<aidl_vehicle::VehiclePropertyAccess>(protoAcfg.access()),
                 .supportVariableUpdateRate = protoAcfg.support_variable_update_rate(),
         };
         if (protoAcfg.supported_enum_values().size() != 0) {
@@ -110,6 +121,16 @@
             COPY_PROTOBUF_VEC_TO_VHAL_TYPE(protoAcfg, supported_enum_values, (&vehicleAreaConfig),
                                            supportedEnumValues.value());
         }
+        if (protoAcfg.has_has_supported_value_info()) {
+            aidl_vehicle::HasSupportedValueInfo hasSupportedValueInfo = {};
+            hasSupportedValueInfo.hasMinSupportedValue =
+                    protoAcfg.has_supported_value_info().has_min_supported_value();
+            hasSupportedValueInfo.hasMaxSupportedValue =
+                    protoAcfg.has_supported_value_info().has_max_supported_value();
+            hasSupportedValueInfo.hasSupportedValuesList =
+                    protoAcfg.has_supported_value_info().has_supported_values_list();
+            vehicleAreaConfig.hasSupportedValueInfo = hasSupportedValueInfo;
+        }
 
         return vehicleAreaConfig;
     };
@@ -170,6 +191,94 @@
     out->enableVariableUpdateRate = in.enable_variable_update_rate();
 }
 
+void aidlToProto(const PropIdAreaId& in, proto::PropIdAreaId* out) {
+    out->set_prop_id(in.propId);
+    out->set_area_id(in.areaId);
+}
+
+void protoToAidl(const proto::PropIdAreaId& in, PropIdAreaId* out) {
+    out->propId = in.prop_id();
+    out->areaId = in.area_id();
+}
+
+void aidlToProto(const aidl_vehicle::RawPropValues& in, proto::RawPropValues* out) {
+    out->set_string_value(in.stringValue);
+    out->set_byte_values(in.byteValues.data(), in.byteValues.size());
+    for (auto& int32Value : in.int32Values) {
+        out->add_int32_values(int32Value);
+    }
+    for (auto& int64Value : in.int64Values) {
+        out->add_int64_values(int64Value);
+    }
+    for (auto& floatValue : in.floatValues) {
+        out->add_float_values(floatValue);
+    }
+}
+
+void protoToAidl(const proto::RawPropValues& in, aidl_vehicle::RawPropValues* out) {
+    COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, int32_values, out, int32Values);
+    COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, int64_values, out, int64Values);
+    COPY_PROTOBUF_VEC_TO_VHAL_TYPE(in, float_values, out, floatValues);
+    out->stringValue = in.string_value();
+    for (const char& byte : in.byte_values()) {
+        out->byteValues.push_back(byte);
+    }
+}
+
+void aidlToProto(const aidl_vehicle::MinMaxSupportedValueResult& in,
+                 proto::MinMaxSupportedValueResult* out) {
+    out->set_status(static_cast<proto::StatusCode>(in.status));
+    if (in.minSupportedValue.has_value()) {
+        aidlToProto(in.minSupportedValue.value(), out->mutable_min_supported_value());
+    }
+    if (in.maxSupportedValue.has_value()) {
+        aidlToProto(in.maxSupportedValue.value(), out->mutable_max_supported_value());
+    }
+}
+
+void protoToAidl(const proto::MinMaxSupportedValueResult& in,
+                 aidl_vehicle::MinMaxSupportedValueResult* out) {
+    out->status = static_cast<aidl_vehicle::StatusCode>(in.status());
+    if (in.has_min_supported_value()) {
+        aidl_vehicle::RawPropValues minSupportedValue = {};
+        protoToAidl(in.min_supported_value(), &minSupportedValue);
+        out->minSupportedValue = minSupportedValue;
+    }
+    if (in.has_max_supported_value()) {
+        aidl_vehicle::RawPropValues maxSupportedValue = {};
+        protoToAidl(in.max_supported_value(), &maxSupportedValue);
+        out->maxSupportedValue = maxSupportedValue;
+    }
+}
+
+void aidlToProto(const aidl_vehicle::SupportedValuesListResult& in,
+                 proto::SupportedValuesListResult* out) {
+    out->set_status(static_cast<proto::StatusCode>(in.status));
+    if (!in.supportedValuesList.has_value()) {
+        return;
+    }
+    for (const auto& protoSupportedValue : in.supportedValuesList.value()) {
+        if (protoSupportedValue.has_value()) {
+            aidlToProto(protoSupportedValue.value(), out->add_supported_values_list());
+        }
+    }
+}
+
+void protoToAidl(const proto::SupportedValuesListResult& in,
+                 aidl_vehicle::SupportedValuesListResult* out) {
+    out->status = static_cast<aidl_vehicle::StatusCode>(in.status());
+    if (out->status != aidl_vehicle::StatusCode::OK) {
+        return;
+    }
+    std::vector<std::optional<aidl_vehicle::RawPropValues>> aidlSupportedValuesList;
+    for (const auto& protoRawPropValues : in.supported_values_list()) {
+        aidl_vehicle::RawPropValues aidlRawPropValues = {};
+        protoToAidl(protoRawPropValues, &aidlRawPropValues);
+        aidlSupportedValuesList.push_back(std::move(aidlRawPropValues));
+    }
+    out->supportedValuesList = std::move(aidlSupportedValuesList);
+}
+
 #undef COPY_PROTOBUF_VEC_TO_VHAL_TYPE
 #undef CAST_COPY_PROTOBUF_VEC_TO_VHAL_TYPE
 
diff --git a/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
index 2efda5b..eafbe91 100644
--- a/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
+++ b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
@@ -83,7 +83,7 @@
 
 }  // namespace
 
-TEST_P(PropConfigConversionTest, testConversion) {
+TEST_P(PropConfigConversionTest, testConvertPropConfig) {
     proto::VehiclePropConfig protoCfg;
     aidl_vehicle::VehiclePropConfig aidlCfg;
 
@@ -93,7 +93,7 @@
     EXPECT_EQ(aidlCfg, GetParam());
 }
 
-TEST_P(PropValueConversionTest, testConversion) {
+TEST_P(PropValueConversionTest, testConvertPropValue) {
     proto::VehiclePropValue protoVal;
     aidl_vehicle::VehiclePropValue aidlVal;
 
@@ -130,6 +130,132 @@
     EXPECT_EQ(aidlOptions, outputOptions);
 }
 
+TEST_F(PropValueConversionTest, testConvertPropIdAreaId) {
+    proto::PropIdAreaId protoValue;
+    PropIdAreaId aidlValue = {.propId = 12, .areaId = 34};
+    PropIdAreaId outputValue;
+
+    aidlToProto(aidlValue, &protoValue);
+    protoToAidl(protoValue, &outputValue);
+
+    EXPECT_EQ(aidlValue, outputValue);
+}
+
+TEST_F(PropValueConversionTest, testConvertRawPropValues) {
+    proto::RawPropValues protoValue;
+    aidl_vehicle::RawPropValues aidlValue = {
+            .int32Values = {1, 2, 3, 4},
+            .floatValues = {1.1, 2.2, 3.3, 4.4},
+            .int64Values = {4L, 3L, 2L, 1L},
+            .byteValues = {0xde, 0xad, 0xbe, 0xef},
+            .stringValue = "test",
+    };
+    aidl_vehicle::RawPropValues outputValue;
+
+    aidlToProto(aidlValue, &protoValue);
+    protoToAidl(protoValue, &outputValue);
+
+    EXPECT_EQ(aidlValue, outputValue);
+}
+
+TEST_F(PropValueConversionTest, testConvertMinMaxSupportedValueResult) {
+    proto::MinMaxSupportedValueResult protoValue;
+    aidl_vehicle::RawPropValues aidlValue1 = {
+            .int32Values = {1, 2, 3, 4},
+            .floatValues = {1.1, 2.2, 3.3, 4.4},
+            .int64Values = {4L, 3L, 2L, 1L},
+            .byteValues = {0xde, 0xad, 0xbe, 0xef},
+            .stringValue = "test",
+    };
+    aidl_vehicle::RawPropValues aidlValue2 = {
+            .int32Values = {4, 3, 2, 1},
+            .floatValues = {3.3},
+            .int64Values = {2L, 3L},
+            .byteValues = {0xde, 0xad, 0xbe, 0xef},
+            .stringValue = "test",
+    };
+    aidl_vehicle::MinMaxSupportedValueResult aidlValue = {
+            .status = aidl_vehicle::StatusCode::OK,
+            .minSupportedValue = aidlValue1,
+            .maxSupportedValue = aidlValue2,
+    };
+    aidl_vehicle::MinMaxSupportedValueResult outputValue;
+
+    aidlToProto(aidlValue, &protoValue);
+    protoToAidl(protoValue, &outputValue);
+
+    EXPECT_EQ(aidlValue, outputValue);
+}
+
+TEST_F(PropValueConversionTest, testConvertMinMaxSupportedValueResult_errorStatus) {
+    proto::MinMaxSupportedValueResult protoValue;
+    aidl_vehicle::MinMaxSupportedValueResult aidlValue = {
+            .status = aidl_vehicle::StatusCode::INTERNAL_ERROR,
+    };
+    aidl_vehicle::MinMaxSupportedValueResult outputValue;
+
+    aidlToProto(aidlValue, &protoValue);
+    protoToAidl(protoValue, &outputValue);
+
+    EXPECT_EQ(aidlValue, outputValue);
+}
+
+TEST_F(PropValueConversionTest, testConvertSupportedValuesListResult) {
+    proto::SupportedValuesListResult protoValue;
+    aidl_vehicle::RawPropValues aidlValue1 = {
+            .int32Values = {1, 2, 3, 4},
+            .floatValues = {1.1, 2.2, 3.3, 4.4},
+            .int64Values = {4L, 3L, 2L, 1L},
+            .byteValues = {0xde, 0xad, 0xbe, 0xef},
+            .stringValue = "test",
+    };
+    aidl_vehicle::RawPropValues aidlValue2 = {
+            .int32Values = {4, 3, 2, 1},
+            .floatValues = {3.3},
+            .int64Values = {2L, 3L},
+            .byteValues = {0xde, 0xad, 0xbe, 0xef},
+            .stringValue = "test",
+    };
+    aidl_vehicle::SupportedValuesListResult aidlValue = {
+            .status = aidl_vehicle::StatusCode::OK,
+            .supportedValuesList = std::vector<std::optional<aidl_vehicle::RawPropValues>>(
+                    {aidlValue1, aidlValue2}),
+    };
+    aidl_vehicle::SupportedValuesListResult outputValue;
+
+    aidlToProto(aidlValue, &protoValue);
+    protoToAidl(protoValue, &outputValue);
+
+    EXPECT_EQ(aidlValue, outputValue);
+}
+
+TEST_F(PropValueConversionTest, testConvertSupportedValuesListResult_emptySupportedValues) {
+    proto::SupportedValuesListResult protoValue;
+    aidl_vehicle::SupportedValuesListResult aidlValue = {
+            .status = aidl_vehicle::StatusCode::OK,
+            .supportedValuesList = std::vector<std::optional<aidl_vehicle::RawPropValues>>({}),
+    };
+    aidl_vehicle::SupportedValuesListResult outputValue;
+
+    aidlToProto(aidlValue, &protoValue);
+    protoToAidl(protoValue, &outputValue);
+
+    EXPECT_EQ(aidlValue, outputValue);
+}
+
+TEST_F(PropValueConversionTest, testConvertSupportedValuesListResult_errorStatus) {
+    proto::SupportedValuesListResult protoValue;
+    aidl_vehicle::SupportedValuesListResult aidlValue = {
+            .status = aidl_vehicle::StatusCode::INTERNAL_ERROR,
+    };
+    aidl_vehicle::SupportedValuesListResult outputValue;
+
+    aidlToProto(aidlValue, &protoValue);
+    protoToAidl(protoValue, &outputValue);
+
+    EXPECT_EQ(aidlValue, outputValue);
+}
+
 }  // namespace proto_msg_converter
 }  // namespace vehicle
 }  // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/current/proto/Android.bp b/automotive/vehicle/aidl/impl/current/proto/Android.bp
index 2b5cdf4..b12288b 100644
--- a/automotive/vehicle/aidl/impl/current/proto/Android.bp
+++ b/automotive/vehicle/aidl/impl/current/proto/Android.bp
@@ -42,6 +42,11 @@
     out: [
         "android/hardware/automotive/vehicle/DumpOptions.pb.h",
         "android/hardware/automotive/vehicle/DumpResult.pb.h",
+        "android/hardware/automotive/vehicle/GetMinMaxSupportedValuesTypes.pb.h",
+        "android/hardware/automotive/vehicle/GetSupportedValuesListsTypes.pb.h",
+        "android/hardware/automotive/vehicle/HasSupportedValueInfo.pb.h",
+        "android/hardware/automotive/vehicle/PropIdAreaId.pb.h",
+        "android/hardware/automotive/vehicle/RawPropValues.pb.h",
         "android/hardware/automotive/vehicle/StatusCode.pb.h",
         "android/hardware/automotive/vehicle/VehicleAreaConfig.pb.h",
         "android/hardware/automotive/vehicle/VehiclePropConfig.pb.h",
@@ -69,6 +74,11 @@
     out: [
         "android/hardware/automotive/vehicle/DumpOptions.pb.cc",
         "android/hardware/automotive/vehicle/DumpResult.pb.cc",
+        "android/hardware/automotive/vehicle/GetMinMaxSupportedValuesTypes.pb.cc",
+        "android/hardware/automotive/vehicle/GetSupportedValuesListsTypes.pb.cc",
+        "android/hardware/automotive/vehicle/HasSupportedValueInfo.pb.cc",
+        "android/hardware/automotive/vehicle/PropIdAreaId.pb.cc",
+        "android/hardware/automotive/vehicle/RawPropValues.pb.cc",
         "android/hardware/automotive/vehicle/StatusCode.pb.cc",
         "android/hardware/automotive/vehicle/VehicleAreaConfig.pb.cc",
         "android/hardware/automotive/vehicle/VehiclePropConfig.pb.cc",
diff --git a/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/GetMinMaxSupportedValuesTypes.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/GetMinMaxSupportedValuesTypes.proto
new file mode 100644
index 0000000..b70c24c
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/GetMinMaxSupportedValuesTypes.proto
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+import "android/hardware/automotive/vehicle/PropIdAreaId.proto";
+import "android/hardware/automotive/vehicle/RawPropValues.proto";
+import "android/hardware/automotive/vehicle/StatusCode.proto";
+
+message MinMaxSupportedValueResult {
+    /**
+     * The status for result. If this is not OK, the operation failed for this
+     * [propId, areaId].
+     */
+    StatusCode status = 1;
+    /**
+     * The min supported value.
+     *
+     * If the [propId, areaId] does not specify a min supported value, this
+     * is {@code null}.
+     */
+    RawPropValues min_supported_value = 2;
+    /**
+     * The max supported value.
+     *
+     * If the [propId, areaId] does not specify a max supported value, this
+     * is {@code null}.
+     *
+     * This must be ignored if status is not {@code StatusCode.OK}.
+     */
+    RawPropValues max_supported_value = 3;
+};
+
+message GetMinMaxSupportedValuesRequest {
+    repeated PropIdAreaId prop_id_area_id = 1;
+};
+
+message GetMinMaxSupportedValuesResult {
+    repeated MinMaxSupportedValueResult result = 1;
+};
diff --git a/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/GetSupportedValuesListsTypes.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/GetSupportedValuesListsTypes.proto
new file mode 100644
index 0000000..a1488ea
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/GetSupportedValuesListsTypes.proto
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+import "android/hardware/automotive/vehicle/PropIdAreaId.proto";
+import "android/hardware/automotive/vehicle/RawPropValues.proto";
+import "android/hardware/automotive/vehicle/StatusCode.proto";
+
+message SupportedValuesListResult {
+    /**
+     * The status for result. If this is not OK, the operation failed for this
+     * [propId, areaId].
+     */
+    StatusCode status = 1;
+    /**
+     * The supported values list.
+     *
+     * If the [propId, areaId] does not specify a supported values list, this
+     * is {@code null}.
+     *
+     * This must be ignored if status is not {@code StatusCode.OK}.
+     */
+    repeated RawPropValues supported_values_list = 2;
+};
+
+message GetSupportedValuesListsRequest {
+    repeated PropIdAreaId prop_id_area_id = 1;
+};
+
+message GetSupportedValuesListsResult {
+    repeated SupportedValuesListResult result = 1;
+};
diff --git a/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/HasSupportedValueInfo.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/HasSupportedValueInfo.proto
new file mode 100644
index 0000000..c04deb4
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/HasSupportedValueInfo.proto
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+/* Must be in sync with HasSupportedValueInfo.aidl. */
+message HasSupportedValueInfo {
+    /**
+     * Whether [propId, areaId] has min supported value specified.
+     *
+     * If this is {@code true}, the hardware specifies a min supported value.
+     * If {@code MinMaxSupportedValueResult}'s {@code status} is
+     * {@code StatusCode.OK}, its {@code minSupportedValue} must not be
+     * {@code null}.
+     *
+     * If this is {@code false}, {@code minSupportedValue} must be {@code null}.
+     *
+     * Unless otherwise specified, this field is set to {@code false} for any
+     * properties whose type is not int32, int64 or float.
+     *
+     * For certain properties, e.g. {@code EV_BRAKE_REGENERATION_LEVEL}, this
+     * must always be {@code true}. Check {@code VehicleProperty}
+     * documentation.
+     */
+    bool has_min_supported_value = 1;
+
+    /**
+     * Whether [propId, areaId] has max supported value specified.
+     *
+     * If this is {@code true}, the hardware specifies a max supported value.
+     * If {@code MinMaxSupportedValueResult}'s {@code status} is
+     * {@code StatusCode.OK}, its {@code maxSupportedValue} must not be
+     * {@code null}.
+     *
+     * If this is {@code false}, {@code maxSupportedValue} must be {@code null}.
+     *
+     * Unless otherwise specified, this field is set to {@code false} for any
+     * properties whose type is not int32, int64 or float.
+     *
+     * For certain properties, e.g. {@code EV_BRAKE_REGENERATION_LEVEL}, this
+     * must always be {@code true}. Check {@code VehicleProperty}
+     * documentation.
+     */
+    bool has_max_supported_value = 2;
+
+    /**
+     * Whether [propId, areaId] has supported values list specified.
+     *
+     * If this is {@code true}, it means the hardware specifies supported
+     * values for this property.
+     * If {@code SupportedValueListResult}'s {@code status} is
+     * {@code StatusCode.OK}, its {@code supportedValuesList} must not be
+     * {@code null}.
+     *
+     * If this is {@code false}, {@code supportedValuesList} must always be
+     * {@code null}.
+     *
+     * The supported value is the superset for both the input value for writable
+     * property and the output value for readable property.
+     *
+     * For certain properties, e.g. {@code GEAR_SELECTION}, this must always be
+     * {@code true}. Check {@code VehicleProperty} documentation.
+     */
+    bool has_supported_values_list = 3;
+};
diff --git a/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/PropIdAreaId.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/PropIdAreaId.proto
new file mode 100644
index 0000000..556eec6
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/PropIdAreaId.proto
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+message PropIdAreaId {
+    int32 prop_id = 1;
+    int32 area_id = 2;
+};
diff --git a/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/RawPropValues.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/RawPropValues.proto
new file mode 100644
index 0000000..8f54fea
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/RawPropValues.proto
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.hardware.automotive.vehicle.proto;
+
+/* Must be in sync with RawPropValues.aidl. */
+message RawPropValues {
+    /* This is used for properties of types VehiclePropertyType#INT
+     * and VehiclePropertyType#INT_VEC */
+    repeated int32 int32_values = 1;
+
+    /* This is used for properties of types VehiclePropertyType#FLOAT
+     * and VehiclePropertyType#FLOAT_VEC */
+    repeated float float_values = 2;
+
+    /* This is used for properties of type VehiclePropertyType#INT64 */
+    repeated int64 int64_values = 3;
+
+    /* This is used for properties of type VehiclePropertyType#BYTES */
+    bytes byte_values = 4;
+
+    /* This is used for properties of type VehiclePropertyType#STRING */
+    string string_value = 5;
+};
diff --git a/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
index 7ea8540..695af31 100644
--- a/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
+++ b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
@@ -19,6 +19,7 @@
 package android.hardware.automotive.vehicle.proto;
 
 import "android/hardware/automotive/vehicle/VehiclePropertyAccess.proto";
+import "android/hardware/automotive/vehicle/HasSupportedValueInfo.proto";
 
 /* Must be in sync with VehicleAreaConfig.aidl. */
 message VehicleAreaConfig {
@@ -47,4 +48,30 @@
     repeated int64 supported_enum_values = 8;
     VehiclePropertyAccess access = 9;
     bool support_variable_update_rate = 10;
+    /**
+     * This specifies whether this property may have min/max supported value or supported values
+     * list for [propId, areaId] that supports new supported values APIs.
+     *
+     * If this is not {@code null}. The client may use {@code getMinMaxSupportedValue},
+     * {@code getSupportedValuesLists}, {@code subscribeSupportedValueChange},
+     * {@code unsubscribeSupportedValueChange}.
+     *
+     * If this is not {@code null}. The VHAL implementation must implement
+     * {@code getMinMaxSupportedValue}, {@code getSupportedValuesLists},
+     * {@code subscribeSupportedValueChange} for the [propId, areaId].
+     *
+     * This should be non-null if the VHAL implementation wants to expose
+     * min/max supported value or supported values list that may change dynamically. For example,
+     * if the max HVAC fan speed may change due to HVAC power settings.
+     *
+     * This should not be non-null if the VHAL implementation wants to expose supported
+     * values list for property ID that is not an enum type (hence do not support
+     * {@code VehicleAreaConfig#supportedEnumValues}).
+     *
+     * If this is {@code null}, the APIs mentioned before are not supported.
+     * Client must fallback to use static supported value information in {@code VehicleAreaConfig}.
+     *
+     * For VHAL implementation < V4, this is always {@code null}.
+     */
+    HasSupportedValueInfo has_supported_value_info = 11;
 };
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/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
index d0edfad..ff4ce3d 100644
--- a/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
+++ b/bluetooth/1.0/vts/functional/VtsHalBluetoothV1_0TargetTest.cpp
@@ -534,6 +534,8 @@
     // Check the loopback of the ACL packet
     ASSERT_TRUE(bluetooth_cb->WaitForCallback(kCallbackNameAclEventReceived)
                     .no_timeout);
+    ASSERT_FALSE(acl_queue.empty());
+
     hidl_vec<uint8_t> acl_loopback = acl_queue.front();
     acl_queue.pop();
 
diff --git a/bluetooth/aidl/Android.bp b/bluetooth/aidl/Android.bp
index 4ee2f49..0daecf7 100644
--- a/bluetooth/aidl/Android.bp
+++ b/bluetooth/aidl/Android.bp
@@ -16,6 +16,13 @@
     srcs: ["android/hardware/bluetooth/*.aidl"],
     stability: "vintf",
     backend: {
+        cpp: {
+            // FIXME should this be disabled?
+            // prefer NDK backend which can be used anywhere
+            // If you disable this, you also need to delete the C++
+            // translate code.
+            enabled: true,
+        },
         rust: {
             enabled: true,
         },
@@ -37,4 +44,5 @@
         },
     ],
     frozen: true,
+
 }
diff --git a/bluetooth/aidl/default/Android.bp b/bluetooth/aidl/default/Android.bp
index d3f6364..46a6983 100644
--- a/bluetooth/aidl/default/Android.bp
+++ b/bluetooth/aidl/default/Android.bp
@@ -2,61 +2,58 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-cc_library_static {
-    name: "libbluetoothhcihalimpl",
-    vendor_available: true,
-    host_supported: true,
-    srcs: [
-        "BluetoothHci.cpp",
-        "net_bluetooth_mgmt.cpp",
-    ],
+cc_defaults {
+    name: "android.hardware.bluetooth-service-build-defaults",
     cflags: [
         "-Wall",
         "-Wextra",
     ],
-    header_libs: [
-        "libbluetooth_offload_hal_headers",
+    shared_libs: [
+        "android.hardware.bluetooth-V1-ndk",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libutils",
     ],
     static_libs: [
         "android.hardware.bluetooth.async",
         "android.hardware.bluetooth.hci",
-    ],
-    shared_libs: [
-        "libbase",
-        "libcutils",
-        "liblog",
-        "libutils",
+        "libbluetooth_offload_hal",
     ],
 }
 
-rust_binary {
+cc_library_static {
+    name: "libbluetoothhcihalimpl",
+    vendor_available: true,
+    defaults: ["android.hardware.bluetooth-service-build-defaults"],
+    srcs: [
+        "BluetoothHci.cpp",
+        "net_bluetooth_mgmt.cpp",
+    ],
+}
+
+cc_binary {
     name: "android.hardware.bluetooth-service.default",
-    crate_name: "bluetooth_hci_hal_server",
     relative_install_path: "hw",
     init_rc: ["bluetooth-service-default.rc"],
     vintf_fragments: [":manifest_android.hardware.bluetooth-service.default.xml"],
     vendor: true,
-    prefer_rlib: true,
-    srcs: ["main.rs"],
-    rustlibs: [
-        "android.hardware.bluetooth-V1-rust",
-        "libbluetooth_offload_hal",
-        "libbluetooth_offload_leaudio_hci",
-        "libbinder_rs",
-        "liblogger",
-        "liblog_rust",
-    ],
-    static_libs: [
-        "android.hardware.bluetooth.async",
-        "android.hardware.bluetooth.hci",
-        "libbluetoothhcihalimpl",
+    defaults: ["android.hardware.bluetooth-service-build-defaults"],
+    srcs: [
+        "service.cpp",
     ],
     shared_libs: [
+        "android.hardware.bluetooth-V1-ndk",
         "libbase",
-        "libc++",
-        "libcutils",
-        "liblog",
+        "libbinder_ndk",
+        "libhidlbase",
         "libutils",
+        "liblog",
+    ],
+    static_libs: [
+        "libbluetoothhcihalimpl",
     ],
 }
 
diff --git a/bluetooth/aidl/default/BluetoothHci.cpp b/bluetooth/aidl/default/BluetoothHci.cpp
index bcdb67e..5ac3afe 100644
--- a/bluetooth/aidl/default/BluetoothHci.cpp
+++ b/bluetooth/aidl/default/BluetoothHci.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 The Android Open Source Project
+ * Copyright 2022 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.
@@ -16,20 +16,18 @@
 
 #define LOG_TAG "android.hardware.bluetooth.service.default"
 
+#include "BluetoothHci.h"
+
 #include <cutils/properties.h>
 #include <fcntl.h>
-#include <hal/ffi.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <poll.h>
 #include <string.h>
+#include <sys/uio.h>
 #include <termios.h>
 
-#include <future>
-#include <memory>
-#include <vector>
-
-#include "async_fd_watcher.h"
-#include "h4_protocol.h"
 #include "log/log.h"
-#include "net_bluetooth_mgmt.h"
 
 namespace {
 int SetTerminalRaw(int fd) {
@@ -46,6 +44,7 @@
 
 using namespace ::android::hardware::bluetooth::hci;
 using namespace ::android::hardware::bluetooth::async;
+using aidl::android::hardware::bluetooth::hal::Status;
 
 namespace aidl::android::hardware::bluetooth::impl {
 
@@ -62,298 +61,234 @@
   return str.compare(0, prefix.length(), prefix) == 0;
 }
 
-class Hal {
- public:
-  Hal(const std::string& dev_path = "/dev/hvc5") {
-    char property_bytes[PROPERTY_VALUE_MAX];
-    property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
-    mDevPath = std::string(property_bytes);
-  }
+BluetoothHci::BluetoothHci(const std::string& dev_path) {
+  char property_bytes[PROPERTY_VALUE_MAX];
+  property_get("vendor.ser.bt-uart", property_bytes, dev_path.c_str());
+  mDevPath = std::string(property_bytes);
+}
 
-  static void Initialize(void* instance,
-                         const struct hal_callbacks* callbacks) {
-    static_cast<Hal*>(instance)->Initialize(callbacks);
-  }
-
-  static void Close(void* instance) { static_cast<Hal*>(instance)->Close(); }
-
-  static void SendCommand(void* instance, const uint8_t* data, size_t len) {
-    static_cast<Hal*>(instance)->SendCommand(
-        std::vector<uint8_t>(data, data + len));
-  }
-
-  static void SendAcl(void* instance, const uint8_t* data, size_t len) {
-    static_cast<Hal*>(instance)->SendAcl(
-        std::vector<uint8_t>(data, data + len));
-  }
-
-  static void SendSco(void* instance, const uint8_t* data, size_t len) {
-    static_cast<Hal*>(instance)->SendSco(
-        std::vector<uint8_t>(data, data + len));
-  }
-
-  static void SendIso(void* instance, const uint8_t* data, size_t len) {
-    static_cast<Hal*>(instance)->SendIso(
-        std::vector<uint8_t>(data, data + len));
-  }
-
- private:
-  int getFdFromDevPath() {
-    int fd = open(mDevPath.c_str(), O_RDWR);
-    if (fd < 0) {
-      ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
-            strerror(errno));
-      return fd;
-    }
-    if (int ret = SetTerminalRaw(fd) < 0) {
-      ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
-            strerror(errno));
-    }
+int BluetoothHci::getFdFromDevPath() {
+  int fd = open(mDevPath.c_str(), O_RDWR);
+  if (fd < 0) {
+    ALOGE("Could not connect to bt: %s (%s)", mDevPath.c_str(),
+          strerror(errno));
     return fd;
   }
+  if (int ret = SetTerminalRaw(fd) < 0) {
+    ALOGI("Could not make %s a raw terminal %d(%s)", mDevPath.c_str(), ret,
+          strerror(errno));
+  }
+  return fd;
+}
 
-  void reset() {
-    // Send a reset command and wait until the command complete comes back.
+void BluetoothHci::reset() {
+  // Send a reset command and wait until the command complete comes back.
 
-    std::vector<uint8_t> reset = {0x03, 0x0c, 0x00};
+  std::vector<uint8_t> reset = {0x03, 0x0c, 0x00};
 
-    auto resetPromise = std::make_shared<std::promise<void>>();
-    auto resetFuture = resetPromise->get_future();
+  auto resetPromise = std::make_shared<std::promise<void>>();
+  auto resetFuture = resetPromise->get_future();
 
-    mH4 = std::make_shared<H4Protocol>(
-        mFd,
-        [](const std::vector<uint8_t>& raw_command) {
-          ALOGI("Discarding %d bytes with command type",
-                static_cast<int>(raw_command.size()));
-        },
-        [](const std::vector<uint8_t>& raw_acl) {
-          ALOGI("Discarding %d bytes with acl type",
-                static_cast<int>(raw_acl.size()));
-        },
-        [](const std::vector<uint8_t>& raw_sco) {
-          ALOGI("Discarding %d bytes with sco type",
-                static_cast<int>(raw_sco.size()));
-        },
-        [resetPromise](const std::vector<uint8_t>& raw_event) {
-          std::vector<uint8_t> reset_complete = {0x0e, 0x04, 0x01,
-                                                 0x03, 0x0c, 0x00};
-          bool valid = raw_event.size() == 6 &&
-                       raw_event[0] == reset_complete[0] &&
-                       raw_event[1] == reset_complete[1] &&
-                       // Don't compare the number of packets field.
-                       raw_event[3] == reset_complete[3] &&
-                       raw_event[4] == reset_complete[4] &&
-                       raw_event[5] == reset_complete[5];
-          if (valid) {
-            resetPromise->set_value();
-          } else {
-            ALOGI("Discarding %d bytes with event type",
-                  static_cast<int>(raw_event.size()));
-          }
-        },
-        [](const std::vector<uint8_t>& raw_iso) {
-          ALOGI("Discarding %d bytes with iso type",
-                static_cast<int>(raw_iso.size()));
-        },
-        [this]() {
-          ALOGI("HCI socket device disconnected while waiting for reset");
-          mFdWatcher.StopWatchingFileDescriptors();
-        });
-    mFdWatcher.WatchFdForNonBlockingReads(mFd,
-                                          [this](int) { mH4->OnDataReady(); });
+  mH4 = std::make_shared<H4Protocol>(
+      mFd,
+      [](const std::vector<uint8_t>& raw_command) {
+        ALOGI("Discarding %d bytes with command type",
+              static_cast<int>(raw_command.size()));
+      },
+      [](const std::vector<uint8_t>& raw_acl) {
+        ALOGI("Discarding %d bytes with acl type",
+              static_cast<int>(raw_acl.size()));
+      },
+      [](const std::vector<uint8_t>& raw_sco) {
+        ALOGI("Discarding %d bytes with sco type",
+              static_cast<int>(raw_sco.size()));
+      },
+      [resetPromise](const std::vector<uint8_t>& raw_event) {
+        std::vector<uint8_t> reset_complete = {0x0e, 0x04, 0x01,
+                                               0x03, 0x0c, 0x00};
+        bool valid = raw_event.size() == 6 &&
+                     raw_event[0] == reset_complete[0] &&
+                     raw_event[1] == reset_complete[1] &&
+                     // Don't compare the number of packets field.
+                     raw_event[3] == reset_complete[3] &&
+                     raw_event[4] == reset_complete[4] &&
+                     raw_event[5] == reset_complete[5];
+        if (valid) {
+          resetPromise->set_value();
+        } else {
+          ALOGI("Discarding %d bytes with event type",
+                static_cast<int>(raw_event.size()));
+        }
+      },
+      [](const std::vector<uint8_t>& raw_iso) {
+        ALOGI("Discarding %d bytes with iso type",
+              static_cast<int>(raw_iso.size()));
+      },
+      [this]() {
+        ALOGI("HCI socket device disconnected while waiting for reset");
+        mFdWatcher.StopWatchingFileDescriptors();
+      });
+  mFdWatcher.WatchFdForNonBlockingReads(mFd,
+                                        [this](int) { mH4->OnDataReady(); });
 
-    if (!send(PacketType::COMMAND, reset)) {
-      ALOGE("Error sending reset command");
-    }
-    auto status = resetFuture.wait_for(std::chrono::seconds(1));
-    mFdWatcher.StopWatchingFileDescriptors();
-    if (status == std::future_status::ready) {
-      ALOGI("HCI Reset successful");
-    } else {
-      ALOGE("HCI Reset Response not received in one second");
-    }
-
-    resetPromise.reset();
+  send(PacketType::COMMAND, reset);
+  auto status = resetFuture.wait_for(std::chrono::seconds(1));
+  mFdWatcher.StopWatchingFileDescriptors();
+  if (status == std::future_status::ready) {
+    ALOGI("HCI Reset successful");
+  } else {
+    ALOGE("HCI Reset Response not received in one second");
   }
 
-  void Initialize(const struct hal_callbacks* callbacks) {
-    ALOGI(__func__);
+  resetPromise.reset();
+}
 
-    HalState old_state = HalState::READY;
-    {
-      std::lock_guard<std::mutex> guard(mStateMutex);
-      if (mState != HalState::READY) {
-        old_state = mState;
-      } else {
-        mState = HalState::INITIALIZING;
-      }
-    }
+void BluetoothHci::initialize(
+    const std::shared_ptr<hal::IBluetoothHciCallbacks>& cb) {
+  ALOGI(__func__);
 
-    if (old_state != HalState::READY) {
-      ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
-      Close();
-      callbacks->initialization_complete(callbacks->handle,
-                                         STATUS_ALREADY_INITIALIZED);
-      return;
-    }
-
-    mCallbacks = std::make_unique<struct hal_callbacks>(*callbacks);
-    management_.reset(new NetBluetoothMgmt);
-    mFd = management_->openHci();
-    if (mFd < 0) {
-      management_.reset();
-
-      ALOGI("Unable to open Linux interface, trying default path.");
-      mFd = getFdFromDevPath();
-      if (mFd < 0) {
-        mState = HalState::READY;
-        mCallbacks->initialization_complete(mCallbacks->handle,
-                                            STATUS_UNABLE_TO_OPEN_INTERFACE);
-        return;
-      }
-    }
-
-    // TODO: HCI Reset on emulators since the bluetooth controller
-    // cannot be powered on/off during the HAL setup; and the stack
-    // might received spurious packets/events during boottime.
-    // Proper solution would be to use bt-virtio or vsock to better
-    // control the link to rootcanal and the controller lifetime.
-    const std::string kBoardProperty = "ro.product.board";
-    const std::string kCuttlefishBoard = "cutf";
-    auto board_name = GetSystemProperty(kBoardProperty);
-    if (board_name.has_value() &&
-        (starts_with(board_name.value(), "cutf") ||
-         starts_with(board_name.value(), "goldfish"))) {
-      reset();
-    }
-
-    mH4 = std::make_shared<H4Protocol>(
-        mFd,
-        [](const std::vector<uint8_t>& /* raw_command */) {
-          LOG_ALWAYS_FATAL("Unexpected command!");
-        },
-        [this](const std::vector<uint8_t>& raw_acl) {
-          mCallbacks->acl_received(mCallbacks->handle, raw_acl.data(),
-                                   raw_acl.size());
-        },
-        [this](const std::vector<uint8_t>& raw_sco) {
-          mCallbacks->sco_received(mCallbacks->handle, raw_sco.data(),
-                                   raw_sco.size());
-        },
-        [this](const std::vector<uint8_t>& raw_event) {
-          mCallbacks->event_received(mCallbacks->handle, raw_event.data(),
-                                     raw_event.size());
-        },
-        [this](const std::vector<uint8_t>& raw_iso) {
-          mCallbacks->iso_received(mCallbacks->handle, raw_iso.data(),
-                                   raw_iso.size());
-        },
-        [this]() {
-          ALOGI("HCI socket device disconnected");
-          mFdWatcher.StopWatchingFileDescriptors();
-        });
-    mFdWatcher.WatchFdForNonBlockingReads(mFd,
-                                          [this](int) { mH4->OnDataReady(); });
-
-    {
-      std::lock_guard<std::mutex> guard(mStateMutex);
-      mState = HalState::ONE_CLIENT;
-    }
-
-    ALOGI("initialization complete");
-    mCallbacks->initialization_complete(mCallbacks->handle, STATUS_SUCCESS);
+  if (cb == nullptr) {
+    ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
+    abort();
   }
 
-  void Close() {
-    ALOGI(__func__);
-    {
-      std::lock_guard<std::mutex> guard(mStateMutex);
-      if (mState != HalState::ONE_CLIENT) {
-        LOG_ALWAYS_FATAL_IF(mState == HalState::INITIALIZING,
-                            "mState is INITIALIZING");
-        ALOGI("Already closed");
-        return;
-      }
-      mCallbacks.reset();
-      mState = HalState::CLOSING;
-    }
-
-    mFdWatcher.StopWatchingFileDescriptors();
-
-    if (management_) {
-      management_->closeHci();
-    } else {
-      ::close(mFd);
-    }
-
-    {
-      std::lock_guard<std::mutex> guard(mStateMutex);
-      mState = HalState::READY;
-      mH4 = nullptr;
-    }
-  }
-
-  void SendCommand(const std::vector<uint8_t>& data) {
-    send(PacketType::COMMAND, data);
-  }
-  void SendAcl(const std::vector<uint8_t>& data) {
-    send(PacketType::ACL_DATA, data);
-  }
-  void SendSco(const std::vector<uint8_t>& data) {
-    send(PacketType::SCO_DATA, data);
-  }
-  void SendIso(const std::vector<uint8_t>& data) {
-    send(PacketType::ISO_DATA, data);
-  }
-
-  bool send(PacketType type, const std::vector<uint8_t>& v) {
-    if (v.empty()) {
-      ALOGE("Packet is empty, no data was found to be sent");
-      return false;
-    }
-
+  HalState old_state = HalState::READY;
+  {
     std::lock_guard<std::mutex> guard(mStateMutex);
-    if (mH4 == nullptr) {
-      ALOGE("Illegal State");
-      return false;
+    if (mState != HalState::READY) {
+      old_state = mState;
+    } else {
+      mState = HalState::INITIALIZING;
     }
-
-    mH4->Send(type, v);
-    return true;
   }
 
-  std::unique_ptr<struct hal_callbacks> mCallbacks;
-  std::string mDevPath;
-  int mFd{-1};
-  ::android::hardware::bluetooth::async::AsyncFdWatcher mFdWatcher;
-  std::shared_ptr<::android::hardware::bluetooth::hci::H4Protocol> mH4;
-  std::unique_ptr<NetBluetoothMgmt> management_{};
+  if (old_state != HalState::READY) {
+    ALOGE("initialize: Unexpected State %d", static_cast<int>(old_state));
+    close();
+    cb->initializationComplete(Status::ALREADY_INITIALIZED);
+  }
 
-  // Don't close twice or open before close is complete
-  std::mutex mStateMutex;
-  enum class HalState {
-    READY,
-    INITIALIZING,
-    ONE_CLIENT,
-    CLOSING,
-  } mState{HalState::READY};
-};
+  mCb = cb;
+  management_.reset(new NetBluetoothMgmt);
+  mFd = management_->openHci();
+  if (mFd < 0) {
+    management_.reset();
+
+    ALOGI("Unable to open Linux interface, trying default path.");
+    mFd = getFdFromDevPath();
+    if (mFd < 0) {
+      mState = HalState::READY;
+      cb->initializationComplete(Status::UNABLE_TO_OPEN_INTERFACE);
+    }
+  }
+
+  // TODO: HCI Reset on emulators since the bluetooth controller
+  // cannot be powered on/off during the HAL setup; and the stack
+  // might received spurious packets/events during boottime.
+  // Proper solution would be to use bt-virtio or vsock to better
+  // control the link to rootcanal and the controller lifetime.
+  const std::string kBoardProperty = "ro.product.board";
+  const std::string kCuttlefishBoard = "cutf";
+  auto board_name = GetSystemProperty(kBoardProperty);
+  if (board_name.has_value() && (
+        starts_with(board_name.value(), "cutf") ||
+        starts_with(board_name.value(), "goldfish"))) {
+    reset();
+  }
+
+  mH4 = std::make_shared<H4Protocol>(
+      mFd,
+      [](const std::vector<uint8_t>& /* raw_command */) {
+        LOG_ALWAYS_FATAL("Unexpected command!");
+      },
+      [this](const std::vector<uint8_t>& raw_acl) {
+        mCb->aclDataReceived(raw_acl);
+      },
+      [this](const std::vector<uint8_t>& raw_sco) {
+        mCb->scoDataReceived(raw_sco);
+      },
+      [this](const std::vector<uint8_t>& raw_event) {
+        mCb->hciEventReceived(raw_event);
+      },
+      [this](const std::vector<uint8_t>& raw_iso) {
+        mCb->isoDataReceived(raw_iso);
+      },
+      [this]() {
+        ALOGI("HCI socket device disconnected");
+        mFdWatcher.StopWatchingFileDescriptors();
+      });
+  mFdWatcher.WatchFdForNonBlockingReads(mFd,
+                                        [this](int) { mH4->OnDataReady(); });
+
+  {
+    std::lock_guard<std::mutex> guard(mStateMutex);
+    mState = HalState::ONE_CLIENT;
+  }
+  ALOGI("initialization complete");
+  mCb->initializationComplete(Status::SUCCESS);
+}
+
+void BluetoothHci::close() {
+  ALOGI(__func__);
+  {
+    std::lock_guard<std::mutex> guard(mStateMutex);
+    if (mState != HalState::ONE_CLIENT) {
+      LOG_ALWAYS_FATAL_IF(mState == HalState::INITIALIZING,
+                          "mState is INITIALIZING");
+      ALOGI("Already closed");
+    }
+    mState = HalState::CLOSING;
+  }
+
+  mFdWatcher.StopWatchingFileDescriptors();
+
+  if (management_) {
+    management_->closeHci();
+  } else {
+    ::close(mFd);
+  }
+
+  {
+    std::lock_guard<std::mutex> guard(mStateMutex);
+    mState = HalState::READY;
+    mH4 = nullptr;
+  }
+}
+
+void BluetoothHci::clientDied() {
+  ALOGI(__func__);
+  close();
+}
+
+void BluetoothHci::sendHciCommand(const std::vector<uint8_t>& packet) {
+  return send(PacketType::COMMAND, packet);
+}
+
+void BluetoothHci::sendAclData(const std::vector<uint8_t>& packet) {
+  return send(PacketType::ACL_DATA, packet);
+}
+
+void BluetoothHci::sendScoData(const std::vector<uint8_t>& packet) {
+  return send(PacketType::SCO_DATA, packet);
+}
+
+void BluetoothHci::sendIsoData(const std::vector<uint8_t>& packet) {
+  return send(PacketType::ISO_DATA, packet);
+}
+
+void BluetoothHci::send(PacketType type, const std::vector<uint8_t>& v) {
+  if (v.empty()) {
+    ALOGE("Packet is empty, no data was found to be sent");
+    abort();
+  }
+
+  std::lock_guard<std::mutex> guard(mStateMutex);
+  if (mH4 == nullptr) {
+    ALOGE("Illegal State");
+    abort();
+  }
+
+  mH4->Send(type, v);
+}
 
 }  // namespace aidl::android::hardware::bluetooth::impl
-
-extern "C" {
-
-using namespace aidl::android::hardware::bluetooth::impl;
-
-struct hal_interface hal_new() {
-  return (struct hal_interface){
-      .handle = new Hal(),
-      .initialize = &Hal::Initialize,
-      .close = &Hal::Close,
-      .send_command = &Hal::SendCommand,
-      .send_acl = &Hal::SendAcl,
-      .send_sco = &Hal::SendSco,
-      .send_iso = &Hal::SendIso,
-  };
-}
-}
diff --git a/bluetooth/aidl/default/BluetoothHci.h b/bluetooth/aidl/default/BluetoothHci.h
new file mode 100644
index 0000000..5c31468
--- /dev/null
+++ b/bluetooth/aidl/default/BluetoothHci.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2022 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 <hal/ffi.h>
+
+#include <future>
+#include <string>
+
+#include "async_fd_watcher.h"
+#include "h4_protocol.h"
+#include "net_bluetooth_mgmt.h"
+
+namespace aidl::android::hardware::bluetooth::impl {
+
+// This Bluetooth HAL implementation connects with a serial port at dev_path_.
+class BluetoothHci : public hal::IBluetoothHci {
+ public:
+  BluetoothHci(const std::string& dev_path = "/dev/hvc5");
+
+  void initialize(
+      const std::shared_ptr<hal::IBluetoothHciCallbacks>& cb) override;
+
+  void sendHciCommand(const std::vector<uint8_t>& packet) override;
+
+  void sendAclData(const std::vector<uint8_t>& packet) override;
+
+  void sendScoData(const std::vector<uint8_t>& packet) override;
+
+  void sendIsoData(const std::vector<uint8_t>& packet) override;
+
+  void close() override;
+
+  void clientDied() override;
+
+  static void OnPacketReady();
+
+  static BluetoothHci* get();
+
+ private:
+  int mFd{-1};
+  std::shared_ptr<hal::IBluetoothHciCallbacks> mCb = nullptr;
+
+  std::shared_ptr<::android::hardware::bluetooth::hci::H4Protocol> mH4;
+
+  std::string mDevPath;
+
+  ::android::hardware::bluetooth::async::AsyncFdWatcher mFdWatcher;
+
+  int getFdFromDevPath();
+  void send(::android::hardware::bluetooth::hci::PacketType type,
+            const std::vector<uint8_t>& packet);
+  std::unique_ptr<NetBluetoothMgmt> management_{};
+
+  // Send a reset command and discard all packets until a reset is received.
+  void reset();
+
+  // Don't close twice or open before close is complete
+  std::mutex mStateMutex;
+  enum class HalState {
+    READY,
+    INITIALIZING,
+    ONE_CLIENT,
+    CLOSING,
+  } mState{HalState::READY};
+};
+
+}  // namespace aidl::android::hardware::bluetooth::impl
diff --git a/bluetooth/aidl/default/main.rs b/bluetooth/aidl/default/main.rs
deleted file mode 100644
index b30162a..0000000
--- a/bluetooth/aidl/default/main.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2024, 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.
-
-use android_hardware_bluetooth::aidl::android::hardware::bluetooth::IBluetoothHci::{
-    self,
-    IBluetoothHci as _
-};
-use android_hardware_bluetooth::binder;
-use bluetooth_offload_hal::{ HciHalProxy, CInterface };
-use bluetooth_offload_leaudio_hci::LeAudioModuleBuilder;
-use log;
-use std::panic;
-
-fn new_hal() -> CInterface {
-    extern "C" { fn hal_new() -> CInterface; }
-    unsafe { hal_new() }
-}
-
-fn main() {
-    logger::init(
-        logger::Config::default()
-            .with_max_level(log::LevelFilter::Debug)
-            .with_tag_on_device("android.hardware.bluetooth"),
-    );
-
-    panic::set_hook(Box::new(|panic_info| {
-        log::error!("{}", panic_info);
-    }));
-
-    log::info!("Bluetooth HAL starting up");
-
-    binder::ProcessState::set_thread_pool_max_thread_count(0);
-    binder::ProcessState::start_thread_pool();
-
-    binder::add_service(
-        &format!("{}/default", IBluetoothHci::BpBluetoothHci::get_descriptor()),
-        IBluetoothHci::BnBluetoothHci::new_binder(
-            HciHalProxy::new(
-                vec![ Box::new(LeAudioModuleBuilder {}) ],
-                new_hal()
-            ),
-            binder::BinderFeatures::default(),
-        ).as_binder()
-    ).expect("Failed to register service");
-
-    binder::ProcessState::join_thread_pool();
-}
diff --git a/bluetooth/aidl/default/service.cpp b/bluetooth/aidl/default/service.cpp
new file mode 100644
index 0000000..9e1a22c
--- /dev/null
+++ b/bluetooth/aidl/default/service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2022 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.
+ */
+
+#define LOG_TAG "aidl.android.hardware.bluetooth.service.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "BluetoothHci.h"
+
+using ::aidl::android::hardware::bluetooth::hal::IBluetoothHci_addService;
+using ::aidl::android::hardware::bluetooth::impl::BluetoothHci;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+
+int main(int /* argc */, char** /* argv */) {
+  ALOGI("Bluetooth HAL starting");
+  if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+    ALOGI("failed to set thread pool max thread count");
+    return 1;
+  }
+
+  IBluetoothHci_addService(new BluetoothHci());
+  ABinderProcess_joinThreadPool();
+  return 0;
+}
diff --git a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
index 6b9046c..10c347b 100644
--- a/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
+++ b/bluetooth/audio/aidl/default/A2dpOffloadCodecSbc.cpp
@@ -102,7 +102,7 @@
   kBlockLength16
 };
 
-enum { kSubbands8 = kSubbands.first, kSubbands4 };
+enum { kSubbands4 = kSubbands.first, kSubbands8 };
 
 enum {
   kAllocationMethodSnr = kAllocationMethod.first,
@@ -486,7 +486,7 @@
   }
 
   min_bitpool = std::max(min_bitpool, uint8_t(lcaps.get(kMinimumBitpool)));
-  max_bitpool = std::max(max_bitpool, uint8_t(lcaps.get(kMaximumBitpool)));
+  max_bitpool = std::min(max_bitpool, uint8_t(lcaps.get(kMaximumBitpool)));
 
   if (hint) {
     min_bitpool =
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index 8d03fae..d68113d 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -78,8 +78,7 @@
                        cookie);
 
   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
-  onSessionReady(_aidl_return);
-  return ndk::ScopedAStatus::ok();
+  return onSessionReady(_aidl_return);
 }
 
 ndk::ScopedAStatus BluetoothAudioProvider::endSession() {
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/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
index 003da11..9cd63d6 100644
--- a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
@@ -37,8 +37,9 @@
     /**
      * The value used by the Host stack for the local Maximum Packet Size shall be the value
      * LE_ACL_Data_Packet_Length returned by the controller in response to the command HCI LE Read
-     * Buffer Size. Then, the MPS size must be in range 1 to 255. We do not make the MPS
-     * configurable in HAL because using the maximum value does not require a large amount of
-     * memory.
+     * Buffer Size if Total_Num_LE_ACL_Data_Packets is not zero. The MPS shall be the value
+     * ACL_Data_Packet_Length returned in response to the command HCI Read Buffer Size if
+     * Total_Num_LE_ACL_Data_Packets is zero. We do not make the MPS configurable in HAL because
+     * using the maximum value does not require a large amount of memory.
      */
 }
diff --git a/broadcastradio/aidl/OWNERS b/broadcastradio/aidl/OWNERS
index 302fdd7..51a85e4 100644
--- a/broadcastradio/aidl/OWNERS
+++ b/broadcastradio/aidl/OWNERS
@@ -1,4 +1,3 @@
 xuweilin@google.com
 oscarazu@google.com
 ericjeong@google.com
-keunyoung@google.com
diff --git a/broadcastradio/aidl/vts/OWNERS b/broadcastradio/aidl/vts/OWNERS
index 302fdd7..51a85e4 100644
--- a/broadcastradio/aidl/vts/OWNERS
+++ b/broadcastradio/aidl/vts/OWNERS
@@ -1,4 +1,3 @@
 xuweilin@google.com
 oscarazu@google.com
 ericjeong@google.com
-keunyoung@google.com
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 49c8410..bfc2d90 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -8715,25 +8715,14 @@
     ASSERT_NE(nullptr, bufferItemConsumer);
     ASSERT_NE(nullptr, bufferHandler);
 
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
-    *bufferItemConsumer = new BufferItemConsumer(
-            GraphicBuffer::USAGE_HW_TEXTURE);  // Use GLConsumer default usage flags
-#else
-    sp<IGraphicBufferProducer> producer;
-    sp<IGraphicBufferConsumer> consumer;
-    BufferQueue::createBufferQueue(&producer, &consumer);
-    *bufferItemConsumer = new BufferItemConsumer(consumer,
-            GraphicBuffer::USAGE_HW_TEXTURE); //Use GLConsumer default usage flags
-#endif  // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
+    sp<Surface> surface;
+    std::tie(*bufferItemConsumer, surface) =
+            BufferItemConsumer::create(GraphicBuffer::USAGE_HW_TEXTURE);
+
     ASSERT_NE(nullptr, (*bufferItemConsumer).get());
     *bufferHandler = new BufferItemHander(*bufferItemConsumer);
     ASSERT_NE(nullptr, (*bufferHandler).get());
     (*bufferItemConsumer)->setFrameAvailableListener(*bufferHandler);
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
-    sp<Surface> surface = (*bufferItemConsumer)->getSurface();
-#else
-    sp<Surface> surface = new Surface(producer);
-#endif  // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
     sp<PreviewWindowCb> previewCb = new PreviewWindowCb(surface);
 
     auto rc = device->setPreviewWindow(previewCb);
diff --git a/compatibility_matrices/Android.bp b/compatibility_matrices/Android.bp
index 63ef223..0d37060 100644
--- a/compatibility_matrices/Android.bp
+++ b/compatibility_matrices/Android.bp
@@ -88,8 +88,6 @@
         "compatibility_matrix.5.xml",
     ],
     kernel_configs: [
-        "kernel_config_r_4.14",
-        "kernel_config_r_4.19",
         "kernel_config_r_5.4",
     ],
 }
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 1cf98b0..d01a6ea 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -1,578 +1,7 @@
 <compatibility-matrix version="1.0" type="framework" level="5">
-    <hal format="hidl">
-        <name>android.hardware.atrace</name>
-        <version>1.0</version>
-        <interface>
-            <name>IAtraceDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.audio</name>
-        <version>6.0</version>
-        <interface>
-            <name>IDevicesFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.audio.effect</name>
-        <version>6.0</version>
-        <interface>
-            <name>IEffectsFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.authsecret</name>
-        <version>1.0</version>
-        <interface>
-            <name>IAuthSecret</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.automotive.audiocontrol</name>
-        <version>1.0</version>
-        <version>2.0</version>
-        <interface>
-            <name>IAudioControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.automotive.can</name>
-        <version>1.0</version>
-        <interface>
-            <name>ICanBus</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-        <interface>
-            <name>ICanController</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.automotive.evs</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IEvsEnumerator</name>
-            <instance>default</instance>
-            <regex-instance>[a-z]+/[0-9]+</regex-instance>
-        </interface>
-    </hal>
-    <hal format="aidl">
-        <name>android.hardware.automotive.occupant_awareness</name>
-        <interface>
-            <name>IOccupantAwareness</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.automotive.sv</name>
-        <version>1.0</version>
-        <interface>
-            <name>ISurroundViewService</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.automotive.vehicle</name>
-        <version>2.0</version>
-        <interface>
-            <name>IVehicle</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.biometrics.face</name>
-        <version>1.0</version>
-        <interface>
-            <name>IBiometricsFace</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.biometrics.fingerprint</name>
-        <version>2.1-2</version>
-        <interface>
-            <name>IBiometricsFingerprint</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.bluetooth</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IBluetoothHci</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.bluetooth.audio</name>
-        <version>2.0</version>
-        <interface>
-            <name>IBluetoothAudioProvidersFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.boot</name>
-        <version>1.1</version>
-        <interface>
-            <name>IBootControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.broadcastradio</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IBroadcastRadioFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.broadcastradio</name>
-        <version>2.0</version>
-        <interface>
-            <name>IBroadcastRadio</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.camera.provider</name>
-        <version>2.4-6</version>
-        <interface>
-            <name>ICameraProvider</name>
-            <regex-instance>[^/]+/[0-9]+</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.cas</name>
-        <version>1.1-2</version>
-        <interface>
-            <name>IMediaCasService</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.confirmationui</name>
-        <version>1.0</version>
-        <interface>
-            <name>IConfirmationUI</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.contexthub</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IContexthub</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.drm</name>
-        <version>1.3</version>
-        <interface>
-            <name>ICryptoFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-        <interface>
-            <name>IDrmFactory</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.dumpstate</name>
-        <version>1.1</version>
-        <interface>
-            <name>IDumpstateDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.gatekeeper</name>
-        <version>1.0</version>
-        <interface>
-            <name>IGatekeeper</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.gnss</name>
-        <version>2.0-1</version>
-        <interface>
-            <name>IGnss</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <!-- Either the AIDL or the HIDL allocator HAL must exist on the device.
-         If the HIDL composer HAL exists, it must be at least version 2.0.
-         See DeviceManifestTest.GrallocHal -->
-    <hal format="hidl">
-        <name>android.hardware.graphics.allocator</name>
-        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
-        <version>2.0</version>
-        <version>3.0</version>
-        <version>4.0</version>
-        <interface>
-            <name>IAllocator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.graphics.composer</name>
-        <version>2.1-4</version>
-        <interface>
-            <name>IComposer</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.graphics.mapper</name>
-        <!-- New, non-Go devices should use 4.0, tested in vts_treble_vintf_vendor_test -->
-        <version>2.1</version>
-        <version>3.0</version>
-        <version>4.0</version>
-        <interface>
-            <name>IMapper</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <!-- Either the AIDL or the HIDL health HAL must exist on the device.
-         If the HIDL health HAL exists, it must be at least version 2.1.
-         See DeviceManifestTest.HealthHal -->
-    <hal format="hidl">
-        <name>android.hardware.health</name>
-        <version>2.1</version>
-        <interface>
-            <name>IHealth</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.health.storage</name>
-        <version>1.0</version>
-        <interface>
-            <name>IStorage</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl">
-        <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>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.ir</name>
-        <version>1.0</version>
-        <interface>
-            <name>IConsumerIr</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.input.classifier</name>
-        <version>1.0</version>
-        <interface>
-            <name>IInputClassifier</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.keymaster</name>
-        <version>3.0</version>
-        <version>4.0-1</version>
-        <interface>
-            <name>IKeymasterDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.keymaster</name>
-        <version>4.0-1</version>
-        <interface>
-            <name>IKeymasterDevice</name>
-            <instance>strongbox</instance>
-        </interface>
-    </hal>
-    <hal format="aidl">
-        <name>android.hardware.light</name>
-        <interface>
-            <name>ILights</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.media.c2</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IComponentStore</name>
-            <instance>software</instance>
-            <regex-instance>default[0-9]*</regex-instance>
-            <regex-instance>vendor[0-9]*_software</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.media.c2</name>
-        <version>1.0</version>
-        <interface>
-            <name>IConfigurable</name>
-            <instance>default</instance>
-            <instance>software</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.media.omx</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOmx</name>
-            <instance>default</instance>
-        </interface>
-        <interface>
-            <name>IOmxStore</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.memtrack</name>
-        <version>1.0</version>
-        <interface>
-            <name>IMemtrack</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.neuralnetworks</name>
-        <version>1.0-3</version>
-        <interface>
-            <name>IDevice</name>
-            <regex-instance>.*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.nfc</name>
-        <version>1.2</version>
-        <interface>
-            <name>INfc</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.oemlock</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOemLock</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl">
-        <name>android.hardware.power</name>
-        <interface>
-            <name>IPower</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.power.stats</name>
-        <version>1.0</version>
-        <interface>
-            <name>IPowerStats</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.radio</name>
-        <version>1.4</version>
-        <version>1.5</version>
-        <interface>
-            <name>IRadio</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-            <instance>slot3</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.radio</name>
-        <version>1.2</version>
-        <interface>
-            <name>ISap</name>
-            <instance>slot1</instance>
-            <instance>slot2</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.radio.config</name>
-        <!--
-        See compatibility_matrix.4.xml on versioning of radio config HAL.
-        -->
-        <version>1.1</version>
-        <interface>
-            <name>IRadioConfig</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.renderscript</name>
-        <version>1.0</version>
-        <interface>
-            <name>IDevice</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl">
-        <name>android.hardware.rebootescrow</name>
-        <interface>
-            <name>IRebootEscrow</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.secure_element</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>ISecureElement</name>
-            <regex-instance>eSE[1-9][0-9]*</regex-instance>
-            <regex-instance>SIM[1-9][0-9]*</regex-instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.sensors</name>
-        <version>1.0</version>
-        <version>2.0-1</version>
-        <interface>
-            <name>ISensors</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.soundtrigger</name>
-        <version>2.0-3</version>
-        <interface>
-            <name>ISoundTriggerHw</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.tetheroffload.config</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOffloadConfig</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.tetheroffload.control</name>
-        <version>1.0</version>
-        <interface>
-            <name>IOffloadControl</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.thermal</name>
-        <version>2.0</version>
-        <interface>
-            <name>IThermal</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.tv.cec</name>
-        <version>1.0</version>
-        <interface>
-            <name>IHdmiCec</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.tv.input</name>
-        <version>1.0</version>
-        <interface>
-            <name>ITvInput</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.tv.tuner</name>
-        <version>1.0</version>
-        <interface>
-            <name>ITuner</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.usb</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>IUsb</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.usb.gadget</name>
-        <version>1.0-1</version>
-        <interface>
-            <name>IUsbGadget</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="aidl">
-        <name>android.hardware.vibrator</name>
-        <interface>
-            <name>IVibrator</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.vr</name>
-        <version>1.0</version>
-        <interface>
-            <name>IVr</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.weaver</name>
-        <version>1.0</version>
-        <interface>
-            <name>IWeaver</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.wifi</name>
-        <version>1.0-4</version>
-        <interface>
-            <name>IWifi</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.wifi.hostapd</name>
-        <version>1.0-2</version>
-        <interface>
-            <name>IHostapd</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl">
-        <name>android.hardware.wifi.supplicant</name>
-        <version>1.0-3</version>
-        <interface>
-            <name>ISupplicant</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
+  <!--
+    Android R FCM has been deprecated, but this file is kept
+    to help manage the android11-5.4 kernel config requirements as that
+    kernel version is not being deprecated with the R FCM.
+    -->
 </compatibility-matrix>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 57e039c..a2a13d1 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -104,6 +104,28 @@
             "android.hardware.vibrator@1.1",
             "android.hardware.vibrator@1.2",
             "android.hardware.vibrator@1.3",
+
+            // b/392700935 for HALs deprecated in R
+            "android.hardware.automotive.audiocontrol@1.0",
+            "android.hardware.automotive.audiocontrol@2.0",
+            "android.hardware.boot@1.1",
+            "android.hardware.contexthub@1.0",
+            "android.hardware.contexthub@1.1",
+            "android.hardware.health.storage@1.0",
+            "android.hardware.memtrack@1.0",
+            "android.hardware.power.stats@1.0",
+            "android.hardware.radio@1.4",
+            "android.hardware.radio@1.5",
+            "android.hardware.soundtrigger@2.0",
+            "android.hardware.soundtrigger@2.1",
+            "android.hardware.soundtrigger@2.2",
+            "android.hardware.tetheroffload.control@1.0",
+            "android.hardware.vr@1.0",
+            "android.hardware.wifi.supplicant@1.0",
+            "android.hardware.wifi.supplicant@1.1",
+            "android.hardware.wifi@1.0",
+            "android.hardware.wifi@1.1",
+            "android.hardware.wifi@1.2",
     };
 
     auto package_has_prefix = [&](const std::string& prefix) {
diff --git a/configstore/OWNERS b/configstore/OWNERS
index 70ad434..74789b5 100644
--- a/configstore/OWNERS
+++ b/configstore/OWNERS
@@ -1,3 +1,2 @@
 # Bug component: 24939
 
-lpy@google.com
diff --git a/confirmationui/1.0/default/OWNERS b/confirmationui/1.0/default/OWNERS
index 17aed51..d8b8840 100644
--- a/confirmationui/1.0/default/OWNERS
+++ b/confirmationui/1.0/default/OWNERS
@@ -1,3 +1,2 @@
 # Bug component: 1124672
-jdanis@google.com
 swillden@google.com
diff --git a/confirmationui/1.0/vts/OWNERS b/confirmationui/1.0/vts/OWNERS
index aa07242..b0ee996 100644
--- a/confirmationui/1.0/vts/OWNERS
+++ b/confirmationui/1.0/vts/OWNERS
@@ -1,4 +1,3 @@
 # Bug component: 1124672
-jdanis@google.com
 swillden@google.com
 yim@google.com
diff --git a/confirmationui/support/OWNERS b/confirmationui/support/OWNERS
index 17aed51..d8b8840 100644
--- a/confirmationui/support/OWNERS
+++ b/confirmationui/support/OWNERS
@@ -1,3 +1,2 @@
 # Bug component: 1124672
-jdanis@google.com
 swillden@google.com
diff --git a/gatekeeper/1.0/default/OWNERS b/gatekeeper/1.0/default/OWNERS
index c97fba6..d552a9a 100644
--- a/gatekeeper/1.0/default/OWNERS
+++ b/gatekeeper/1.0/default/OWNERS
@@ -1,3 +1,2 @@
 # Bug component: 1124862
-jdanis@google.com
 swillden@google.com
diff --git a/gatekeeper/1.0/software/OWNERS b/gatekeeper/1.0/software/OWNERS
index c97fba6..d552a9a 100644
--- a/gatekeeper/1.0/software/OWNERS
+++ b/gatekeeper/1.0/software/OWNERS
@@ -1,3 +1,2 @@
 # Bug component: 1124862
-jdanis@google.com
 swillden@google.com
diff --git a/gnss/OWNERS b/gnss/OWNERS
index 57982e7..2c54f9f 100644
--- a/gnss/OWNERS
+++ b/gnss/OWNERS
@@ -2,7 +2,6 @@
 
 gomo@google.com
 smalkos@google.com
-trong@google.com
 wyattriley@google.com
 yim@google.com
 yuhany@google.com
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/AuxiliaryInformation.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/AuxiliaryInformation.aidl
index f6c6cb9..61b510b 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/AuxiliaryInformation.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/AuxiliaryInformation.aidl
@@ -21,6 +21,8 @@
 /**
  * Contains parameters to provide additional information dependent on the GNSS constellation.
  *
+ * If svid is -1, the AuxiliaryInformation is not available.
+ *
  * @hide
  */
 @VintfStability
@@ -49,6 +51,8 @@
      * - QZSS:    183-206
      * - Galileo: 1-36
      * - Beidou:  1-63
+     *
+     * If it is -1, the AuxiliaryInformation is not available.
      */
     int svid;
 
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
index ced8917..65f840c 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
@@ -18,7 +18,9 @@
 
 /**
  * Contains Galileo ionospheric model.
- * This is Defined in Galileo-OS-SIS-ICD-v2.1, 5.1.6.
+ * This is defined in Galileo-OS-SIS-ICD-v2.1, 5.1.6.
+ *
+ * If all coefficients are 0, the GalileoIonosphericModel is not available.
  *
  * @hide
  */
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
index ebf6c05..25e8c4b 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
@@ -20,6 +20,8 @@
  * Contains Glonass almanac data.
  * This is defined in Glonass ICD v5.1, section 4.5.
  *
+ * If issueDateMs is -1, the GlonassAlmanac is not available.
+ *
  * @hide
  */
 @VintfStability
@@ -77,7 +79,10 @@
         double omega;
     }
 
-    /** Almanac issue date in milliseconds (UTC). */
+    /**
+     * Almanac issue date in milliseconds (UTC).
+     * If it is -1, the GlonassAlmanac is not available.
+     */
     long issueDateMs;
 
     /** Array of GlonassSatelliteAlmanac. */
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
index f12378b..e03bbf0 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
@@ -24,6 +24,8 @@
  * For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.6.
  * For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
  *
+ * If weekNumber is -1, the GnssAlmanac is not available.
+ *
  * @hide
  */
 @VintfStability
@@ -44,6 +46,7 @@
 
     /**
      * Almanac reference week number.
+     * If it is -1, the GnssAlmanac is not available.
      *
      * For GPS and QZSS, this is GPS week number (modulo 1024).
      * For Beidou, this is Baidou week number (modulo 8192).
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
index e261e97..c1dba78 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
@@ -20,6 +20,8 @@
  * Contains Klobuchar ionospheric model coefficients used by GPS, BDS, QZSS.
  * This is defined in IS-GPS-200 20.3.3.5.1.7.
  *
+ * If all coefficients are 0, the KlobucharIonosphericModel is not available.
+ *
  * @hide
  */
 @VintfStability
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
index 0ebd46d..d05fba8 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
@@ -20,11 +20,16 @@
  * Contains the leap seconds set of parameters needed for GNSS time.
  * This is defined in RINEX 3.05 "LEAP SECONDS" in table A2.
  *
+ * If leapSeconds is -1, the LeapSecondsModel is not available.
+ *
  * @hide
  */
 @VintfStability
 parcelable LeapSecondsModel {
-    /** Time difference due to leap seconds before the event in seconds. */
+    /**
+     * Time difference due to leap seconds before the event in seconds.
+     * If it is -1, the LeapSecondsModel is not available.
+     */
     int leapSeconds;
 
     /** Time difference due to leap seconds after the event in seconds. */
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl
index c16a711..2b291f0 100644
--- a/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl
@@ -20,6 +20,8 @@
  * Contains parameters to convert from current GNSS time to UTC time.
  * This is defined in RINEX 3.05 "TIME SYSTEM CORR" in table A5.
  *
+ * If weekNumber is -1, the UtcModel is not available.
+ *
  * @hide
  */
 @VintfStability
@@ -33,6 +35,6 @@
     /** Reference GNSS time of week in seconds. */
     int timeOfWeek;
 
-    /** Reference GNSS week number. */
+    /** Reference GNSS week number. If it is -1, the UTC model is not available. */
     int weekNumber;
 }
diff --git a/graphics/OWNERS b/graphics/OWNERS
index 1cb6015..9ba1ee0 100644
--- a/graphics/OWNERS
+++ b/graphics/OWNERS
@@ -5,6 +5,4 @@
 alecmouri@google.com
 chrisforbes@google.com
 jreck@google.com
-lpy@google.com
-scroggo@google.com
-sumir@google.com
\ No newline at end of file
+sumir@google.com
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
index da6001a..f12bce3 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -269,9 +269,7 @@
         auto& data = mReturnData[displayLuts.display];
         for (auto& [layerId, luts] : displayLuts.layerLuts) {
             if (luts.pfd.get() >= 0) {
-                data.layerLuts.push_back(
-                        {layerId, Luts{ndk::ScopedFileDescriptor(dup(luts.pfd.get())), luts.offsets,
-                                       luts.lutProperties}});
+                data.layerLuts.push_back({layerId, std::move(luts)});
             }
         }
     }
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/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 2ff3b2b..6c58b4c 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -3276,7 +3276,7 @@
         invalid_writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
                                                          LayerLifecycleBatchCommandType::DESTROY);
         execute();
-        const auto errors = getReader(display.getDisplayId()).takeErrors();
+        const auto errors = getReader(getInvalidDisplayId()).takeErrors();
         ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
     }
 }
diff --git a/ir/OWNERS b/ir/OWNERS
index 04de9ef..376fe0a 100644
--- a/ir/OWNERS
+++ b/ir/OWNERS
@@ -1,2 +1,2 @@
 # Bug component: 163905
-connoro@google.com
+devinmoore@google.com
\ No newline at end of file
diff --git a/nfc/1.0/default/OWNERS b/nfc/1.0/default/OWNERS
index 5febd1d..e681870 100644
--- a/nfc/1.0/default/OWNERS
+++ b/nfc/1.0/default/OWNERS
@@ -1,2 +1 @@
 rmojumder@google.com
-zachoverflow@google.com
diff --git a/nfc/1.2/vts/OWNERS b/nfc/1.2/vts/OWNERS
index 21d4df1..eeeadd1 100644
--- a/nfc/1.2/vts/OWNERS
+++ b/nfc/1.2/vts/OWNERS
@@ -1,3 +1,2 @@
-zachoverflow@google.com
 jackcwyu@google.com
 georgekgchang@google.com
diff --git a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
index 6db7e14..d3fcbb3 100644
--- a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
+++ b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
@@ -153,8 +153,7 @@
                     SyncEventGuard guard(sNfaVsCommand);
                     sNfaVsCommand.notifyOne();
                 } break;
-                case NCI_ANDROID_SET_PASSIVE_OBSERVER_TECH:
-                case NCI_ANDROID_PASSIVE_OBSERVE: {
+                case NCI_ANDROID_SET_PASSIVE_OBSERVER_TECH: {
                     if (param_len == 5) {
                         if ((p_param[0] & NCI_MT_MASK) == (NCI_MT_RSP << NCI_MT_SHIFT)) {
                             sVSCmdStatus = p_param[4];
@@ -190,36 +189,6 @@
 }
 
 /*
- * Enable passive observe mode.
- */
-tNFA_STATUS static nfaObserveModeEnable(bool enable) {
-    tNFA_STATUS status = NFA_STATUS_FAILED;
-
-    status = NFA_StopRfDiscovery();
-    if (status == NFA_STATUS_OK) {
-        if (!sNfaEnableDisablePollingEvent.wait(1000)) {
-            LOG(WARNING) << "Timeout waiting to disable NFC RF discovery";
-            return NFA_STATUS_TIMEOUT;
-        }
-    }
-
-    uint8_t cmd[] = {NCI_ANDROID_PASSIVE_OBSERVE,
-                     static_cast<uint8_t>(enable ? NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE
-                                                 : NCI_ANDROID_PASSIVE_OBSERVE_PARAM_DISABLE)};
-
-    status = NFA_SendVsCommand(NCI_MSG_PROP_ANDROID, sizeof(cmd), cmd, nfaVSCallback);
-
-    if (status == NFA_STATUS_OK) {
-        if (!sNfaVsCommand.wait(1000)) {
-            LOG(WARNING) << "Timeout waiting for set observe mode command response";
-            return NFA_STATUS_TIMEOUT;
-        }
-    }
-
-    return status;
-}
-
-/*
  * Get observe mode state.
  */
 tNFA_STATUS static nfaQueryObserveModeState() {
@@ -322,71 +291,18 @@
 };
 
 /*
- * ObserveModeEnableDisable:
- * Attempts to enable observe mode. Does not test Observe Mode functionality,
- * but simply verifies that the enable command responds successfully.
- *
- * @VsrTest = GMS-VSR-3.2.8-001
+ * SetPassiveObserverTech_getCaps:
+ * Verifies GET_CAPS returns get correct value for observe mode capabilities.
  */
-TEST_P(NfcBehaviorChanges, ObserveModeEnableDisable) {
-    if (get_vsr_api_level() < 202404) {
-        GTEST_SKIP() << "Skipping test for board API level < 202404";
-    }
-
-    tNFA_STATUS status = nfaObserveModeEnable(true);
-    ASSERT_EQ(status, NFA_STATUS_OK);
-
-    status = nfaQueryObserveModeState();
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    ASSERT_NE(sObserveModeState, 0);
-
-    status = nfaObserveModeEnable(false);
-    ASSERT_EQ(status, NFA_STATUS_OK);
-
-    status = nfaQueryObserveModeState();
-    ASSERT_EQ(status, NFA_STATUS_OK);
-    ASSERT_EQ(sObserveModeState, 0);
-}
-
-/*
- * 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
- */
-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/1.0/vts/OWNERS b/power/1.0/vts/OWNERS
index 6de2cd5..53948b9 100644
--- a/power/1.0/vts/OWNERS
+++ b/power/1.0/vts/OWNERS
@@ -1,2 +1 @@
 # Bug component: 158088
-connoro@google.com
diff --git a/power/1.1/vts/functional/OWNERS b/power/1.1/vts/functional/OWNERS
index 6de2cd5..53948b9 100644
--- a/power/1.1/vts/functional/OWNERS
+++ b/power/1.1/vts/functional/OWNERS
@@ -1,2 +1 @@
 # Bug component: 158088
-connoro@google.com
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/power/stats/1.0/default/OWNERS b/power/stats/1.0/default/OWNERS
index 2d95a97..0557220 100644
--- a/power/stats/1.0/default/OWNERS
+++ b/power/stats/1.0/default/OWNERS
@@ -1,3 +1,2 @@
 krossmo@google.com
 bsschwar@google.com
-tstrudel@google.com
diff --git a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
index 9588ed9..7cde897 100644
--- a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
@@ -52,7 +52,7 @@
     /** @deprecated use LTE instead. */
     LTE_CA = 1 << RadioTechnology.LTE_CA,
     /**
-     * 5G NR. This is only use in 5G Standalone mode.
+     * 5G NR. This is only used in 5G Standalone mode.
      */
     NR = 1 << RadioTechnology.NR,
 }
diff --git a/radio/aidl/android/hardware/radio/RadioError.aidl b/radio/aidl/android/hardware/radio/RadioError.aidl
index 6a28893..aa53df3 100644
--- a/radio/aidl/android/hardware/radio/RadioError.aidl
+++ b/radio/aidl/android/hardware/radio/RadioError.aidl
@@ -73,7 +73,7 @@
      */
     MODE_NOT_SUPPORTED = 13,
     /**
-     * Command failed becausee recipient is not on FDN list
+     * Command failed because recipient is not on FDN list
      */
     FDN_CHECK_FAILURE = 14,
     /**
@@ -133,7 +133,7 @@
      */
     LCE_NOT_SUPPORTED = 36,
     /**
-     * Not sufficieent memory to process the request
+     * Not sufficient memory to process the request
      */
     NO_MEMORY = 37,
     /**
@@ -218,7 +218,7 @@
      */
     ENCODING_ERR = 57,
     /**
-     * SMSC addrss specified is invalid
+     * SMSC address specified is invalid
      */
     INVALID_SMSC_ADDRESS = 58,
     /**
@@ -279,7 +279,7 @@
     OEM_ERROR_24 = 524,
     OEM_ERROR_25 = 525,
     /**
-     * 1X voice and SMS are not allowed simulteneously.
+     * 1X voice and SMS are not allowed simultaneously.
      */
     SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED = 67,
     /**
@@ -293,8 +293,8 @@
     BLOCKED_DUE_TO_CALL = 69,
     /**
      * Returned from setRadioPowerResponse when detecting RF HW issues. Some RF Front-End (RFFE)
-     * components like antenna are considered critical for modem to provide telephony service.
-     * This RadioError is used when modem detect such RFFE problem.
+     * components like antennas are considered critical for modem to provide telephony service.
+     * This RadioError is used when modem detects such RFFE problems.
      */
     RF_HARDWARE_ISSUE = 70,
     /**
diff --git a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
index 592fde6..733eae8 100644
--- a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
@@ -143,7 +143,7 @@
      */
     DATA_REGISTRATION_FAIL = -2,
     /**
-     * Network/modem disonnect
+     * Network/modem disconnect
      */
     SIGNAL_LOST = -3,
     /**
@@ -172,7 +172,7 @@
     ACTIVATION_REJECTED_BCM_VIOLATION = 0x30,
     /**
      * Network has already initiated the activation, modification, or deactivation of bearer
-     * resources that was requested by the UE.
+     * resources that were requested by the UE.
      */
     COLLISION_WITH_NETWORK_INITIATED_REQUEST = 0x38,
     /**
@@ -182,7 +182,7 @@
      */
     ONLY_IPV4V6_ALLOWED = 0x39,
     /**
-     * Network supports non-IP PDP type only. IPv4, IPv6 and IPv4v6 is not allowed. In LTE mode of
+     * Network supports non-IP PDP type only. IPv4, IPv6 and IPv4v6 are not allowed. In LTE mode of
      * operation, this is a PDN throttling cause code, meaning the UE can throttle further requests
      * to the same APN.
      */
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index 8a5f1df..260628c 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -41,7 +41,7 @@
     const int TYPE_3GPP2 = 2;
 
     /**
-     * Innfrastructure type unknown. This is only for initializing.
+     * Infrastructure type unknown. This is only for initializing.
      */
     const int INFRASTRUCTURE_UNKNOWN = 0;
 
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
index 538b90a..7624606 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataResponse.aidl
@@ -29,7 +29,7 @@
 oneway interface IRadioDataResponse {
     /**
      * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond. For more details, refer
+     * radio requests which take a long time to respond. For more details, refer
      * https://source.android.com/devices/tech/connect/ril.html
      *
      * @param serial Serial no. of the request whose acknowledgement is sent.
@@ -199,7 +199,7 @@
      *   RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:INTERNAL_ERR
-     *   RadioError:NO_RESOURCES if the vendor is unable handle due to resources are full.
+     *   RadioError:NO_RESOURCES if the vendor is unable to handle due to resources being full.
      *   RadioError:SIM_ABSENT
      */
     void setupDataCallResponse(in RadioResponseInfo info, in SetupDataCallResult dcResponse);
diff --git a/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
index c67b3b7..1d90b8f 100644
--- a/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
+++ b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
@@ -59,7 +59,7 @@
     int maxKeepaliveIntervalMillis;
     /**
      * Context ID, returned in setupDataCallResponse that uniquely identifies the data call to which
-     * this keepalive must applied.
+     * this keepalive must be applied.
      */
     int cid;
 }
diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
index 498f228..fc9a4e1 100644
--- a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
+++ b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
@@ -30,7 +30,7 @@
 oneway interface IRadioModemResponse {
     /**
      * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond. For more details, refer
+     * radio requests which take a long time to respond. For more details, refer
      * https://source.android.com/devices/tech/connect/ril.html
      *
      * @param serial Serial no. of the request whose acknowledgement is sent.
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index dce9865..13d9a9a 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -495,7 +495,7 @@
      * Requests that network personalization be deactivated
      *
      * @param serial Serial number of request.
-     * @param netPin Network depersonlization code
+     * @param netPin Network depersonalization code
      *
      * Response function is IRadioNetworkResponse.supplyNetworkDepersonalizationResponse()
      *
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index 295061b..d7d351c 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -137,7 +137,7 @@
      *        the framework
      * @param ageMs time in milliseconds indicating how long NITZ was cached in RIL and modem.
      *        This must track true age and therefore must be calculated using clocks that
-     *        include the time spend in sleep / low power states. If it can not be guaranteed,
+     *        include the time spent in sleep / low power states. If it can not be guaranteed,
      *        there must not be any caching done at the modem and should fill in 0 for ageMs
      */
     void nitzTimeReceived(
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index fd332fc..9a89181 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -39,7 +39,7 @@
 oneway interface IRadioNetworkResponse {
     /**
      * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond. For more details, refer
+     * radio requests which take a long time to respond. For more details, refer
      * https://source.android.com/devices/tech/connect/ril.html
      *
      * @param serial Serial no. of the request whose acknowledgement is sent.
diff --git a/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl b/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
index 133526e..a4ae13a 100644
--- a/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
+++ b/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
@@ -26,7 +26,7 @@
      * capacity of both primary and secondary. This bandwidth estimate shall be the estimated
      * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
      * If the DL Aggregate Maximum Bit Rate is known, this value shall not exceed the DL-AMBR for
-     * the Internet PDN connection. This must be filled with 0 if network is not connected.
+     * the Internet PDN connection. This must be filled with 0 if the network is not connected.
      */
     int downlinkCapacityKbps;
     /**
@@ -34,14 +34,14 @@
      * capacity of both primary and secondary. This bandwidth estimate shall be the estimated
      * maximum sustainable link bandwidth (as would be measured at the Upper PDCP or SNDCP SAP).
      * If the UL Aggregate Maximum Bit Rate is known, this value shall not exceed the UL-AMBR for
-     * the Internet PDN connection. This must be filled with 0 if network is not connected.
+     * the Internet PDN connection. This must be filled with 0 if the network is not connected.
      */
     int uplinkCapacityKbps;
     /**
      * Estimated downlink capacity of secondary carrier in a dual connected NR mode in kbps. This
      * bandwidth estimate shall be the estimated maximum sustainable link bandwidth (as would be
      * measured at the Upper PDCP or SNDCP SAP). This is valid only in if device is connected to
-     * both primary and secodary in dual connected mode. This must be filled with 0 if secondary is
+     * both primary and secondary in dual connected mode. This must be filled with 0 if secondary is
      * not connected or if modem does not support this feature.
      */
     int secondaryDownlinkCapacityKbps;
@@ -49,7 +49,7 @@
      * Estimated uplink capacity secondary carrier in a dual connected NR mode in kbps. This
      * bandwidth estimate shall be the estimated maximum sustainable link bandwidth (as would be
      * measured at the Upper PDCP or SNDCP SAP). This is valid only in if device is connected to
-     * both primary and secodary in dual connected mode.This must be filled with 0 if secondary is
+     * both primary and secondary in dual connected mode.This must be filled with 0 if secondary is
      * not connected or if modem does not support this feature.
      */
     int secondaryUplinkCapacityKbps;
diff --git a/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl b/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
index a1984e9..73cf389 100644
--- a/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
@@ -26,19 +26,19 @@
 @RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable LteVopsInfo {
     /**
-     * This indicates if camped network support VoLTE services. This information is received from
+     * This indicates if the camped network supports VoLTE services. This information is received from
      * LTE network during LTE NAS registration procedure through LTE ATTACH ACCEPT/TAU ACCEPT.
      * Refer 3GPP 24.301 EPS network feature support -> IMS VoPS
      */
     boolean isVopsSupported;
     /**
-     * This indicates if camped network support VoLTE emergency bearers. This information is
+     * This indicates if the camped network supports VoLTE emergency bearers. This information is
      * received from LTE network through two sources:
      * a. During LTE NAS registration procedure through LTE ATTACH ACCEPT/TAU ACCEPT. Refer
      *    3GPP 24.301 EPS network feature support -> EMC BS
-     * b. In case device is not registered on network. Refer 3GPP 25.331 LTE RRC
+     * b. In case the device is not registered on network. Refer 3GPP 25.331 LTE RRC
      *    SIB1 : ims-EmergencySupport-r9
-     * If device is registered on LTE, then this field indicates (a).
+     * If the device is registered on LTE, then this field indicates (a).
      * In case of limited service on LTE this field indicates (b).
      */
     boolean isEmcBearerSupported;
diff --git a/radio/aidl/android/hardware/radio/network/RegState.aidl b/radio/aidl/android/hardware/radio/network/RegState.aidl
index 15e7160..1cfa2c1 100644
--- a/radio/aidl/android/hardware/radio/network/RegState.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegState.aidl
@@ -56,7 +56,7 @@
      */
     NOT_REG_MT_NOT_SEARCHING_OP_EM = 10,
     /**
-     * Same as NOT_REG_MT_SEARCHING_OP but indicatees that emergency calls are enabled
+     * Same as NOT_REG_MT_SEARCHING_OP but indicates that emergency calls are enabled
      */
     NOT_REG_MT_SEARCHING_OP_EM = 12,
     /**
diff --git a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
index f820109..9158258 100644
--- a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
@@ -27,7 +27,7 @@
 @RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CardStatus {
     /*
-     * Card is physically absent from device. (Some old modems use STATE_ABSENT when the SIM
+     * Card is physically absent from the device. (Some old modems use STATE_ABSENT when the SIM
      * is powered off. This is no longer correct, however the platform will still support this
      * legacy behavior.)
      */
@@ -76,7 +76,7 @@
      */
     String atr;
     /**
-     * Integrated Circuit Card IDentifier (ICCID) is Unique Identifier of the SIM CARD. File is
+     * Integrated Circuit Card IDentifier (ICCID) is the Unique Identifier of the SIM CARD. File is
      * located in the SIM card at EFiccid (0x2FE2) as per ETSI 102.221. The ICCID is defined by
      * the ITU-T recommendation E.118 ISO/IEC 7816.
      *
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index 16573f4..7ad8c77 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -389,7 +389,7 @@
 
     /**
      * Provide Carrier specific information to the modem that must be used to encrypt the IMSI and
-     * IMPI. Sent by the framework during boot, carrier switch and everytime the framework receives
+     * IMPI. Sent by the framework during boot, carrier switch and every time the framework receives
      * a new certificate.
      *
      * @param serial Serial number of request.
@@ -583,7 +583,7 @@
      * Close a previously opened logical channel. This command reflects TS 27.007
      * "close logical channel" operation (+CCHC).
      *
-     * Per spec SGP.22 V3.0, ES10 commands needs to be sent over command port of MEP-A. In order
+     * Per spec SGP.22 V3.0, ES10 commands need to be sent over command port of MEP-A. In order
      * to close proper logical channel, should pass information about whether the logical channel
      * was opened for sending ES10 commands or not.
      *
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl
index d9735d3..7967b6b 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl
@@ -30,7 +30,7 @@
 oneway interface IRadioSimIndication {
     /**
      * Indicates that the modem requires the Carrier info for IMSI/IMPI encryption. This might
-     * happen when the modem restarts or for some reason it's cache has been invalidated.
+     * happen when the modem restarts or for some reason its cache has been invalidated.
      *
      * @param type Type of radio indication
      */
@@ -85,7 +85,7 @@
     void simStatusChanged(in RadioIndicationType type);
 
     /**
-     * Indicates when SIM notifies applcations some event happens.
+     * Indicates when SIM notifies applications some event happens.
      *
      * @param type Type of radio indication
      * @param cmd SAT/USAT commands or responses sent by ME to SIM or commands handled by ME,
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
index 62fa674..5c31bd2 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -33,7 +33,7 @@
 oneway interface IRadioSimResponse {
     /**
      * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond. For more details, refer
+     * radio requests which take a long time to respond. For more details, refer
      * https://source.android.com/devices/tech/connect/ril.html
      *
      * @param serial Serial no. of the request whose acknowledgement is sent.
@@ -629,7 +629,7 @@
     /**
      * @param info Response info struct containing response type, serial no. and error
      * @param persoType SIM Personalization type
-     * @param remainingRetries postiive values indicates number of retries remaining, must be equal
+     * @param remainingRetries positive values indicates number of retries remaining, must be equal
      *        to -1 if number of retries is infinite.
      *
      * Valid errors returned:
diff --git a/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
index 618ac32..88c4552 100644
--- a/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
@@ -45,9 +45,9 @@
     /**
      * AID (application ID) of the card application. See ETSI 102.221 8.1 and 101.220 4.
      * For TYPE_SIM_FILE_UPDATE result, it must be set to AID of application in which updated EF
-     * resides or it must be empty string if EF is outside of an application. For TYPE_SIM_INIT
+     * resides or it must be an empty string if EF is outside of an application. For TYPE_SIM_INIT
      * result, this field is set to AID of application that caused REFRESH. For TYPE_SIM_RESET
-     * result, it is empty string.
+     * result, it is an empty string.
      */
     String aid;
 }
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
index e7214e5..c4a26a3 100644
--- a/radio/aidl/vts/radio_config_test.cpp
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -54,11 +54,9 @@
  * Test IRadioConfig.getHalDeviceCapabilities() for the response returned.
  */
 TEST_P(RadioConfigTest, getHalDeviceCapabilities) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping getHalDeviceCapabilities "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping getHalDeviceCapabilities "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
@@ -73,11 +71,9 @@
  * Test IRadioConfig.getSimSlotsStatus() for the response returned.
  */
 TEST_P(RadioConfigTest, getSimSlotsStatus) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping getSimSlotsStatus "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping getSimSlotsStatus "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -92,11 +88,9 @@
  * Test IRadioConfig.getPhoneCapability() for the response returned.
  */
 TEST_P(RadioConfigTest, getPhoneCapability) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping getPhoneCapability "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping getPhoneCapability "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
@@ -125,11 +119,9 @@
  * Test IRadioConfig.getSimultaneousCallingSupport() for the response returned.
  */
 TEST_P(RadioConfigTest, getSimultaneousCallingSupport) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping getSimultaneousCallingSupport "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping getSimultaneousCallingSupport "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     int32_t aidl_version;
@@ -167,11 +159,9 @@
  * Test IRadioConfig.setPreferredDataModem() for the response returned.
  */
 TEST_P(RadioConfigTest, setPreferredDataModem) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping setPreferredDataModem "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping setPreferredDataModem "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -216,11 +206,9 @@
  * Test IRadioConfig.setPreferredDataModem() with invalid arguments.
  */
 TEST_P(RadioConfigTest, setPreferredDataModem_invalidArgument) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping setPreferredDataModem_invalidArgument "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping setPreferredDataModem_invalidArgument "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -243,11 +231,9 @@
  * Test IRadioConfig.setSimSlotsMapping() for the response returned.
  */
 TEST_P(RadioConfigTest, setSimSlotsMapping) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping setSimSlotsMapping "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping setSimSlotsMapping "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     // get slot status and set SIM slots mapping based on the result.
@@ -318,11 +304,9 @@
  */
 
 TEST_P(RadioConfigTest, checkPortInfoExistsAndPortActive) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping checkPortInfoExistsAndPortActive "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping checkPortInfoExistsAndPortActive "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
diff --git a/radio/aidl/vts/radio_data_test.cpp b/radio/aidl/vts/radio_data_test.cpp
index 2aa5508..7de0187 100644
--- a/radio/aidl/vts/radio_data_test.cpp
+++ b/radio/aidl/vts/radio_data_test.cpp
@@ -68,10 +68,8 @@
  * Test IRadioData.setupDataCall() for the response returned.
  */
 TEST_P(RadioDataTest, setupDataCall) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "setupDataCall : required FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "setupDataCall : required FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -141,11 +139,9 @@
  * Test IRadioData.setupDataCall() with osAppId for the response returned.
  */
 TEST_P(RadioDataTest, setupDataCall_osAppId) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping setupDataCall_osAppId "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping setupDataCall_osAppId "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -240,11 +236,9 @@
  * Test IRadioData.getSlicingConfig() for the response returned.
  */
 TEST_P(RadioDataTest, getSlicingConfig) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping getSlicingConfig "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping getSlicingConfig "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -262,11 +256,9 @@
  * Test IRadioData.setDataThrottling() for the response returned.
  */
 TEST_P(RadioDataTest, setDataThrottling) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping setDataThrottling "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping setDataThrottling "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -347,11 +339,9 @@
  * Test IRadioData.setInitialAttachApn() for the response returned.
  */
 TEST_P(RadioDataTest, setInitialAttachApn) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping setInitialAttachApn "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping setInitialAttachApn "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -397,11 +387,9 @@
  * Test IRadioData.setDataProfile() for the response returned.
  */
 TEST_P(RadioDataTest, setDataProfile) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping setDataProfile "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping setDataProfile "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -450,11 +438,9 @@
  * Test IRadioData.deactivateDataCall() for the response returned.
  */
 TEST_P(RadioDataTest, deactivateDataCall) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping deactivateDataCall "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping deactivateDataCall "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -488,11 +474,9 @@
  * Test IRadioData.startKeepalive() for the response returned.
  */
 TEST_P(RadioDataTest, startKeepalive) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping startKeepalive "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping startKeepalive "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     std::vector<KeepaliveRequest> requests = {
@@ -593,11 +577,9 @@
  * Test IRadioData.stopKeepalive() for the response returned.
  */
 TEST_P(RadioDataTest, stopKeepalive) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping stopKeepalive "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping stopKeepalive "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -616,11 +598,9 @@
  * Test IRadioData.getDataCallList() for the response returned.
  */
 TEST_P(RadioDataTest, getDataCallList) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping getDataCallList "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping getDataCallList "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
@@ -642,11 +622,9 @@
  * Test IRadioData.setDataAllowed() for the response returned.
  */
 TEST_P(RadioDataTest, setDataAllowed) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
-            GTEST_SKIP() << "Skipping setDataAllowed "
-                            "due to undefined FEATURE_TELEPHONY_DATA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_DATA)) {
+        GTEST_SKIP() << "Skipping setDataAllowed "
+                        "due to undefined FEATURE_TELEPHONY_DATA";
     }
 
     serial = GetRandomSerialNumber();
diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp
index 95e2617..089895f 100644
--- a/radio/aidl/vts/radio_messaging_test.cpp
+++ b/radio/aidl/vts/radio_messaging_test.cpp
@@ -59,11 +59,9 @@
  * Test IRadioMessaging.sendSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendSms) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping sendSms "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping sendSms "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -90,11 +88,9 @@
  * Test IRadioMessaging.sendSmsExpectMore() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendSmsExpectMore) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping sendSmsExpectMore "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping sendSmsExpectMore "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -120,11 +116,9 @@
  * Test IRadioMessaging.sendCdmaSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendCdmaSms) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping sendCdmaSms "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping sendCdmaSms "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -171,11 +165,9 @@
  * Test IRadioMessaging.sendCdmaSmsExpectMore() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendCdmaSmsExpectMore) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping sendCdmaSmsExpectMore "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping sendCdmaSmsExpectMore "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -222,11 +214,9 @@
  * Test IRadioMessaging.setGsmBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, setGsmBroadcastConfig) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping setGsmBroadcastConfig "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping setGsmBroadcastConfig "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -292,11 +282,9 @@
  * Test IRadioMessaging.getGsmBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, getGsmBroadcastConfig) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping getGsmBroadcastConfig "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping getGsmBroadcastConfig "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -319,11 +307,9 @@
  * Test IRadioMessaging.setCdmaBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, setCdmaBroadcastConfig) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping setCdmaBroadcastConfig "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping setCdmaBroadcastConfig "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -352,11 +338,9 @@
  * Test IRadioMessaging.getCdmaBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, getCdmaBroadcastConfig) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping getCdmaBroadcastConfig "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping getCdmaBroadcastConfig "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -377,11 +361,9 @@
  * Test IRadioMessaging.setCdmaBroadcastActivation() for the response returned.
  */
 TEST_P(RadioMessagingTest, setCdmaBroadcastActivation) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping setCdmaBroadcastActivation "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping setCdmaBroadcastActivation "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -404,11 +386,9 @@
  * Test IRadioMessaging.setGsmBroadcastActivation() for the response returned.
  */
 TEST_P(RadioMessagingTest, setGsmBroadcastActivation) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping setGsmBroadcastActivation "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping setGsmBroadcastActivation "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -433,11 +413,9 @@
  * Test IRadioMessaging.acknowledgeLastIncomingGsmSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, acknowledgeLastIncomingGsmSms) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping acknowledgeLastIncomingGsmSms "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping acknowledgeLastIncomingGsmSms "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -461,11 +439,9 @@
  * Test IRadioMessaging.acknowledgeIncomingGsmSmsWithPdu() for the response returned.
  */
 TEST_P(RadioMessagingTest, acknowledgeIncomingGsmSmsWithPdu) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping acknowledgeIncomingGsmSmsWithPdu "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping acknowledgeIncomingGsmSmsWithPdu "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -489,11 +465,9 @@
  * Test IRadioMessaging.acknowledgeLastIncomingCdmaSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, acknowledgeLastIncomingCdmaSms) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping acknowledgeIncomingGsmSmsWithPdu "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping acknowledgeIncomingGsmSmsWithPdu "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -520,11 +494,9 @@
  * Test IRadioMessaging.sendImsSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendImsSms) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
-            GTEST_SKIP() << "Skipping acknowledgeIncomingGsmSmsWithPdu "
-                            "due to undefined FEATURE_TELEPHONY_IMS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        GTEST_SKIP() << "Skipping acknowledgeIncomingGsmSmsWithPdu "
+                        "due to undefined FEATURE_TELEPHONY_IMS";
     }
 
     serial = GetRandomSerialNumber();
@@ -577,11 +549,9 @@
  * Test IRadioMessaging.getSmscAddress() for the response returned.
  */
 TEST_P(RadioMessagingTest, getSmscAddress) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping getSmscAddress "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping getSmscAddress "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -604,11 +574,9 @@
  * Test IRadioMessaging.setSmscAddress() for the response returned.
  */
 TEST_P(RadioMessagingTest, setSmscAddress) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping setSmscAddress "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping setSmscAddress "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -632,11 +600,9 @@
  * Test IRadioMessaging.writeSmsToSim() for the response returned.
  */
 TEST_P(RadioMessagingTest, writeSmsToSim) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping writeSmsToSim "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping writeSmsToSim "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -665,11 +631,9 @@
  * Test IRadioMessaging.deleteSmsOnSim() for the response returned.
  */
 TEST_P(RadioMessagingTest, deleteSmsOnSim) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping deleteSmsOnSim "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping deleteSmsOnSim "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
@@ -695,11 +659,9 @@
  * Test IRadioMessaging.writeSmsToRuim() for the response returned.
  */
 TEST_P(RadioMessagingTest, writeSmsToRuim) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping writeSmsToRuim "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping writeSmsToRuim "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -753,11 +715,9 @@
  * Test IRadioMessaging.deleteSmsOnRuim() for the response returned.
  */
 TEST_P(RadioMessagingTest, deleteSmsOnRuim) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping deleteSmsOnRuim "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping deleteSmsOnRuim "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -811,11 +771,9 @@
  * Test IRadioMessaging.reportSmsMemoryStatus() for the response returned.
  */
 TEST_P(RadioMessagingTest, reportSmsMemoryStatus) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
-            GTEST_SKIP() << "Skipping reportSmsMemoryStatus "
-                            "due to undefined FEATURE_TELEPHONY_MESSAGING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_MESSAGING)) {
+        GTEST_SKIP() << "Skipping reportSmsMemoryStatus "
+                        "due to undefined FEATURE_TELEPHONY_MESSAGING";
     }
 
     serial = GetRandomSerialNumber();
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index 98ea0d2..9fb7db8 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -68,11 +68,9 @@
  * Test IRadioModem.setRadioPower() for the response returned.
  */
 TEST_P(RadioModemTest, setRadioPower_emergencyCall_cancelled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setRadioPower_emergencyCall_cancelled "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setRadioPower_emergencyCall_cancelled "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     // Set radio power to off.
@@ -106,11 +104,9 @@
  * Test IRadioModem.enableModem() for the response returned.
  */
 TEST_P(RadioModemTest, enableModem) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping enableModem "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping enableModem "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
@@ -157,11 +153,9 @@
  * Test IRadioModem.getModemStackStatus() for the response returned.
  */
 TEST_P(RadioModemTest, getModemStackStatus) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping getModemStackStatus "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping getModemStackStatus "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
@@ -182,11 +176,9 @@
  * Test IRadioModem.getBasebandVersion() for the response returned.
  */
 TEST_P(RadioModemTest, getBasebandVersion) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping getBasebandVersion "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping getBasebandVersion "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
@@ -205,11 +197,9 @@
  * Test IRadioModem.getDeviceIdentity() for the response returned.
  */
 TEST_P(RadioModemTest, getDeviceIdentity) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping getDeviceIdentity "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping getDeviceIdentity "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
@@ -298,11 +288,9 @@
  * Test IRadioModem.nvWriteCdmaPrl() for the response returned.
  */
 TEST_P(RadioModemTest, nvWriteCdmaPrl) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping nvWriteCdmaPrl "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping nvWriteCdmaPrl "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -342,11 +330,9 @@
  * Test IRadioModem.getHardwareConfig() for the response returned.
  */
 TEST_P(RadioModemTest, getHardwareConfig) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping getHardwareConfig "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping getHardwareConfig "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
@@ -368,11 +354,9 @@
  * Test IRadioModem.requestShutdown() for the response returned.
  */
 TEST_P(RadioModemTest, DISABLED_requestShutdown) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping DISABLED_requestShutdown "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping DISABLED_requestShutdown "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -392,11 +376,9 @@
  * Test IRadioModem.getRadioCapability() for the response returned.
  */
 TEST_P(RadioModemTest, getRadioCapability) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getRadioCapability "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getRadioCapability "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -415,11 +397,9 @@
  * Test IRadioModem.setRadioCapability() for the response returned.
  */
 TEST_P(RadioModemTest, setRadioCapability) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setRadioCapability "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setRadioCapability "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
@@ -443,11 +423,9 @@
  * Test IRadioModem.getModemActivityInfo() for the response returned.
  */
 TEST_P(RadioModemTest, getModemActivityInfo) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getModemActivityInfo "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getModemActivityInfo "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -467,11 +445,9 @@
  * Test IRadioModem.sendDeviceState() for the response returned.
  */
 TEST_P(RadioModemTest, sendDeviceState) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping sendDeviceState "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping sendDeviceState "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     serial = GetRandomSerialNumber();
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 439d268..ff231db 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -98,11 +98,9 @@
  * for the response returned.
  */
 TEST_P(RadioNetworkTest, setGetAllowedNetworkTypesBitmap) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setGetAllowedNetworkTypesBitmap "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setGetAllowedNetworkTypesBitmap "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -167,11 +165,9 @@
  * Test IRadioNetwork.setNrDualConnectivityState() for the response returned.
  */
 TEST_P(RadioNetworkTest, setNrDualConnectivityState) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setNrDualConnectivityState "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setNrDualConnectivityState "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -198,11 +194,9 @@
  * Test IRadioNetwork.isNrDualConnectivityEnabled() for the response returned.
  */
 TEST_P(RadioNetworkTest, isNrDualConnectivityEnabled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping isNrDualConnectivityEnabled "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping isNrDualConnectivityEnabled "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -243,11 +237,9 @@
  * Verify that the usage setting can be retrieved.
  */
 TEST_P(RadioNetworkTest, getUsageSetting) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping getUsageSetting "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping getUsageSetting "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
@@ -289,11 +281,9 @@
  * -That the usage setting cannot be set to invalid values.
  */
 TEST_P(RadioNetworkTest, setUsageSetting) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
-            GTEST_SKIP() << "Skipping setUsageSetting "
-                            "due to undefined FEATURE_TELEPHONY";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY)) {
+        GTEST_SKIP() << "Skipping setUsageSetting "
+                        "due to undefined FEATURE_TELEPHONY";
     }
 
     invokeAndExpectResponse([&](int serial) { return radio_network->getUsageSetting(serial); },
@@ -358,11 +348,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() with invalid hysteresisDb
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_invalidHysteresisDb) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_invalidHysteresisDb "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_invalidHysteresisDb "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -391,11 +379,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() with empty thresholds
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_EmptyThresholds) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_EmptyThresholds "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_EmptyThresholds "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -423,11 +409,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for GERAN
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Geran) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Geran "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Geran "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -457,11 +441,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for UTRAN
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran_Rscp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Utran_Rscp "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Utran_Rscp "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -490,11 +472,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for UTRAN
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Utran_Ecno) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Utran_Ecno "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Utran_Ecno "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -524,11 +504,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSRP) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Eutran_RSRP "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Eutran_RSRP "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -557,11 +535,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSRQ) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Eutran_RSRQ "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Eutran_RSRQ "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -590,11 +566,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Eutran_RSSNR) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Eutran_RSSNR "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Eutran_RSSNR "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -619,11 +593,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for CDMA2000
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Cdma2000) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Cdma2000 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Cdma2000 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
@@ -657,11 +629,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSRSRP
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSRSRP) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_NGRAN_SSRSRP "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_NGRAN_SSRSRP "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -694,11 +664,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSRSRQ
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSRSRQ) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_NGRAN_SSRSRQ "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_NGRAN_SSRSRQ "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -731,11 +699,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for EUTRAN
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Disable_RSSNR) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Disable_RSSNR "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Disable_RSSNR "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -760,11 +726,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSSINR
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSSINR) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_NGRAN_SSSINR "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_NGRAN_SSSINR "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -797,11 +761,9 @@
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for multi-RANs per request
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_multiRansPerRequest) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_multiRansPerRequest "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_multiRansPerRequest "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     SignalThresholdInfo signalThresholdInfoGeran;
@@ -890,11 +852,9 @@
  * Test IRadioNetwork.setLinkCapacityReportingCriteria() invalid hysteresisDlKbps
  */
 TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_invalidHysteresisDlKbps) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setLinkCapacityReportingCriteria_invalidHysteresisDlKbps "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setLinkCapacityReportingCriteria_invalidHysteresisDlKbps "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -917,11 +877,9 @@
  * Test IRadioNetwork.setLinkCapacityReportingCriteria() invalid hysteresisUlKbps
  */
 TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_invalidHysteresisUlKbps) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setLinkCapacityReportingCriteria_invalidHysteresisUlKbps "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setLinkCapacityReportingCriteria_invalidHysteresisUlKbps "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -943,11 +901,9 @@
  * Test IRadioNetwork.setLinkCapacityReportingCriteria() empty params
  */
 TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_emptyParams) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setLinkCapacityReportingCriteria_emptyParams "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setLinkCapacityReportingCriteria_emptyParams "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -968,11 +924,9 @@
  * Test IRadioNetwork.setLinkCapacityReportingCriteria() for GERAN
  */
 TEST_P(RadioNetworkTest, setLinkCapacityReportingCriteria_Geran) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setLinkCapacityReportingCriteria_Geran "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setLinkCapacityReportingCriteria_Geran "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -997,11 +951,9 @@
  * Test IRadioNetwork.setSystemSelectionChannels() for the response returned.
  */
 TEST_P(RadioNetworkTest, setSystemSelectionChannels) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setSystemSelectionChannels "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setSystemSelectionChannels "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1047,11 +999,9 @@
  * Test IRadioNetwork.startNetworkScan() for the response returned.
  */
 TEST_P(RadioNetworkTest, startNetworkScan) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1070,6 +1020,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
 
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::SIM_ABSENT}));
@@ -1096,11 +1049,9 @@
  * Test IRadioNetwork.startNetworkScan() with invalid specifier.
  */
 TEST_P(RadioNetworkTest, startNetworkScan_InvalidArgument) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_InvalidArgument "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_InvalidArgument "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     // get aidl version
@@ -1124,6 +1075,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
 
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
@@ -1169,11 +1123,9 @@
  * Test IRadioNetwork.startNetworkScan() with invalid interval (lower boundary).
  */
 TEST_P(RadioNetworkTest, startNetworkScan_InvalidInterval1) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_InvalidInterval1 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_InvalidInterval1 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1192,6 +1144,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
@@ -1205,11 +1160,9 @@
  * Test IRadioNetwork.startNetworkScan() with invalid interval (upper boundary).
  */
 TEST_P(RadioNetworkTest, startNetworkScan_InvalidInterval2) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_InvalidInterval2 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_InvalidInterval2 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1228,6 +1181,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
@@ -1241,11 +1197,9 @@
  * Test IRadioNetwork.startNetworkScan() with invalid max search time (lower boundary).
  */
 TEST_P(RadioNetworkTest, startNetworkScan_InvalidMaxSearchTime1) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_InvalidMaxSearchTime1 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_InvalidMaxSearchTime1 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1264,6 +1218,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
@@ -1277,11 +1234,9 @@
  * Test IRadioNetwork.startNetworkScan() with invalid max search time (upper boundary).
  */
 TEST_P(RadioNetworkTest, startNetworkScan_InvalidMaxSearchTime2) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_InvalidMaxSearchTime2 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_InvalidMaxSearchTime2 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1300,6 +1255,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
@@ -1313,11 +1271,9 @@
  * Test IRadioNetwork.startNetworkScan() with invalid periodicity (lower boundary).
  */
 TEST_P(RadioNetworkTest, startNetworkScan_InvalidPeriodicity1) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_InvalidPeriodicity1 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_InvalidPeriodicity1 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1336,6 +1292,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
@@ -1349,11 +1308,9 @@
  * Test IRadioNetwork.startNetworkScan() with invalid periodicity (upper boundary).
  */
 TEST_P(RadioNetworkTest, startNetworkScan_InvalidPeriodicity2) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_InvalidPeriodicity2 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_InvalidPeriodicity2 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1372,6 +1329,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
@@ -1385,11 +1345,9 @@
  * Test IRadioNetwork.startNetworkScan() with valid periodicity
  */
 TEST_P(RadioNetworkTest, startNetworkScan_GoodRequest1) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_GoodRequest1 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_GoodRequest1 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1408,6 +1366,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_GoodRequest1, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::NONE, RadioError::SIM_ABSENT}));
@@ -1426,11 +1387,9 @@
  * Test IRadioNetwork.startNetworkScan() with valid periodicity and plmns
  */
 TEST_P(RadioNetworkTest, startNetworkScan_GoodRequest2) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping startNetworkScan_GoodRequest2 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping startNetworkScan_GoodRequest2 "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1450,6 +1409,9 @@
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
     ALOGI("startNetworkScan_GoodRequest2, rspInfo.error = %s\n",
           toString(radioRsp_network->rspInfo.error).c_str());
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping startNetworkScan because it's not supported";
+    }
     if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
         ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
                                      {RadioError::NONE, RadioError::SIM_ABSENT}));
@@ -1468,11 +1430,9 @@
  * Test IRadioNetwork.setNetworkSelectionModeManual() for the response returned.
  */
 TEST_P(RadioNetworkTest, setNetworkSelectionModeManual) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setNetworkSelectionModeManual "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setNetworkSelectionModeManual "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1488,18 +1448,17 @@
             radioRsp_network->rspInfo.error,
             {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::INVALID_ARGUMENTS,
              RadioError::INVALID_STATE, RadioError::NO_MEMORY, RadioError::INTERNAL_ERR,
-             RadioError::SYSTEM_ERR, RadioError::CANCELLED, RadioError::MODEM_ERR}));
+             RadioError::SYSTEM_ERR, RadioError::CANCELLED, RadioError::MODEM_ERR,
+             RadioError::REQUEST_NOT_SUPPORTED}));
 }
 
 /*
  * Test IRadioNetwork.getBarringInfo() for the response returned.
  */
 TEST_P(RadioNetworkTest, getBarringInfo) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getBarringInfo "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getBarringInfo "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1507,6 +1466,9 @@
     EXPECT_EQ(std::cv_status::no_timeout, wait());
     EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
     EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    if (radioRsp_network->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping getBarringInfo because it's not supported";
+    }
     ASSERT_TRUE(radioRsp_network->barringInfoList.size() > 0);
 
     std::set<int> reportedServices;
@@ -1606,11 +1568,9 @@
  * Test IRadioNetwork.getSignalStrength() for the response returned.
  */
 TEST_P(RadioNetworkTest, getSignalStrength) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getSignalStrength "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getSignalStrength "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1632,11 +1592,9 @@
  * Test IRadioNetwork.getCellInfoList() for the response returned.
  */
 TEST_P(RadioNetworkTest, getCellInfoList) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getCellInfoList "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getCellInfoList "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1657,11 +1615,9 @@
  * Test IRadioNetwork.getVoiceRegistrationState() for the response returned.
  */
 TEST_P(RadioNetworkTest, getVoiceRegistrationState) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getVoiceRegistrationState "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getVoiceRegistrationState "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1682,11 +1638,9 @@
  * Test IRadioNetwork.getDataRegistrationState() for the response returned.
  */
 TEST_P(RadioNetworkTest, getDataRegistrationState) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getDataRegistrationState "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getDataRegistrationState "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1787,11 +1741,9 @@
     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 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getAvailableBandModes "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1823,11 +1775,9 @@
  * Test IRadioNetwork.setIndicationFilter()
  */
 TEST_P(RadioNetworkTest, setIndicationFilter) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setIndicationFilter "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setIndicationFilter "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1848,11 +1798,9 @@
  * Test IRadioNetwork.setBarringPassword() for the response returned.
  */
 TEST_P(RadioNetworkTest, setBarringPassword) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setBarringPassword "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setBarringPassword "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1878,11 +1826,9 @@
  * Test IRadioNetwork.setSuppServiceNotifications() for the response returned.
  */
 TEST_P(RadioNetworkTest, setSuppServiceNotifications) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping setSuppServiceNotifications "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping setSuppServiceNotifications "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -1904,11 +1850,9 @@
  * Test IRadioNetwork.getImsRegistrationState() for the response returned.
  */
 TEST_P(RadioNetworkTest, getImsRegistrationState) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
-            GTEST_SKIP() << "Skipping getImsRegistrationState "
-                            "due to undefined FEATURE_TELEPHONY_IMS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        GTEST_SKIP() << "Skipping getImsRegistrationState "
+                        "due to undefined FEATURE_TELEPHONY_IMS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1931,11 +1875,9 @@
  * Test IRadioNetwork.getOperator() for the response returned.
  */
 TEST_P(RadioNetworkTest, getOperator) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getOperator "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getOperator "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1954,11 +1896,9 @@
  * Test IRadioNetwork.getNetworkSelectionMode() for the response returned.
  */
 TEST_P(RadioNetworkTest, getNetworkSelectionMode) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getNetworkSelectionMode "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getNetworkSelectionMode "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1977,11 +1917,9 @@
  * Test IRadioNetwork.setNetworkSelectionModeAutomatic() for the response returned.
  */
 TEST_P(RadioNetworkTest, setNetworkSelectionModeAutomatic) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setNetworkSelectionModeAutomatic "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setNetworkSelectionModeAutomatic "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -2003,11 +1941,9 @@
  * Test IRadioNetwork.getAvailableNetworks() for the response returned.
  */
 TEST_P(RadioNetworkTest, getAvailableNetworks) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getAvailableNetworks "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getAvailableNetworks "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -2034,11 +1970,9 @@
     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 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setBandMode "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -2062,11 +1996,9 @@
     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 "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setLocationUpdates "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -2086,11 +2018,9 @@
  * Test IRadioNetwork.setCdmaRoamingPreference() for the response returned.
  */
 TEST_P(RadioNetworkTest, setCdmaRoamingPreference) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping setCdmaRoamingPreference "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping setCdmaRoamingPreference "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -2111,11 +2041,9 @@
  * Test IRadioNetwork.getCdmaRoamingPreference() for the response returned.
  */
 TEST_P(RadioNetworkTest, getCdmaRoamingPreference) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping getCdmaRoamingPreference "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping getCdmaRoamingPreference "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -2137,11 +2065,9 @@
  * Test IRadioNetwork.getVoiceRadioTechnology() for the response returned.
  */
 TEST_P(RadioNetworkTest, getVoiceRadioTechnology) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping getVoiceRadioTechnology "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping getVoiceRadioTechnology "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -2160,11 +2086,9 @@
  * Test IRadioNetwork.setCellInfoListRate() for the response returned.
  */
 TEST_P(RadioNetworkTest, setCellInfoListRate) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setCellInfoListRate "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setCellInfoListRate "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -2184,11 +2108,9 @@
  * Test IRadioNetwork.supplyNetworkDepersonalization() for the response returned.
  */
 TEST_P(RadioNetworkTest, supplyNetworkDepersonalization) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping supplyNetworkDepersonalization "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping supplyNetworkDepersonalization "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     serial = GetRandomSerialNumber();
@@ -2211,11 +2133,9 @@
  * Test IRadioNetwork.setEmergencyMode() for the response returned.
  */
 TEST_P(RadioNetworkTest, setEmergencyMode) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setEmergencyMode "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setEmergencyMode "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     int32_t aidl_version;
@@ -2255,11 +2175,9 @@
  * Test IRadioNetwork.triggerEmergencyNetworkScan() for the response returned.
  */
 TEST_P(RadioNetworkTest, triggerEmergencyNetworkScan) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping triggerEmergencyNetworkScan "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping triggerEmergencyNetworkScan "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     int32_t aidl_version;
@@ -2317,11 +2235,9 @@
  * Test IRadioNetwork.cancelEmergencyNetworkScan() for the response returned.
  */
 TEST_P(RadioNetworkTest, cancelEmergencyNetworkScan) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping cancelEmergencyNetworkScan "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping cancelEmergencyNetworkScan "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     int32_t aidl_version;
@@ -2348,11 +2264,9 @@
  * Test IRadioNetwork.exitEmergencyMode() for the response returned.
  */
 TEST_P(RadioNetworkTest, exitEmergencyMode) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping exitEmergencyMode "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping exitEmergencyMode "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     int32_t aidl_version;
@@ -2379,11 +2293,9 @@
  * Test IRadioNetwork.setN1ModeEnabled() for the response returned.
  */
 TEST_P(RadioNetworkTest, setN1ModeEnabled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setN1ModeEnabled "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setN1ModeEnabled "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     int32_t aidl_version;
@@ -2418,11 +2330,9 @@
  * Test IRadioNetwork.isN1ModeEnabled() for the response returned.
  */
 TEST_P(RadioNetworkTest, isN1ModeEnabled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping isN1ModeEnabled "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping isN1ModeEnabled "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     int32_t aidl_version;
@@ -2456,11 +2366,9 @@
  * Test IRadioNetwork.setNullCipherAndIntegrityEnabled() for the response returned.
  */
 TEST_P(RadioNetworkTest, setNullCipherAndIntegrityEnabled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping setNullCipherAndIntegrityEnabled "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping setNullCipherAndIntegrityEnabled "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     int32_t aidl_version;
@@ -2488,11 +2396,9 @@
  * Test IRadioNetwork.isNullCipherAndIntegrityEnabled() for the response returned.
  */
 TEST_P(RadioNetworkTest, isNullCipherAndIntegrityEnabled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-            GTEST_SKIP() << "Skipping isNullCipherAndIntegrityEnabled "
-                            "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
+        GTEST_SKIP() << "Skipping isNullCipherAndIntegrityEnabled "
+                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
     }
 
     int32_t aidl_version;
diff --git a/radio/aidl/vts/radio_sap_test.cpp b/radio/aidl/vts/radio_sap_test.cpp
index 6d283e9..55e5148 100644
--- a/radio/aidl/vts/radio_sap_test.cpp
+++ b/radio/aidl/vts/radio_sap_test.cpp
@@ -85,11 +85,9 @@
  * Test ISap.connectReq() for the response returned.
  */
 TEST_P(SapTest, connectReq) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping connectReq "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping connectReq "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -110,11 +108,9 @@
  * Test ISap.disconnectReq() for the response returned
  */
 TEST_P(SapTest, disconnectReq) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping disconnectReq "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping disconnectReq "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -130,11 +126,9 @@
  * Test ISap.apduReq() for the response returned.
  */
 TEST_P(SapTest, apduReq) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping apduReq "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping apduReq "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -158,11 +152,9 @@
  * Test ISap.transferAtrReq() for the response returned.
  */
 TEST_P(SapTest, transferAtrReq) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping transferAtrReq "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping transferAtrReq "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -183,11 +175,9 @@
  * Test ISap.powerReq() for the response returned.
  */
 TEST_P(SapTest, powerReq) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping powerReq "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping powerReq "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -210,11 +200,9 @@
  * Test ISap.resetSimReq() for the response returned.
  */
 TEST_P(SapTest, resetSimReq) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping resetSimReq "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping resetSimReq "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -236,11 +224,9 @@
  * Test ISap.transferCardReaderStatusReq() for the response returned.
  */
 TEST_P(SapTest, transferCardReaderStatusReq) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping transferCardReaderStatusReq "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping transferCardReaderStatusReq "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -260,11 +246,9 @@
  * Test ISap.setTransferProtocolReq() for the response returned.
  */
 TEST_P(SapTest, setTransferProtocolReq) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping setTransferProtocolReq "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping setTransferProtocolReq "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index aaccb21..e7c7c65 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -74,11 +74,9 @@
  * Test IRadioSim.setSimCardPower() for the response returned.
  */
 TEST_P(RadioSimTest, setSimCardPower) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping setSimCardPower "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping setSimCardPower "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     /* Test setSimCardPower power down */
@@ -89,7 +87,12 @@
     EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
     ASSERT_TRUE(CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
                                  {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
-                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ERR}));
+                                  RadioError::RADIO_NOT_AVAILABLE, RadioError::SIM_ERR,
+                                  RadioError::REQUEST_NOT_SUPPORTED}));
+
+    if (radioRsp_sim->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) {
+        GTEST_SKIP() << "Skipping setSimCardPower because it's not supported";
+    }
 
     // setSimCardPower does not return  until the request is handled, and should not trigger
     // CardStatus::STATE_ABSENT when turning off power
@@ -143,11 +146,9 @@
  * Test IRadioSim.setCarrierInfoForImsiEncryption() for the response returned.
  */
 TEST_P(RadioSimTest, setCarrierInfoForImsiEncryption) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping setCarrierInfoForImsiEncryption "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping setCarrierInfoForImsiEncryption "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -174,11 +175,9 @@
  * Test IRadioSim.getSimPhonebookRecords() for the response returned.
  */
 TEST_P(RadioSimTest, getSimPhonebookRecords) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping getSimPhonebookRecords "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping getSimPhonebookRecords "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -204,11 +203,9 @@
  * Test IRadioSim.getSimPhonebookCapacity for the response returned.
  */
 TEST_P(RadioSimTest, getSimPhonebookCapacity) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping getSimPhonebookCapacity "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping getSimPhonebookCapacity "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -251,11 +248,9 @@
  * Test IRadioSim.updateSimPhonebookRecords() for the response returned.
  */
 TEST_P(RadioSimTest, updateSimPhonebookRecords) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping updateSimPhonebookRecords "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping updateSimPhonebookRecords "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -322,11 +317,9 @@
  * For SIM ABSENT case.
  */
 TEST_P(RadioSimTest, togglingUiccApplicationsSimAbsent) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping togglingUiccApplicationsSimAbsent "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping togglingUiccApplicationsSimAbsent "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     // This test case only test SIM ABSENT case.
@@ -356,11 +349,9 @@
  * For SIM PRESENT case.
  */
 TEST_P(RadioSimTest, togglingUiccApplicationsSimPresent) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping togglingUiccApplicationsSimPresent "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping togglingUiccApplicationsSimPresent "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     // This test case only test SIM ABSENT case.
@@ -410,11 +401,9 @@
  * Test IRadioSim.areUiccApplicationsEnabled() for the response returned.
  */
 TEST_P(RadioSimTest, areUiccApplicationsEnabled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping areUiccApplicationsEnabled "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping areUiccApplicationsEnabled "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     // Disable Uicc applications.
@@ -437,11 +426,9 @@
  * Test IRadioSim.getAllowedCarriers() for the response returned.
  */
 TEST_P(RadioSimTest, getAllowedCarriers) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping getAllowedCarriers "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping getAllowedCarriers "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -459,11 +446,9 @@
  * Test IRadioSim.setAllowedCarriers() for the response returned.
  */
 TEST_P(RadioSimTest, setAllowedCarriers) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping setAllowedCarriers "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping setAllowedCarriers "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -621,11 +606,9 @@
  * Test IRadioSim.getIccCardStatus() for the response returned.
  */
 TEST_P(RadioSimTest, getIccCardStatus) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping getIccCardStatus "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping getIccCardStatus "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     EXPECT_LE(cardStatus.applications.size(), RadioConst::CARD_MAX_APPS);
@@ -638,11 +621,9 @@
  * Test IRadioSim.supplyIccPinForApp() for the response returned
  */
 TEST_P(RadioSimTest, supplyIccPinForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping supplyIccPinForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping supplyIccPinForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -670,11 +651,9 @@
  * Test IRadioSim.supplyIccPukForApp() for the response returned.
  */
 TEST_P(RadioSimTest, supplyIccPukForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping supplyIccPukForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping supplyIccPukForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -693,7 +672,8 @@
             EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
             ASSERT_TRUE(CheckAnyOfErrors(
                     radioRsp_sim->rspInfo.error,
-                    {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE}));
+                    {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE,
+                     RadioError::REQUEST_NOT_SUPPORTED}));
         }
     }
 }
@@ -702,11 +682,9 @@
  * Test IRadioSim.supplyIccPin2ForApp() for the response returned.
  */
 TEST_P(RadioSimTest, supplyIccPin2ForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping supplyIccPin2ForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping supplyIccPin2ForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -735,11 +713,9 @@
  * Test IRadioSim.supplyIccPuk2ForApp() for the response returned.
  */
 TEST_P(RadioSimTest, supplyIccPuk2ForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping supplyIccPuk2ForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping supplyIccPuk2ForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -758,7 +734,8 @@
             EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
             ASSERT_TRUE(CheckAnyOfErrors(
                     radioRsp_sim->rspInfo.error,
-                    {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE}));
+                    {RadioError::PASSWORD_INCORRECT, RadioError::INVALID_SIM_STATE,
+                     RadioError::REQUEST_NOT_SUPPORTED}));
         }
     }
 }
@@ -767,11 +744,9 @@
  * Test IRadioSim.changeIccPinForApp() for the response returned.
  */
 TEST_P(RadioSimTest, changeIccPinForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping changeIccPinForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping changeIccPinForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -799,11 +774,9 @@
  * Test IRadioSim.changeIccPin2ForApp() for the response returned.
  */
 TEST_P(RadioSimTest, changeIccPin2ForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping changeIccPin2ForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping changeIccPin2ForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -832,11 +805,9 @@
  * Test IRadioSim.getImsiForApp() for the response returned.
  */
 TEST_P(RadioSimTest, getImsiForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping getImsiForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping getImsiForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -868,11 +839,9 @@
  * Test IRadioSim.iccIoForApp() for the response returned.
  */
 TEST_P(RadioSimTest, iccIoForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping iccIoForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping iccIoForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -900,11 +869,9 @@
  * Test IRadioSim.iccTransmitApduBasicChannel() for the response returned.
  */
 TEST_P(RadioSimTest, iccTransmitApduBasicChannel) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping iccTransmitApduBasicChannel "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping iccTransmitApduBasicChannel "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -922,11 +889,9 @@
  * Test IRadioSim.iccOpenLogicalChannel() for the response returned.
  */
 TEST_P(RadioSimTest, iccOpenLogicalChannel) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping iccOpenLogicalChannel "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping iccOpenLogicalChannel "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -951,11 +916,9 @@
         GTEST_SKIP() << "Skipping iccCloseLogicalChannel (deprecated)";
     }
 
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping iccCloseLogicalChannel "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping iccCloseLogicalChannel "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -972,11 +935,9 @@
  * Test IRadioSim.iccCloseLogicalChannelWithSessionInfo() for the response returned.
  */
 TEST_P(RadioSimTest, iccCloseLogicalChannelWithSessionInfo) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping iccCloseLogicalChannelWithSessionInfo "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping iccCloseLogicalChannelWithSessionInfo "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     int32_t aidl_version;
@@ -1006,11 +967,9 @@
  * Test IRadioSim.iccTransmitApduLogicalChannel() for the response returned.
  */
 TEST_P(RadioSimTest, iccTransmitApduLogicalChannel) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping iccTransmitApduLogicalChannel "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping iccTransmitApduLogicalChannel "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -1028,11 +987,9 @@
  * Test IRadioSim.requestIccSimAuthentication() for the response returned.
  */
 TEST_P(RadioSimTest, requestIccSimAuthentication) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping requestIccSimAuthentication "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping requestIccSimAuthentication "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -1055,11 +1012,9 @@
  * Test IRadioSim.getFacilityLockForApp() for the response returned.
  */
 TEST_P(RadioSimTest, getFacilityLockForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping getFacilityLockForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping getFacilityLockForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -1085,11 +1040,9 @@
  * Test IRadioSim.setFacilityLockForApp() for the response returned.
  */
 TEST_P(RadioSimTest, setFacilityLockForApp) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping setFacilityLockForApp "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping setFacilityLockForApp "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -1116,11 +1069,9 @@
  * Test IRadioSim.getCdmaSubscription() for the response returned.
  */
 TEST_P(RadioSimTest, getCdmaSubscription) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping getCdmaSubscription "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping getCdmaSubscription "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -1141,11 +1092,9 @@
  * Test IRadioSim.getCdmaSubscriptionSource() for the response returned.
  */
 TEST_P(RadioSimTest, getCdmaSubscriptionSource) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping getCdmaSubscriptionSource "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping getCdmaSubscriptionSource "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -1166,11 +1115,9 @@
  * Test IRadioSim.setCdmaSubscriptionSource() for the response returned.
  */
 TEST_P(RadioSimTest, setCdmaSubscriptionSource) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping setCdmaSubscriptionSource "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping setCdmaSubscriptionSource "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -1195,11 +1142,9 @@
     if (!shouldTestCdma()) {
         GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
     }
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping setUiccSubscription "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping setUiccSubscription "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -1224,11 +1169,9 @@
  * Test IRadioSim.sendEnvelope() for the response returned.
  */
 TEST_P(RadioSimTest, sendEnvelope) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping sendEnvelope "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping sendEnvelope "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -1254,11 +1197,9 @@
  * Test IRadioSim.sendTerminalResponseToSim() for the response returned.
  */
 TEST_P(RadioSimTest, sendTerminalResponseToSim) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping sendTerminalResponseToSim "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping sendTerminalResponseToSim "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -1284,11 +1225,9 @@
  * Test IRadioSim.reportStkServiceIsRunning() for the response returned.
  */
 TEST_P(RadioSimTest, reportStkServiceIsRunning) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping reportStkServiceIsRunning "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping reportStkServiceIsRunning "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
@@ -1310,11 +1249,9 @@
  * string.
  */
 TEST_P(RadioSimTest, sendEnvelopeWithStatus) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-            GTEST_SKIP() << "Skipping sendEnvelopeWithStatus "
-                            "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
+        GTEST_SKIP() << "Skipping sendEnvelopeWithStatus "
+                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
     }
 
     serial = GetRandomSerialNumber();
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
index 3b07378..9eb5bac 100644
--- a/radio/aidl/vts/radio_voice_test.cpp
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -93,18 +93,9 @@
  * Test IRadioVoice.emergencyDial() for the response returned.
  */
 TEST_P(RadioVoiceTest, emergencyDial) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping emergencyDial "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
-    } else {
-        if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
-            ALOGI("Skipping emergencyDial because voice call is not supported in device");
-            return;
-        } else {
-            ALOGI("Running emergencyDial because voice call is supported in device");
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping emergencyDial "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -150,18 +141,9 @@
  * Test IRadioVoice.emergencyDial() with specified service and its response returned.
  */
 TEST_P(RadioVoiceTest, emergencyDial_withServices) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping emergencyDial_withServices "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
-    } else {
-        if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
-            ALOGI("Skipping emergencyDial because voice call is not supported in device");
-            return;
-        } else {
-            ALOGI("Running emergencyDial because voice call is supported in device");
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping emergencyDial_withServices "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -207,18 +189,9 @@
  * Test IRadioVoice.emergencyDial() with known emergency call routing and its response returned.
  */
 TEST_P(RadioVoiceTest, emergencyDial_withEmergencyRouting) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping emergencyDial_withEmergencyRouting "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
-    } else {
-        if (!deviceSupportsFeature(FEATURE_VOICE_CALL)) {
-            ALOGI("Skipping emergencyDial because voice call is not supported in device");
-            return;
-        } else {
-            ALOGI("Running emergencyDial because voice call is supported in device");
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping emergencyDial_withEmergencyRouting "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -265,11 +238,9 @@
  * Test IRadioVoice.getCurrentCalls() for the response returned.
  */
 TEST_P(RadioVoiceTest, getCurrentCalls) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getCurrentCalls "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getCurrentCalls "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -284,11 +255,9 @@
  * Test IRadioVoice.getClir() for the response returned.
  */
 TEST_P(RadioVoiceTest, getClir) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getClir "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getClir "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -309,11 +278,9 @@
  * Test IRadioVoice.setClir() for the response returned.
  */
 TEST_P(RadioVoiceTest, setClir) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping setClir "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping setClir "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -334,11 +301,9 @@
  * Test IRadioVoice.getClip() for the response returned.
  */
 TEST_P(RadioVoiceTest, getClip) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getClip "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getClip "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -359,11 +324,9 @@
  * Test IRadioVoice.getTtyMode() for the response returned.
  */
 TEST_P(RadioVoiceTest, getTtyMode) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getTtyMode "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getTtyMode "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -382,11 +345,9 @@
  * Test IRadioVoice.setTtyMode() for the response returned.
  */
 TEST_P(RadioVoiceTest, setTtyMode) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping setTtyMode "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping setTtyMode "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -405,11 +366,9 @@
  * Test IRadioVoice.setPreferredVoicePrivacy() for the response returned.
  */
 TEST_P(RadioVoiceTest, setPreferredVoicePrivacy) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping setPreferredVoicePrivacy "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping setPreferredVoicePrivacy "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -429,11 +388,9 @@
  * Test IRadioVoice.getPreferredVoicePrivacy() for the response returned.
  */
 TEST_P(RadioVoiceTest, getPreferredVoicePrivacy) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getPreferredVoicePrivacy "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getPreferredVoicePrivacy "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -453,11 +410,9 @@
  * Test IRadioVoice.exitEmergencyCallbackMode() for the response returned.
  */
 TEST_P(RadioVoiceTest, exitEmergencyCallbackMode) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping exitEmergencyCallbackMode "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping exitEmergencyCallbackMode "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -478,11 +433,9 @@
  * Test IRadioVoice.handleStkCallSetupRequestFromSim() for the response returned.
  */
 TEST_P(RadioVoiceTest, handleStkCallSetupRequestFromSim) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping handleStkCallSetupRequestFromSim "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping handleStkCallSetupRequestFromSim "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -506,11 +459,9 @@
  * Test IRadioVoice.dial() for the response returned.
  */
 TEST_P(RadioVoiceTest, dial) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping dial "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping dial "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -540,11 +491,9 @@
  * Test IRadioVoice.hangup() for the response returned.
  */
 TEST_P(RadioVoiceTest, hangup) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping hangup "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping hangup "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -566,11 +515,9 @@
  * Test IRadioVoice.hangupWaitingOrBackground() for the response returned.
  */
 TEST_P(RadioVoiceTest, hangupWaitingOrBackground) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping hangupWaitingOrBackground "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping hangupWaitingOrBackground "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -591,11 +538,9 @@
  * Test IRadioVoice.hangupForegroundResumeBackground() for the response returned.
  */
 TEST_P(RadioVoiceTest, hangupForegroundResumeBackground) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping hangupForegroundResumeBackground "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping hangupForegroundResumeBackground "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -616,11 +561,9 @@
  * Test IRadioVoice.switchWaitingOrHoldingAndActive() for the response returned.
  */
 TEST_P(RadioVoiceTest, switchWaitingOrHoldingAndActive) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping switchWaitingOrHoldingAndActive "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping switchWaitingOrHoldingAndActive "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -641,11 +584,9 @@
  * Test IRadioVoice.conference() for the response returned.
  */
 TEST_P(RadioVoiceTest, conference) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping conference "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping conference "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -666,11 +607,9 @@
  * Test IRadioVoice.rejectCall() for the response returned.
  */
 TEST_P(RadioVoiceTest, rejectCall) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping rejectCall "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping rejectCall "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -691,11 +630,9 @@
  * Test IRadioVoice.getLastCallFailCause() for the response returned.
  */
 TEST_P(RadioVoiceTest, getLastCallFailCause) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getLastCallFailCause "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getLastCallFailCause "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -715,11 +652,9 @@
  * Test IRadioVoice.getCallForwardStatus() for the response returned.
  */
 TEST_P(RadioVoiceTest, getCallForwardStatus) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getCallForwardStatus "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getCallForwardStatus "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -744,11 +679,9 @@
  * Test IRadioVoice.setCallForward() for the response returned.
  */
 TEST_P(RadioVoiceTest, setCallForward) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping setCallForward "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping setCallForward "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -773,11 +706,9 @@
  * Test IRadioVoice.getCallWaiting() for the response returned.
  */
 TEST_P(RadioVoiceTest, getCallWaiting) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getCallWaiting "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getCallWaiting "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -799,11 +730,9 @@
  * Test IRadioVoice.setCallWaiting() for the response returned.
  */
 TEST_P(RadioVoiceTest, setCallWaiting) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping setCallWaiting "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping setCallWaiting "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -825,11 +754,9 @@
  * Test IRadioVoice.acceptCall() for the response returned.
  */
 TEST_P(RadioVoiceTest, acceptCall) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping acceptCall "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping acceptCall "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -850,11 +777,9 @@
  * Test IRadioVoice.separateConnection() for the response returned.
  */
 TEST_P(RadioVoiceTest, separateConnection) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping separateConnection "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping separateConnection "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -876,11 +801,9 @@
  * Test IRadioVoice.explicitCallTransfer() for the response returned.
  */
 TEST_P(RadioVoiceTest, explicitCallTransfer) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping explicitCallTransfer "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping explicitCallTransfer "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -901,11 +824,9 @@
  * Test IRadioVoice.sendCdmaFeatureCode() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendCdmaFeatureCode) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-            GTEST_SKIP() << "Skipping sendCdmaFeatureCode "
-                            "due to undefined FEATURE_TELEPHONY_CDMA";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping sendCdmaFeatureCode "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
     }
 
     serial = GetRandomSerialNumber();
@@ -928,11 +849,9 @@
  * Test IRadioVoice.sendDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendDtmf) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping sendDtmf "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping sendDtmf "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -955,11 +874,9 @@
  * Test IRadioVoice.startDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, startDtmf) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping startDtmf "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping startDtmf "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -982,11 +899,9 @@
  * Test IRadioVoice.stopDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, stopDtmf) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping stopDtmf "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping stopDtmf "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -1008,11 +923,9 @@
  * Test IRadioVoice.setMute() for the response returned.
  */
 TEST_P(RadioVoiceTest, setMute) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping setMute "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping setMute "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -1033,11 +946,9 @@
  * Test IRadioVoice.getMute() for the response returned.
  */
 TEST_P(RadioVoiceTest, getMute) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping getMute "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping getMute "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -1056,11 +967,9 @@
  * Test IRadioVoice.sendBurstDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendBurstDtmf) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping sendBurstDtmf "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping sendBurstDtmf "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -1082,11 +991,9 @@
  * Test IRadioVoice.sendUssd() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendUssd) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping sendUssd "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping sendUssd "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -1107,11 +1014,9 @@
  * Test IRadioVoice.cancelPendingUssd() for the response returned.
  */
 TEST_P(RadioVoiceTest, cancelPendingUssd) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
-            GTEST_SKIP() << "Skipping cancelPendingUssd "
-                            "due to undefined FEATURE_TELEPHONY_CALLING";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CALLING)) {
+        GTEST_SKIP() << "Skipping cancelPendingUssd "
+                        "due to undefined FEATURE_TELEPHONY_CALLING";
     }
 
     serial = GetRandomSerialNumber();
@@ -1133,11 +1038,9 @@
  * Test IRadioVoice.isVoNrEnabled() for the response returned.
  */
 TEST_P(RadioVoiceTest, isVoNrEnabled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
-            GTEST_SKIP() << "Skipping isVoNrEnabled "
-                            "due to undefined FEATURE_TELEPHONY_IMS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        GTEST_SKIP() << "Skipping isVoNrEnabled "
+                        "due to undefined FEATURE_TELEPHONY_IMS";
     }
 
     serial = GetRandomSerialNumber();
@@ -1155,11 +1058,9 @@
  * Test IRadioVoice.setVoNrEnabled() for the response returned.
  */
 TEST_P(RadioVoiceTest, setVoNrEnabled) {
-    if (telephony_flags::enforce_telephony_feature_mapping()) {
-        if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
-            GTEST_SKIP() << "Skipping setVoNrEnabled "
-                            "due to undefined FEATURE_TELEPHONY_IMS";
-        }
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_IMS)) {
+        GTEST_SKIP() << "Skipping setVoNrEnabled "
+                        "due to undefined FEATURE_TELEPHONY_IMS";
     }
 
     serial = GetRandomSerialNumber();
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index fc703e9..0ae4b96 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -479,8 +479,8 @@
      *        structure.
      *
      * @param unwrappingParams must contain any parameters needed to perform the unwrapping
-     *        operation.  For example, if the wrapping key is an AES key the block and padding modes
-     *        must be specified in this argument.
+     *        operation.  For example, the padding mode for the RSA wrapping key must be specified
+     *        in this argument.
      *
      * @param passwordSid specifies the password secure ID (SID) of the user that owns the key being
      *        installed.  If the authorization list in wrappedKeyData contains a
@@ -550,8 +550,14 @@
     void deleteKey(in byte[] keyBlob);
 
     /**
-     * Deletes all keys in the hardware keystore. Used when keystore is reset completely. After
-     * this function is called all keys created previously must be rendered permanently unusable.
+     * Deletes all keys in the hardware keystore. Used when keystore is reset completely.
+     *
+     * For StrongBox KeyMint: After this function is called all keys created previously must be
+     * rendered permanently unusable.
+     *
+     * For TEE KeyMint: After this function is called all keys with Tag::ROLLBACK_RESISTANCE in
+     * their hardware-enforced authorization lists must be rendered permanently unusable.  Keys
+     * without Tag::ROLLBACK_RESISTANCE may or may not be rendered unusable.
      */
     void deleteAllKeys();
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 06e0f58..0c86a27 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -328,7 +328,16 @@
  * which is mandatory for KeyMint version 2 and first_api_level 33 or greater.
  */
 bool KeyMintAidlTestBase::isDeviceIdAttestationRequired() {
-    return AidlVersion() >= 2 && property_get_int32("ro.vendor.api_level", 0) >= __ANDROID_API_T__;
+    if (!is_gsi_image()) {
+        return AidlVersion() >= 2 &&
+            get_vendor_api_level() >= AVendorSupport_getVendorApiLevelOf(__ANDROID_API_T__);
+    } else {
+        // The device ID properties may not be set properly when testing earlier implementations
+        // under GSI, e.g. `ro.product.<id>` is overridden by the GSI image, but the
+        // `ro.product.vendor.<id>` value (which does survive GSI installation) was not set.
+        return AidlVersion() >= 2 &&
+            get_vendor_api_level() >= AVendorSupport_getVendorApiLevelOf(__ANDROID_API_U__);
+    }
 }
 
 /**
diff --git a/security/keymint/support/authorization_set.cpp b/security/keymint/support/authorization_set.cpp
index c1b5d48..5944908 100644
--- a/security/keymint/support/authorization_set.cpp
+++ b/security/keymint/support/authorization_set.cpp
@@ -22,6 +22,8 @@
 #include <aidl/android/hardware/security/keymint/KeyParameter.h>
 #include <aidl/android/hardware/security/keymint/KeyPurpose.h>
 
+#include <algorithm>
+
 namespace aidl::android::hardware::security::keymint {
 
 void AuthorizationSet::Sort() {
diff --git a/security/secretkeeper/OWNERS b/security/secretkeeper/OWNERS
index acf4c6c..d63ba9b 100644
--- a/security/secretkeeper/OWNERS
+++ b/security/secretkeeper/OWNERS
@@ -1,6 +1,5 @@
 # Bug component: 867125
 
-alanstokes@google.com
 drysdale@google.com
 hasinitg@google.com
 shikhapanwar@google.com
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
diff --git a/security/see/hwcrypto/aidl/vts/functional/Android.bp b/security/see/hwcrypto/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..beb8976
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/Android.bp
@@ -0,0 +1,83 @@
+// Copyright (C) 2024 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_defaults {
+    name: "hw_crypto_hal_aidl_rust_defaults",
+    enabled: false,
+    rustlibs: [
+        "libbinder_rs",
+        "android.hardware.security.see.hwcrypto-V1-rust",
+        "liblogger",
+        "liblog_rust",
+        "libanyhow",
+        "libvsock",
+        "librpcbinder_rs",
+        "librustutils",
+    ],
+    arch: {
+        x86_64: {
+            enabled: true,
+        },
+    },
+}
+
+rust_library {
+    name: "libhwcryptohal_vts_test",
+    crate_name: "hwcryptohal_vts_test",
+    srcs: [
+        "lib.rs",
+    ],
+    defaults: [
+        "hw_crypto_hal_aidl_rust_defaults",
+    ],
+}
+
+rust_binary {
+    name: "wait_hw_crypto",
+    prefer_rlib: true,
+    defaults: [
+        "hw_crypto_hal_aidl_rust_defaults",
+    ],
+    srcs: ["wait_service.rs"],
+    rustlibs: [
+        "libhwcryptohal_vts_test",
+        "liblogger",
+        "liblog_rust",
+        "libanyhow",
+        "libclap",
+    ],
+}
+
+rust_test {
+    name: "VtsAidlHwCryptoConnTest",
+    srcs: ["connection_test.rs"],
+    require_root: true,
+    defaults: [
+        "hw_crypto_hal_aidl_rust_defaults",
+    ],
+    rustlibs: [
+        "libhwcryptohal_vts_test",
+    ],
+    data: [
+        ":trusty_test_vm_elf",
+        ":trusty_test_vm_config",
+        ":trusty_vm_launcher_sh",
+        ":trusty_wait_ready_sh",
+        ":wait_hw_crypto",
+    ],
+}
diff --git a/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml b/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..73290cf
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright 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.
+  -->
+    <configuration description="Runs {MODULE}">
+    <!-- object type="module_controller" class="com.android.tradefed.testtype.suite.module.CommandSuccessModuleController" -->
+        <!--Skip the test when trusty VM is not enabled. -->
+        <!--option name="run-command" value="getprop trusty.test_vm.nonsecure_vm_ready | grep 1" /-->
+    <!--/object-->
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+    <!-- Target Preparers - Run Shell Commands -->
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file" key="trusty-vm-launcher.sh" value="/data/local/tmp/trusty_test_vm/trusty-vm-launcher.sh" />
+        <option name="push-file" key="trusty-wait-ready.sh" value="/data/local/tmp/trusty_test_vm/trusty-wait-ready.sh" />
+        <option name="push-file" key="wait_hw_crypto" value="/data/local/tmp/trusty_test_vm/wait_hw_crypto" />
+        <option name="push-file" key="trusty-test_vm-config.json" value="/data/local/tmp/trusty_test_vm/trusty-test_vm-config.json" />
+        <option name="push-file" key="trusty_test_vm_elf" value="/data/local/tmp/trusty_test_vm/trusty_test_vm_elf" />
+        <option name="push-file" key="VtsAidlHwCryptoConnTest" value="/data/local/tmp/VtsAidlHwCryptoConnTest" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="throw-if-cmd-fail" value="true" />
+        <!--Note: the first run-command shall not expect the background command to have started -->
+        <option name="run-bg-command" value="sh /data/local/tmp/trusty_test_vm/trusty-vm-launcher.sh" />
+        <option name="run-command" value="sh /data/local/tmp/trusty_test_vm/trusty-wait-ready.sh" />
+        <option name="run-bg-command" value="start trusty-hwcryptohal" />
+        <option name="run-command" value="/data/local/tmp/trusty_test_vm/wait_hw_crypto" />
+        <option name="run-command" value="start storageproxyd_test_system" />
+        <option name="teardown-command" value="stop storageproxyd_test_system" />
+        <option name="teardown-command" value="stop trusty-hwcryptohal" />
+        <option name="teardown-command" value="killall storageproxyd_test_system || true" />
+        <option name="teardown-command" value="stop trusty-hwcryptohal" />
+        <option name="teardown-command" value="killall trusty || true" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+        <option name="test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="VtsAidlHwCryptoConnTest" />
+        <!-- Rust tests are run in parallel by default. Run these ones
+            single-threaded, so that one test's secrets don't affect
+            the behaviour of a different test. -->
+        <option name="native-test-flag" value="--test-threads=1" />
+    </test>
+    </configuration>
diff --git a/security/see/hwcrypto/aidl/vts/functional/connection_test.rs b/security/see/hwcrypto/aidl/vts/functional/connection_test.rs
new file mode 100644
index 0000000..338923d
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/connection_test.rs
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+//! HwCrypto Connection tests.
+
+#[test]
+fn test_hwcrypto_key_connection() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey();
+    assert!(hw_crypto_key.is_ok(), "Couldn't get back a hwcryptokey binder object");
+}
diff --git a/security/see/hwcrypto/aidl/vts/functional/lib.rs b/security/see/hwcrypto/aidl/vts/functional/lib.rs
new file mode 100644
index 0000000..e14ac83
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/lib.rs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2024 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.
+ */
+
+//! VTS test library for HwCrypto functionality.
+//! It provides the base clases necessaries to write HwCrypto VTS tests
+
+use anyhow::{Context, Result};
+use binder::{ExceptionCode, FromIBinder, IntoBinderResult, ParcelFileDescriptor};
+use rpcbinder::RpcSession;
+use vsock::VsockStream;
+use std::os::fd::{FromRawFd, IntoRawFd};
+use std::fs::File;
+use std::io::Read;
+use rustutils::system_properties;
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::IHwCryptoKey;
+
+const HWCRYPTO_SERVICE_PORT: u32 = 4;
+
+/// Local function to connect to service
+pub fn connect_service<T: FromIBinder + ?Sized>(
+    cid: u32,
+    port: u32,
+) -> Result<binder::Strong<T>, binder::StatusCode> {
+    RpcSession::new().setup_preconnected_client(|| {
+        let mut stream = VsockStream::connect_with_cid_port(cid, port).ok()?;
+        let mut buffer = [0];
+        let _ = stream.read(&mut buffer);
+        // SAFETY: ownership is transferred from stream to f
+        let f = unsafe { File::from_raw_fd(stream.into_raw_fd()) };
+        Some(ParcelFileDescriptor::new(f).into_raw_fd())
+    })
+}
+
+/// Get a HwCryptoKey binder service object
+pub fn get_hwcryptokey() -> Result<binder::Strong<dyn IHwCryptoKey>, binder::Status> {
+    let cid = system_properties::read("trusty.test_vm.vm_cid")
+        .context("couldn't get vm cid")
+        .or_binder_exception(ExceptionCode::ILLEGAL_STATE)?
+        .ok_or(ExceptionCode::ILLEGAL_STATE)?
+        .parse::<u32>()
+        .context("couldn't parse vm cid")
+        .or_binder_exception(ExceptionCode::ILLEGAL_ARGUMENT)?;
+    Ok(connect_service(cid, HWCRYPTO_SERVICE_PORT)?)
+}
diff --git a/security/see/hwcrypto/aidl/vts/functional/wait_service.rs b/security/see/hwcrypto/aidl/vts/functional/wait_service.rs
new file mode 100644
index 0000000..13cbcb1
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/wait_service.rs
@@ -0,0 +1,47 @@
+// Copyright 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.
+
+//! Small utility to wait for hwcrypto service to be up
+
+use anyhow::{/*Context,*/ Result};
+use clap::Parser;
+use log::info;
+use std::{thread, time};
+
+#[derive(Parser)]
+/// Collection of CLI for trusty_security_vm_launcher
+pub struct Args {
+    /// Number of repetitions for the wait
+    #[arg(long, default_value_t = 20)]
+    number_repetitions: u32,
+
+    /// Delay between repetitiond
+    #[arg(long, default_value_t = 2)]
+    delay_between_repetitions: u32,
+}
+
+fn main() -> Result<()> {
+    let args = Args::parse();
+
+    info!("Waiting for hwcrypto service");
+    let delay = time::Duration::new(args.delay_between_repetitions.into(), 0);
+    for _ in 0..args.number_repetitions {
+        let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey();
+        if hw_crypto_key.is_ok() {
+            break;
+        }
+        thread::sleep(delay);
+    }
+    Ok(())
+}
diff --git a/sensors/aidl/android/hardware/sensors/SensorType.aidl b/sensors/aidl/android/hardware/sensors/SensorType.aidl
index adaf8e6..bc1b4b2 100644
--- a/sensors/aidl/android/hardware/sensors/SensorType.aidl
+++ b/sensors/aidl/android/hardware/sensors/SensorType.aidl
@@ -275,8 +275,9 @@
      *  than every period_ns passed to setDelay() or to batch().
      *  See the definition of the on-change reporting mode for more information.
      *
-     *  SensorInfo.requiredPermission must be set to
-     *  SENSOR_PERMISSION_BODY_SENSORS.
+     *  The framework will override the SensorInfo.requiredPermission to either
+     *  SENSOR_PERMISSION_BODY_SENSORS or SENSOR_PERMISSION_READ_HEART_RATE
+     *  depending on the platform SDK version in order to ensure compatibility.
      *
      *  Both wake-up and non wake-up versions are useful.
      */
diff --git a/threadnetwork/aidl/default/Android.bp b/threadnetwork/aidl/default/Android.bp
index a840fa3..481f027 100644
--- a/threadnetwork/aidl/default/Android.bp
+++ b/threadnetwork/aidl/default/Android.bp
@@ -45,6 +45,41 @@
     ],
 }
 
+cc_library_static {
+    name: "android.hardware.threadnetwork.lib",
+
+    vendor: true,
+    export_include_dirs: ["."],
+
+    defaults: ["android.hardware.threadnetwork-service.defaults"],
+
+    srcs: [
+        "service.cpp",
+        "thread_chip.cpp",
+        "utils.cpp",
+    ],
+
+    shared_libs: [
+        "libbinder_ndk",
+        "liblog",
+    ],
+
+    static_libs: [
+        "android.hardware.threadnetwork-V1-ndk",
+        "libbase",
+        "libcutils",
+        "libutils",
+        "openthread-common",
+        "openthread-hdlc",
+        "openthread-platform",
+        "openthread-posix",
+        "openthread-spi",
+        "openthread-url",
+    ],
+
+    stl: "c++_static",
+}
+
 cc_defaults {
     name: "android.hardware.threadnetwork-service.defaults",
     product_variables: {
diff --git a/threadnetwork/aidl/default/thread_chip.cpp b/threadnetwork/aidl/default/thread_chip.cpp
index e312728..ba0baf2 100644
--- a/threadnetwork/aidl/default/thread_chip.cpp
+++ b/threadnetwork/aidl/default/thread_chip.cpp
@@ -83,6 +83,11 @@
                 mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetFrame() + mRxFrameBuffer.GetLength()));
     }
 
+    if (mVendorCallback != nullptr) {
+        mVendorCallback->onReceiveSpinelFrame(std::vector<uint8_t>(
+                mRxFrameBuffer.GetFrame(), mRxFrameBuffer.GetFrame() + mRxFrameBuffer.GetLength()));
+    }
+
     mRxFrameBuffer.DiscardFrame();
 }
 
@@ -193,6 +198,10 @@
     }
 }
 
+void ThreadChip::setVendorCallback(const std::shared_ptr<IThreadChipCallback>& vendorCallback) {
+    mVendorCallback = vendorCallback;
+}
+
 ndk::ScopedAStatus ThreadChip::errorStatus(int32_t error, const char* message) {
     return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(error, message));
 }
diff --git a/threadnetwork/aidl/default/thread_chip.hpp b/threadnetwork/aidl/default/thread_chip.hpp
index d07d049..6f23efe 100644
--- a/threadnetwork/aidl/default/thread_chip.hpp
+++ b/threadnetwork/aidl/default/thread_chip.hpp
@@ -43,6 +43,7 @@
     ndk::ScopedAStatus hardwareReset() override;
     void Update(otSysMainloopContext& context) override;
     void Process(const otSysMainloopContext& context) override;
+    void setVendorCallback(const std::shared_ptr<IThreadChipCallback>& vendorCallback);
 
   private:
     static void onBinderDiedJump(void* context);
@@ -59,6 +60,7 @@
     std::shared_ptr<ot::Spinel::SpinelInterface> mSpinelInterface;
     ot::Spinel::SpinelInterface::RxFrameBuffer mRxFrameBuffer;
     std::shared_ptr<IThreadChipCallback> mCallback;
+    std::shared_ptr<IThreadChipCallback> mVendorCallback;
     ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
 };
 
diff --git a/wifi/OWNERS b/wifi/OWNERS
index c10bbab..ec21f2e 100644
--- a/wifi/OWNERS
+++ b/wifi/OWNERS
@@ -7,4 +7,3 @@
 # This will get them auto-assigned to the on-call triage engineer, ensuring quickest response.
 #
 arabawy@google.com
-etancohen@google.com
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index 6c7ae09..8bc9d1a 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -3895,12 +3895,13 @@
         return false;
     }
     *aidl_scan_result = {};
-    aidl_scan_result->timeStampInUs =
-            ts_us - (static_cast<uint64_t>(legacy_scan_result.age_ms) * 1000);
-    if (aidl_scan_result->timeStampInUs < 0) {
+    // Ensure that subtracting does not result in a negative value
+    uint64_t age_us = static_cast<uint64_t>(legacy_scan_result.age_ms) * 1000;
+    if (ts_us < age_us) {
         aidl_scan_result->timeStampInUs = 0;
         return false;
     }
+    aidl_scan_result->timeStampInUs = ts_us - age_us;
     size_t max_len_excluding_null = sizeof(legacy_scan_result.ssid) - 1;
     size_t ssid_len = strnlen((const char*)legacy_scan_result.ssid, max_len_excluding_null);
     aidl_scan_result->ssid =
diff --git a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
index de8f382..a172601 100644
--- a/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_chip_aidl_test.cpp
@@ -1016,6 +1016,10 @@
  */
 TEST_P(WifiChipAidlTest, GetWifiChipCapabilities) {
     WifiChipCapabilities chipCapabilities;
+    // STA iface needs to be configured for this test
+    auto iface = configureChipForStaAndGetIface();
+    ASSERT_NE(iface, nullptr);
+
     auto status = wifi_chip_->getWifiChipCapabilities(&chipCapabilities);
     if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
         GTEST_SKIP() << "getWifiChipCapabilities() is not supported by vendor.";
@@ -1027,6 +1031,10 @@
  * SetMloMode
  */
 TEST_P(WifiChipAidlTest, SetMloMode) {
+    // STA iface needs to be configured for this test
+    auto iface = configureChipForStaAndGetIface();
+    ASSERT_NE(iface, nullptr);
+
     auto status = wifi_chip_->setMloMode(IWifiChip::ChipMloMode::LOW_LATENCY);
     if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
         GTEST_SKIP() << "setMloMode() is not supported by vendor.";
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h b/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
index a757954..dbcc152 100644
--- a/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
@@ -75,15 +75,15 @@
 
 /* Pre selected Power scenarios to be applied from BDF file */
 typedef enum {
-    WIFI_POWER_SCENARIO_INVALID          = -2,
-    WIFI_POWER_SCENARIO_DEFAULT          = -1,
-    WIFI_POWER_SCENARIO_VOICE_CALL       = 0,
+    WIFI_POWER_SCENARIO_INVALID = -2,
+    WIFI_POWER_SCENARIO_DEFAULT = -1,
+    WIFI_POWER_SCENARIO_VOICE_CALL = 0,
     WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF = 1,
-    WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON  = 2,
+    WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON = 2,
     WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF = 3,
-    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON  = 4,
-    WIFI_POWER_SCENARIO_ON_BODY_BT       = 5,
-    WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT  = 6,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON = 4,
+    WIFI_POWER_SCENARIO_ON_BODY_BT = 5,
+    WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT = 6,
     WIFI_POWER_SCENARIO_ON_HEAD_HOTSPOT_MMW = 7,
     WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT = 8,
     WIFI_POWER_SCENARIO_ON_BODY_HOTSPOT = 9,
@@ -107,6 +107,10 @@
     WIFI_POWER_SCENARIO_ON_BODY_BT_UNFOLDED_CAP = 27,
     WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_UNFOLDED_CAP = 28,
     WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT_UNFOLDED_CAP = 29,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF_CAP = 30,
+    WIFI_POWER_SCENARIO_ON_BODY_BT_CAP = 31,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_CAP = 32,
+    WIFI_POWER_SCENARIO_ON_BODY_CELL_ON_BT_CAP = 33,
 } wifi_power_scenario;
 
 typedef enum {