Merge "flag: add leaudio_sw_offload" into main
diff --git a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
index cfe001e..9b7fea2 100644
--- a/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
+++ b/audio/aidl/android/hardware/audio/core/StreamDescriptor.aidl
@@ -188,6 +188,14 @@
          * In the 'DRAINING' state the producer is inactive, the consumer is
          * finishing up on the buffer contents, emptying it up. As soon as it
          * gets empty, the stream transfers itself into the next state.
+         *
+         * Note that "early notify" draining is a more complex procedure
+         * intended for transitioning between two clips. Both 'DRAINING' and
+         * 'DRAIN_PAUSED' states have "sub-states" not visible via the API. See
+         * the details in the 'stream-out-async-sm.gv' state machine
+         * description. In the HAL API V3 this behavior is enabled when the
+         * HAL exposes "aosp.clipTransitionSupport" property, and in the HAL
+         * API V4 it is the default behavior.
          */
         DRAINING = 5,
         /**
@@ -234,9 +242,15 @@
         /**
          * Used with output streams only, the HAL module indicates drain
          * completion shortly before all audio data has been consumed in order
-         * to give the client an opportunity to provide data for the next track
+         * to give the client an opportunity to provide data for the next clip
          * for gapless playback. The exact amount of provided time is specific
          * to the HAL implementation.
+         *
+         * In the HAL API V3, the HAL sends two 'onDrainReady' notifications:
+         * one to indicate readiness to receive next clip data, and another when
+         * the previous clip has finished playing. This behavior is enabled when
+         * the HAL exposes "aosp.clipTransitionSupport" property, and in the HAL
+         * API V4 it is the default behavior.
          */
         DRAIN_EARLY_NOTIFY = 2,
     }
diff --git a/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv b/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
index e2da90d..bf75594 100644
--- a/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
+++ b/audio/aidl/android/hardware/audio/core/stream-out-async-sm.gv
@@ -32,27 +32,78 @@
     IDLE -> TRANSFERRING [label="burst"];             // producer -> active
     IDLE -> ACTIVE [label="burst"];                   // full write
     ACTIVE -> PAUSED [label="pause"];                 // consumer -> passive (not consuming)
-    ACTIVE -> DRAINING [label="drain"];               // producer -> passive
+    ACTIVE -> DRAINING [label="drain(ALL)"];          // producer -> passive
+    ACTIVE -> DRAINING_en [label="drain(EARLY_NOTIFY)"];  // prepare for clip transition
     ACTIVE -> TRANSFERRING [label="burst"];           // early unblocking
     ACTIVE -> ACTIVE [label="burst"];                 // full write
     TRANSFERRING -> ACTIVE [label="←IStreamCallback.onTransferReady"];
     TRANSFERRING -> TRANSFER_PAUSED [label="pause"];  // consumer -> passive (not consuming)
-    TRANSFERRING -> DRAINING [label="drain"];         // producer -> passive
+    TRANSFERRING -> DRAINING [label="drain(ALL)"];    // producer -> passive
+    TRANSFERRING -> DRAINING_en [label="drain(EARLY_NOTIFY)"]; // prepare for clip transition
     TRANSFER_PAUSED -> TRANSFERRING [label="start"];  // consumer -> active
-    TRANSFER_PAUSED -> DRAIN_PAUSED [label="drain"];  // producer -> passive
+    TRANSFER_PAUSED -> DRAIN_PAUSED [label="drain(ALL)"];  // producer -> passive
     TRANSFER_PAUSED -> IDLE [label="flush"];          // buffer is cleared
     PAUSED -> PAUSED [label="burst"];
     PAUSED -> ACTIVE [label="start"];                 // consumer -> active
     PAUSED -> IDLE [label="flush"];                   // producer -> passive, buffer is cleared
     DRAINING -> IDLE [label="←IStreamCallback.onDrainReady"];
-    DRAINING -> DRAINING [label="←IStreamCallback.onDrainReady"];  // allowed for `DRAIN_EARLY_NOTIFY`
-    DRAINING -> IDLE [label="<empty buffer>"];        // allowed for `DRAIN_EARLY_NOTIFY`
     DRAINING -> TRANSFERRING [label="burst"];         // producer -> active
     DRAINING -> ACTIVE [label="burst"];               // full write
     DRAINING -> DRAIN_PAUSED [label="pause"];         // consumer -> passive (not consuming)
     DRAIN_PAUSED -> DRAINING [label="start"];         // consumer -> active
     DRAIN_PAUSED -> TRANSFER_PAUSED [label="burst"];  // producer -> active
     DRAIN_PAUSED -> IDLE [label="flush"];             // buffer is cleared
+    // Note that the states in both clusters are combined with 'DRAINING' and 'DRAIN_PAUSED'
+    // state at the API level. The 'en' and 'en_sent' attributes only belong to the internal
+    // state of the stream and are not observable outside.
+    subgraph cluster_early_notify_entering {
+        // The stream is preparing for a transition between two clips. After
+        // receiving 'drain(EARLY_NOTIFY)' command, the stream continues playing
+        // the current clip, and at some point notifies the client that it is
+        // ready for the next clip data by issuing the first 'onDrainReady'
+        // callback.
+        label="EARLY_NOTIFY (entering)";
+        color=gray;
+        // Getting 'burst' or 'flush' command in these states resets the "clip
+        // transition" mode.
+        DRAINING_en;
+        DRAIN_PAUSED_en;
+    }
+    subgraph cluster_early_notify_notification_sent {
+        // After the stream has sent "onDrainReady", the client can now send
+        // 'burst' commands with the data of the next clip. These 'bursts' are
+        // always "early unblocking" because the previous clip is still playing
+        // thus the stream is unable to play any of the received data
+        // synchronously (in other words, it can not do a "full write"). To
+        // indicate readiness to accept the next burst the stream uses the usual
+        // 'onTransferReady' callback.
+        label="EARLY_NOTIFY (notification sent)";
+        color=gray;
+        // The state machine remains in these states until the current clip ends
+        // playing. When it ends, the stream sends 'onDrainReady' (note that
+        // it's the second 'onDrainReady' for the same 'drain(EARLY_NOTIFY)'),
+        // and transitions either to 'IDLE' if there is no data for the next
+        // clip, or to 'TRANSFERRING' otherwise. Note that it can not transition
+        // to 'ACTIVE' because that transition is associated with
+        // 'onTransferReady' callback.
+        DRAINING_en_sent;
+        DRAIN_PAUSED_en_sent;
+    }
+    DRAINING_en -> TRANSFERRING [label="burst"];                  // producer -> active
+    DRAINING_en -> ACTIVE [label="burst"];                        // full write
+    DRAINING_en -> DRAIN_PAUSED_en [label="pause"];               // consumer -> passive (not consuming)
+    DRAINING_en -> DRAINING_en_sent [label="←IStreamCallback.onDrainReady"];
+    DRAIN_PAUSED_en -> DRAINING_en [label="start"];               // consumer -> active
+    DRAIN_PAUSED_en -> TRANSFER_PAUSED [label="burst"];           // producer -> active
+    DRAIN_PAUSED_en -> IDLE [label="flush"];                      // buffer is cleared
+    DRAINING_en_sent -> DRAINING_en_sent [label="burst"];
+    DRAINING_en_sent -> DRAINING_en_sent [label="←IStreamCallback.onTransferReady"];
+    DRAINING_en_sent -> DRAIN_PAUSED_en_sent [label="pause"];     // consumer -> passive (not consuming)
+    DRAINING_en_sent -> TRANSFERRING [label="←IStreamCallback.onDrainReady"];
+    DRAINING_en_sent -> IDLE [label="←IStreamCallback.onDrainReady"];
+    DRAIN_PAUSED_en_sent -> DRAINING_en_sent [label="start"];     // consumer -> active
+    DRAIN_PAUSED_en_sent -> DRAIN_PAUSED_en_sent [label="burst"]; // producer -> active
+    DRAIN_PAUSED_en_sent -> IDLE [label="flush"];                 // buffer is cleared
     ANY_STATE -> ERROR [label="←IStreamCallback.onError"];
     ANY_STATE -> CLOSED [label="→IStream*.close"];
     CLOSED -> F;
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index 077d80b..aa624ff 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -214,24 +214,33 @@
     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;
     if (!getSoundDose(&soundDose).isOk()) {
         LOG(ERROR) << __func__ << ": could not create sound dose instance";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
-    if (!hasMmapFlag(flags)) {
-        dataMQ = std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames);
-        streamAsyncCallback = asyncCallback;
+    StreamContext temp;
+    if (hasMmapFlag(flags)) {
+        MmapBufferDescriptor mmapDesc;
+        RETURN_STATUS_IF_ERROR(
+                createMmapBuffer(*portConfigIt, in_bufferSizeFrames, frameSize, &mmapDesc));
+        temp = StreamContext(
+                std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
+                std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
+                portConfigIt->format.value(), portConfigIt->channelMask.value(),
+                portConfigIt->sampleRate.value().value, flags, nominalLatencyMs,
+                portConfigIt->ext.get<AudioPortExt::mix>().handle, std::move(mmapDesc),
+                outEventCallback, mSoundDose.getInstance(), params);
+    } else {
+        temp = StreamContext(
+                std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
+                std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
+                portConfigIt->format.value(), portConfigIt->channelMask.value(),
+                portConfigIt->sampleRate.value().value, flags, nominalLatencyMs,
+                portConfigIt->ext.get<AudioPortExt::mix>().handle,
+                std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
+                asyncCallback, outEventCallback, mSoundDose.getInstance(), params);
     }
-    StreamContext temp(
-            std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
-            std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
-            portConfigIt->format.value(), portConfigIt->channelMask.value(),
-            portConfigIt->sampleRate.value().value, flags, nominalLatencyMs,
-            portConfigIt->ext.get<AudioPortExt::mix>().handle, std::move(dataMQ),
-            streamAsyncCallback, outEventCallback, mSoundDose.getInstance(), params);
     if (temp.isValid()) {
         *out_context = std::move(temp);
     } else {
@@ -394,9 +403,10 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
-ndk::ScopedAStatus Module::createMmapBuffer(
-        const ::aidl::android::hardware::audio::core::StreamContext& context __unused,
-        ::aidl::android::hardware::audio::core::StreamDescriptor* desc __unused) {
+ndk::ScopedAStatus Module::createMmapBuffer(const AudioPortConfig& portConfig __unused,
+                                            int32_t bufferSizeFrames __unused,
+                                            int32_t frameSizeBytes __unused,
+                                            MmapBufferDescriptor* desc __unused) {
     LOG(ERROR) << __func__ << ": " << mType << ": is not implemented";
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
@@ -612,6 +622,15 @@
     return ndk::ScopedAStatus::ok();
 }
 
+binder_status_t Module::dump(int fd, const char** args, uint32_t numArgs) {
+    for (const auto& portConfig : getConfig().portConfigs) {
+        if (portConfig.ext.getTag() == AudioPortExt::Tag::mix) {
+            getStreams().dump(portConfig.id, fd, args, numArgs);
+        }
+    }
+    return STATUS_OK;
+}
+
 ndk::ScopedAStatus Module::setModuleDebug(
         const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) {
     LOG(DEBUG) << __func__ << ": " << mType << ": old flags:" << mDebug.toString()
@@ -968,9 +987,6 @@
     RETURN_STATUS_IF_ERROR(createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames,
                                                nullptr, nullptr, &context));
     context.fillDescriptor(&_aidl_return->desc);
-    if (hasMmapFlag(context.getFlags())) {
-        RETURN_STATUS_IF_ERROR(createMmapBuffer(context, &_aidl_return->desc));
-    }
     std::shared_ptr<StreamIn> stream;
     RETURN_STATUS_IF_ERROR(createInputStream(std::move(context), in_args.sinkMetadata,
                                              getMicrophoneInfos(), &stream));
@@ -1018,9 +1034,6 @@
                                                isNonBlocking ? in_args.callback : nullptr,
                                                in_args.eventCallback, &context));
     context.fillDescriptor(&_aidl_return->desc);
-    if (hasMmapFlag(context.getFlags())) {
-        RETURN_STATUS_IF_ERROR(createMmapBuffer(context, &_aidl_return->desc));
-    }
     std::shared_ptr<StreamOut> stream;
     RETURN_STATUS_IF_ERROR(createOutputStream(std::move(context), in_args.sourceMetadata,
                                               in_args.offloadInfo, &stream));
@@ -1546,6 +1559,7 @@
 
 const std::string Module::VendorDebug::kForceTransientBurstName = "aosp.forceTransientBurst";
 const std::string Module::VendorDebug::kForceSynchronousDrainName = "aosp.forceSynchronousDrain";
+const std::string Module::kClipTransitionSupportName = "aosp.clipTransitionSupport";
 
 ndk::ScopedAStatus Module::getVendorParameters(const std::vector<std::string>& in_ids,
                                                std::vector<VendorParameter>* _aidl_return) {
@@ -1560,6 +1574,10 @@
             VendorParameter forceSynchronousDrain{.id = id};
             forceSynchronousDrain.ext.setParcelable(Boolean{mVendorDebug.forceSynchronousDrain});
             _aidl_return->push_back(std::move(forceSynchronousDrain));
+        } else if (id == kClipTransitionSupportName) {
+            VendorParameter clipTransitionSupport{.id = id};
+            clipTransitionSupport.ext.setParcelable(Boolean{true});
+            _aidl_return->push_back(std::move(clipTransitionSupport));
         } else {
             allParametersKnown = false;
             LOG(VERBOSE) << __func__ << ": " << mType << ": unrecognized parameter \"" << id << "\"";
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index c6c1b5d..873fc48 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -65,18 +65,26 @@
     if (mReplyMQ) {
         desc->reply = mReplyMQ->dupeDesc();
     }
+    desc->frameSizeBytes = getFrameSize();
+    desc->bufferSizeFrames = getBufferSizeInFrames();
     if (mDataMQ) {
-        desc->frameSizeBytes = getFrameSize();
-        desc->bufferSizeFrames = getBufferSizeInFrames();
         desc->audio.set<StreamDescriptor::AudioBuffer::Tag::fmq>(mDataMQ->dupeDesc());
+    } else {
+        MmapBufferDescriptor mmapDesc;  // Move-only due to `fd`.
+        mmapDesc.sharedMemory.fd = mMmapBufferDesc.sharedMemory.fd.dup();
+        mmapDesc.sharedMemory.size = mMmapBufferDesc.sharedMemory.size;
+        mmapDesc.burstSizeFrames = mMmapBufferDesc.burstSizeFrames;
+        mmapDesc.flags = mMmapBufferDesc.flags;
+        desc->audio.set<StreamDescriptor::AudioBuffer::Tag::mmap>(std::move(mmapDesc));
     }
 }
 
 size_t StreamContext::getBufferSizeInFrames() const {
     if (mDataMQ) {
         return mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize() / getFrameSize();
+    } else {
+        return mMmapBufferDesc.sharedMemory.size / getFrameSize();
     }
-    return 0;
 }
 
 size_t StreamContext::getFrameSize() const {
@@ -96,9 +104,13 @@
         LOG(ERROR) << "frame size is invalid";
         return false;
     }
-    if (!hasMmapFlag(mFlags) && mDataMQ && !mDataMQ->isValid()) {
+    if (!isMmap() && mDataMQ && !mDataMQ->isValid()) {
         LOG(ERROR) << "data FMQ is invalid";
         return false;
+    } else if (isMmap() &&
+               (mMmapBufferDesc.sharedMemory.fd.get() == -1 ||
+                mMmapBufferDesc.sharedMemory.size == 0 || mMmapBufferDesc.burstSizeFrames == 0)) {
+        LOG(ERROR) << "mmap info is invalid" << mMmapBufferDesc.toString();
     }
     return true;
 }
@@ -115,6 +127,7 @@
     mCommandMQ.reset();
     mReplyMQ.reset();
     mDataMQ.reset();
+    mMmapBufferDesc.sharedMemory.fd.set(-1);
 }
 
 pid_t StreamWorkerCommonLogic::getTid() const {
@@ -128,7 +141,7 @@
 std::string StreamWorkerCommonLogic::init() {
     if (mContext->getCommandMQ() == nullptr) return "Command MQ is null";
     if (mContext->getReplyMQ() == nullptr) return "Reply MQ is null";
-    if (!hasMmapFlag(mContext->getFlags())) {
+    if (!mContext->isMmap()) {
         StreamContext::DataMQ* const dataMQ = mContext->getDataMQ();
         if (dataMQ == nullptr) return "Data MQ is null";
         if (sizeof(DataBufferElement) != dataMQ->getQuantumSize()) {
@@ -167,7 +180,7 @@
     } else {
         reply->observable = reply->hardware = kUnknownPosition;
     }
-    if (hasMmapFlag(mContext->getFlags())) {
+    if (mContext->isMmap()) {
         if (auto status = mDriver->getMmapPositionAndLatency(&reply->hardware, &reply->latencyMs);
             status != ::android::OK) {
             reply->hardware = kUnknownPosition;
@@ -252,9 +265,9 @@
                     mState == StreamDescriptor::State::ACTIVE ||
                     mState == StreamDescriptor::State::PAUSED ||
                     mState == StreamDescriptor::State::DRAINING) {
-                    if (hasMmapFlag(mContext->getFlags())) {
-                        populateReply(&reply, mIsConnected);
-                    } else if (!read(fmqByteCount, &reply)) {
+                    if (bool success =
+                                mContext->isMmap() ? readMmap(&reply) : read(fmqByteCount, &reply);
+                        !success) {
                         mState = StreamDescriptor::State::ERROR;
                     }
                     if (mState == StreamDescriptor::State::IDLE ||
@@ -383,16 +396,38 @@
     return !fatal;
 }
 
+bool StreamInWorkerLogic::readMmap(StreamDescriptor::Reply* reply) {
+    void* buffer = nullptr;
+    size_t frameCount = 0;
+    size_t actualFrameCount = 0;
+    int32_t latency = mContext->getNominalLatencyMs();
+    // use default-initialized parameter values for mmap stream.
+    if (::android::status_t status =
+                mDriver->transfer(buffer, frameCount, &actualFrameCount, &latency);
+        status == ::android::OK) {
+        populateReply(reply, mIsConnected);
+        reply->latencyMs = latency;
+        return true;
+    } else {
+        LOG(ERROR) << __func__ << ": transfer failed: " << status;
+        return false;
+    }
+}
+
 const std::string StreamOutWorkerLogic::kThreadName = "writer";
 
 void StreamOutWorkerLogic::onBufferStateChange(size_t bufferFramesLeft) {
     const StreamDescriptor::State state = mState;
-    LOG(DEBUG) << __func__ << ": state: " << toString(state)
+    const DrainState drainState = mDrainState;
+    LOG(DEBUG) << __func__ << ": state: " << toString(state) << ", drainState: " << drainState
                << ", bufferFramesLeft: " << bufferFramesLeft;
-    if (state == StreamDescriptor::State::TRANSFERRING) {
-        mState = StreamDescriptor::State::ACTIVE;
+    if (state == StreamDescriptor::State::TRANSFERRING || drainState == DrainState::EN_SENT) {
+        if (state == StreamDescriptor::State::TRANSFERRING) {
+            mState = StreamDescriptor::State::ACTIVE;
+        }
         std::shared_ptr<IStreamCallback> asyncCallback = mContext->getAsyncCallback();
         if (asyncCallback != nullptr) {
+            LOG(VERBOSE) << __func__ << ": sending onTransferReady";
             ndk::ScopedAStatus status = asyncCallback->onTransferReady();
             if (!status.isOk()) {
                 LOG(ERROR) << __func__ << ": error from onTransferReady: " << status;
@@ -411,8 +446,10 @@
         mState =
                 hasNextClip ? StreamDescriptor::State::TRANSFERRING : StreamDescriptor::State::IDLE;
         mDrainState = DrainState::NONE;
-        if (drainState == DrainState::ALL && asyncCallback != nullptr) {
+        if ((drainState == DrainState::ALL || drainState == DrainState::EN_SENT) &&
+            asyncCallback != nullptr) {
             LOG(DEBUG) << __func__ << ": sending onDrainReady";
+            // For EN_SENT, this is the second onDrainReady which notifies about clip transition.
             ndk::ScopedAStatus status = asyncCallback->onDrainReady();
             if (!status.isOk()) {
                 LOG(ERROR) << __func__ << ": error from onDrainReady: " << status;
@@ -523,9 +560,9 @@
                 if (mState != StreamDescriptor::State::ERROR &&
                     mState != StreamDescriptor::State::TRANSFERRING &&
                     mState != StreamDescriptor::State::TRANSFER_PAUSED) {
-                    if (hasMmapFlag(mContext->getFlags())) {
-                        populateReply(&reply, mIsConnected);
-                    } else if (!write(fmqByteCount, &reply)) {
+                    if (bool success = mContext->isMmap() ? writeMmap(&reply)
+                                                          : write(fmqByteCount, &reply);
+                        !success) {
                         mState = StreamDescriptor::State::ERROR;
                     }
                     std::shared_ptr<IStreamCallback> asyncCallback = mContext->getAsyncCallback();
@@ -539,13 +576,17 @@
                             mState = StreamDescriptor::State::TRANSFER_PAUSED;
                         }
                     } else if (mState == StreamDescriptor::State::IDLE ||
-                               mState == StreamDescriptor::State::DRAINING ||
-                               mState == StreamDescriptor::State::ACTIVE) {
+                               mState == StreamDescriptor::State::ACTIVE ||
+                               (mState == StreamDescriptor::State::DRAINING &&
+                                mDrainState != DrainState::EN_SENT)) {
                         if (asyncCallback == nullptr || reply.fmqByteCount == fmqByteCount) {
                             mState = StreamDescriptor::State::ACTIVE;
                         } else {
                             switchToTransientState(StreamDescriptor::State::TRANSFERRING);
                         }
+                    } else if (mState == StreamDescriptor::State::DRAINING &&
+                               mDrainState == DrainState::EN_SENT) {
+                        // keep mState
                     }
                 } else {
                     populateReplyWrongState(&reply, command);
@@ -700,6 +741,24 @@
     return !fatal;
 }
 
+bool StreamOutWorkerLogic::writeMmap(StreamDescriptor::Reply* reply) {
+    void* buffer = nullptr;
+    size_t frameCount = 0;
+    size_t actualFrameCount = 0;
+    int32_t latency = mContext->getNominalLatencyMs();
+    // use default-initialized parameter values for mmap stream.
+    if (::android::status_t status =
+                mDriver->transfer(buffer, frameCount, &actualFrameCount, &latency);
+        status == ::android::OK) {
+        populateReply(reply, mIsConnected);
+        reply->latencyMs = latency;
+        return true;
+    } else {
+        LOG(ERROR) << __func__ << ": transfer failed: " << status;
+        return false;
+    }
+}
+
 StreamCommonImpl::~StreamCommonImpl() {
     // It is responsibility of the class that implements 'DriverInterface' to call 'cleanupWorker'
     // in the destructor. Note that 'cleanupWorker' can not be properly called from this destructor
diff --git a/audio/aidl/default/include/core-impl/DriverStubImpl.h b/audio/aidl/default/include/core-impl/DriverStubImpl.h
index a1a6c82..84f869a 100644
--- a/audio/aidl/default/include/core-impl/DriverStubImpl.h
+++ b/audio/aidl/default/include/core-impl/DriverStubImpl.h
@@ -22,7 +22,9 @@
 
 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(DriverCallbackInterface* callback) override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
@@ -40,6 +42,8 @@
     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 6a43102..379264d 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -61,6 +61,8 @@
     // The vendor extension done via inheritance can override interface methods and augment
     // a call to the base implementation.
 
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
     ndk::ScopedAStatus setModuleDebug(
             const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
     ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
@@ -159,6 +161,7 @@
     // Multimap because both ports and configs can be used by multiple patches.
     using Patches = std::multimap<int32_t, int32_t>;
 
+    static const std::string kClipTransitionSupportName;
     const Type mType;
     std::unique_ptr<Configuration> mConfig;
     ModuleDebug mDebug;
@@ -209,8 +212,8 @@
             const ::aidl::android::media::audio::common::AudioFormatDescription &format,
             int32_t latencyMs, int32_t sampleRateHz, int32_t *bufferSizeFrames);
     virtual ndk::ScopedAStatus createMmapBuffer(
-            const ::aidl::android::hardware::audio::core::StreamContext& context,
-            ::aidl::android::hardware::audio::core::StreamDescriptor* desc);
+            const ::aidl::android::media::audio::common::AudioPortConfig& portConfig,
+            int32_t bufferSizeFrames, int32_t frameSizeBytes, MmapBufferDescriptor* desc);
 
     // Utility and helper functions accessible to subclasses.
     static int32_t calculateBufferSizeFramesForPcm(int32_t latencyMs, int32_t sampleRateHz) {
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index f0139b4..bb790e9 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -104,6 +104,27 @@
           mOutEventCallback(outEventCallback),
           mStreamDataProcessor(streamDataProcessor),
           mDebugParameters(debugParameters) {}
+    StreamContext(std::unique_ptr<CommandMQ> commandMQ, std::unique_ptr<ReplyMQ> replyMQ,
+                  const ::aidl::android::media::audio::common::AudioFormatDescription& format,
+                  const ::aidl::android::media::audio::common::AudioChannelLayout& channelLayout,
+                  int sampleRate, const ::aidl::android::media::audio::common::AudioIoFlags& flags,
+                  int32_t nominalLatencyMs, int32_t mixPortHandle, MmapBufferDescriptor&& mmapDesc,
+                  std::shared_ptr<IStreamOutEventCallback> outEventCallback,
+                  std::weak_ptr<sounddose::StreamDataProcessorInterface> streamDataProcessor,
+                  DebugParameters debugParameters)
+        : mCommandMQ(std::move(commandMQ)),
+          mInternalCommandCookie(std::rand() | 1 /* make sure it's not 0 */),
+          mReplyMQ(std::move(replyMQ)),
+          mFormat(format),
+          mChannelLayout(channelLayout),
+          mSampleRate(sampleRate),
+          mFlags(flags),
+          mNominalLatencyMs(nominalLatencyMs),
+          mMixPortHandle(mixPortHandle),
+          mMmapBufferDesc(std::move(mmapDesc)),
+          mOutEventCallback(outEventCallback),
+          mStreamDataProcessor(streamDataProcessor),
+          mDebugParameters(debugParameters) {}
 
     void fillDescriptor(StreamDescriptor* desc);
     std::shared_ptr<IStreamCallback> getAsyncCallback() const { return mAsyncCallback; }
@@ -136,6 +157,7 @@
     bool isInput() const {
         return mFlags.getTag() == ::aidl::android::media::audio::common::AudioIoFlags::input;
     }
+    bool isMmap() const { return ::aidl::android::hardware::audio::common::hasMmapFlag(mFlags); }
     bool isValid() const;
     // 'reset' is called on a Binder thread when closing the stream. Does not use
     // locking because it only cleans MQ pointers which were also set on the Binder thread.
@@ -155,7 +177,9 @@
     ::aidl::android::media::audio::common::AudioIoFlags mFlags;
     int32_t mNominalLatencyMs;
     int32_t mMixPortHandle;
+    // Only one of `mDataMQ` or `mMapBufferDesc` can be active, depending on `isMmap`
     std::unique_ptr<DataMQ> mDataMQ;
+    MmapBufferDescriptor mMmapBufferDesc;
     std::shared_ptr<IStreamCallback> mAsyncCallback;
     std::shared_ptr<IStreamOutEventCallback> mOutEventCallback;  // Only used by output streams
     std::weak_ptr<sounddose::StreamDataProcessorInterface> mStreamDataProcessor;
@@ -307,6 +331,7 @@
 
   private:
     bool read(size_t clientSize, StreamDescriptor::Reply* reply);
+    bool readMmap(StreamDescriptor::Reply* reply);
 };
 using StreamInWorker = StreamWorkerImpl<StreamInWorkerLogic>;
 
@@ -325,6 +350,7 @@
 
   private:
     bool write(size_t clientSize, StreamDescriptor::Reply* reply);
+    bool writeMmap(StreamDescriptor::Reply* reply);
 
     std::shared_ptr<IStreamOutEventCallback> mEventCallback;
 
@@ -651,6 +677,12 @@
         return ndk::ScopedAStatus::ok();
     }
 
+    void dump(int fd, const char** args, uint32_t numArgs) const {
+        auto s = ::ndk::ICInterface::asInterface(mStreamBinder.get());
+        if (s) s->dump(fd, args, numArgs);
+        return;
+    }
+
   private:
     std::weak_ptr<StreamCommonInterface> mStream;
     ndk::SpAIBinder mStreamBinder;
@@ -692,6 +724,12 @@
         }
         return ndk::ScopedAStatus::ok();
     }
+    void dump(int32_t portConfigId, int fd, const char** args, uint32_t numArgs) const {
+        if (auto it = mStreams.find(portConfigId); it != mStreams.end()) {
+            it->second.dump(fd, args, numArgs);
+        }
+        return;
+    }
 
   private:
     // Maps port ids and port config ids to streams. Multimap because a port
diff --git a/audio/aidl/default/include/core-impl/StreamOffloadStub.h b/audio/aidl/default/include/core-impl/StreamOffloadStub.h
index 3b452f9..24e98c2 100644
--- a/audio/aidl/default/include/core-impl/StreamOffloadStub.h
+++ b/audio/aidl/default/include/core-impl/StreamOffloadStub.h
@@ -26,14 +26,16 @@
 namespace aidl::android::hardware::audio::core {
 
 struct DspSimulatorState {
+    static constexpr int64_t kSkipBufferNotifyFrames = -1;
+
     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);
+    int64_t bufferFramesLeft GUARDED_BY(lock) = 0;
+    int64_t bufferNotifyFrames GUARDED_BY(lock) = kSkipBufferNotifyFrames;
 };
 
 class DspSimulatorLogic : public ::android::hardware::audio::common::StreamLogic {
@@ -60,11 +62,15 @@
     ::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();
+
+    const int64_t mBufferNotifyFrames;
     DspSimulatorState mState;
     DspSimulatorWorker mDspWorker;
     bool mDspWorkerStarted = false;
diff --git a/audio/aidl/default/stub/DriverStubImpl.cpp b/audio/aidl/default/stub/DriverStubImpl.cpp
index 107affb..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) {}
+
+#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
index fb12697..155f76d 100644
--- a/audio/aidl/default/stub/StreamOffloadStub.cpp
+++ b/audio/aidl/default/stub/StreamOffloadStub.cpp
@@ -42,14 +42,13 @@
     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;
+    int64_t bufferFramesLeft = 0, bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
     {
         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: "
@@ -65,10 +64,21 @@
                 clipNotifies.emplace_back(0 /*clipFramesLeft*/, hasNextClip);
                 framesPlayed -= mSharedState.clipFramesLeft[0];
                 mSharedState.clipFramesLeft.erase(mSharedState.clipFramesLeft.begin());
+                if (!hasNextClip) {
+                    // Since it's a simulation, the buffer consumption rate it not real,
+                    // thus 'bufferFramesLeft' might still have something, need to erase it.
+                    mSharedState.bufferFramesLeft = 0;
+                }
             }
         }
+        bufferFramesLeft = mSharedState.bufferFramesLeft;
+        bufferNotifyFrames = mSharedState.bufferNotifyFrames;
+        if (bufferFramesLeft <= bufferNotifyFrames) {
+            // Suppress further notifications.
+            mSharedState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
+        }
     }
-    if (bufferFramesLeft <= mSharedState.bufferNotifyFrames) {
+    if (bufferFramesLeft <= bufferNotifyFrames) {
         LOG(DEBUG) << __func__ << ": sending onBufferStateChange: " << bufferFramesLeft;
         mSharedState.callback->onBufferStateChange(bufferFramesLeft);
     }
@@ -81,11 +91,13 @@
 }
 
 DriverOffloadStubImpl::DriverOffloadStubImpl(const StreamContext& context)
-    : DriverStubImpl(context),
+    : DriverStubImpl(context, 0 /*asyncSleepTimeUs*/),
+      mBufferNotifyFrames(static_cast<int64_t>(context.getBufferSizeInFrames()) / 2),
       mState{context.getFormat().encoding, context.getSampleRate(),
-             250 /*earlyNotifyMs*/ * context.getSampleRate() / MILLIS_PER_SECOND,
-             static_cast<int64_t>(context.getBufferSizeInFrames()) / 2},
-      mDspWorker(mState) {}
+             250 /*earlyNotifyMs*/ * context.getSampleRate() / MILLIS_PER_SECOND},
+      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));
@@ -99,10 +111,7 @@
 }
 
 ::android::status_t DriverOffloadStubImpl::drain(StreamDescriptor::DrainMode drainMode) {
-    // Does not call into the DriverStubImpl::drain.
-    if (!mIsInitialized) {
-        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
-    }
+    RETURN_STATUS_IF_ERROR(DriverStubImpl::drain(drainMode));
     std::lock_guard l(mState.lock);
     if (!mState.clipFramesLeft.empty()) {
         // Cut playback of the current clip.
@@ -112,6 +121,7 @@
             mState.clipFramesLeft.resize(1);
         }
     }
+    mState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
     return ::android::OK;
 }
 
@@ -122,6 +132,7 @@
         std::lock_guard l(mState.lock);
         mState.clipFramesLeft.clear();
         mState.bufferFramesLeft = 0;
+        mState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
     }
     return ::android::OK;
 }
@@ -129,26 +140,35 @@
 ::android::status_t DriverOffloadStubImpl::pause() {
     RETURN_STATUS_IF_ERROR(DriverStubImpl::pause());
     mDspWorker.pause();
+    {
+        std::lock_guard l(mState.lock);
+        mState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
+    }
+    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);
+        mState.bufferNotifyFrames = DspSimulatorState::kSkipBufferNotifyFrames;
+    }
+    if (hasClips) {
+        mDspWorker.resume();
+    }
     return ::android::OK;
 }
 
 ::android::status_t DriverOffloadStubImpl::transfer(void* buffer, size_t frameCount,
-                                                    size_t* actualFrameCount,
-                                                    int32_t* /*latencyMs*/) {
-    // Does not call into the DriverStubImpl::transfer.
-    if (!mIsInitialized) {
-        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
-    }
-    if (mIsStandby) {
-        LOG(FATAL) << __func__ << ": must not happen while in standby";
-    }
-    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;
-    }
+                                                    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) {
@@ -181,6 +201,7 @@
     {
         std::lock_guard l(mState.lock);
         mState.bufferFramesLeft = *actualFrameCount;
+        mState.bufferNotifyFrames = mBufferNotifyFrames;
     }
     mDspWorker.resume();
     return ::android::OK;
@@ -189,6 +210,18 @@
 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
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index c007f18..2fc126e 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -140,12 +140,12 @@
 
 TEST_P(AECParamTest, SetAndGetEchoDelay) {
     addEchoDelayParam(mEchoDelay);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 TEST_P(AECParamTest, SetAndGetMobileMode) {
     addMobileModeParam(mMobileMode);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
index 72a2d5e..033cb9d 100644
--- a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -140,17 +140,17 @@
 
 TEST_P(AGC1ParamTest, SetAndGetTargetPeakLevelParam) {
     addTargetPeakLevelParam(mTargetPeakLevel);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 TEST_P(AGC1ParamTest, SetAndGetMaxCompressionGain) {
     addMaxCompressionGainParam(mMaxCompressionGain);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 TEST_P(AGC1ParamTest, SetAndGetEnableLimiter) {
     addEnableLimiterParam(mEnableLimiter);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
index ccac8c5..9dec383 100644
--- a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -146,17 +146,17 @@
 
 TEST_P(AGC2ParamTest, SetAndGetDigitalGainParam) {
     addDigitalGainParam(mGain);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 TEST_P(AGC2ParamTest, SetAndGetSaturationMargin) {
     addSaturationMarginParam(mMargin);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 TEST_P(AGC2ParamTest, SetAndGetLevelEstimator) {
     addLevelEstimatorParam(mLevelEstimator);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
diff --git a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
index 7b15e5e..713af9a 100644
--- a/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreConfigTargetTest.cpp
@@ -367,8 +367,15 @@
             auto criterionValue = criterionRule.criterionAndValue;
             auto matchesWhen = criterionRule.matchingRule;
             auto criteriaIt = find_if(criteria.begin(), criteria.end(), [&](const auto& criterion) {
+                auto getForceConfigTag = [](const AudioHalCapCriterionV2& forceConfig) {
+                    return forceConfig.get<AudioHalCapCriterionV2::forceConfigForUse>()
+                            .values[0].getTag();
+                };
                 return criterion.has_value() &&
-                       criterion.value().getTag() == selectionCriterion.getTag();
+                       criterion.value().getTag() == selectionCriterion.getTag() &&
+                       (criterion.value().getTag() != AudioHalCapCriterionV2::forceConfigForUse ||
+                        getForceConfigTag(criterion.value()) ==
+                                getForceConfigTag(selectionCriterion));
             });
             EXPECT_NE(criteriaIt, criteria.end())
                     << " Invalid rule criterion " << toString(selectionCriterion.getTag());
@@ -515,7 +522,8 @@
         std::unordered_set<std::string> configurationNames;
         for (const AudioHalCapConfiguration& configuration : domain.configurations) {
             EXPECT_TRUE(configurationNames.insert(configuration.name).second);
-            ValidateAudioHalConfigurationRule(configuration.rule, criteria);
+            ASSERT_NO_FATAL_FAILURE(
+                    ValidateAudioHalConfigurationRule(configuration.rule, criteria));
         }
         auto domainParameters = domain.configurations[0].parameterSettings;
         for (const auto& settingParameter : domainParameters) {
@@ -590,7 +598,8 @@
             }
             EXPECT_NO_FATAL_FAILURE(ValidateAudioHalCapCriterion(criterion.value()));
         }
-        ValidateAudioHalCapDomains(capCfg.domains.value(), capCfg.criteriaV2.value());
+        ASSERT_NO_FATAL_FAILURE(
+                ValidateAudioHalCapDomains(capCfg.domains.value(), capCfg.criteriaV2.value()));
     }
 
     /**
diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
index 8bbb60b..806c93f 100644
--- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp
@@ -1025,6 +1025,7 @@
             auto [eventSeq, event] = mEventReceiver->waitForEvent(mLastEventSeq);
             mLastEventSeq = eventSeq;
             if (event != *expEvent) {
+                // TODO: Make available as an error so it can be displayed by GTest
                 LOG(ERROR) << __func__ << ": expected event " << toString(*expEvent) << ", got "
                            << toString(event);
                 return {};
@@ -1327,7 +1328,8 @@
   public:
     // To avoid timing out the whole test suite in case no event is received
     // from the HAL, use a local timeout for event waiting.
-    static constexpr auto kEventTimeoutMs = std::chrono::milliseconds(1000);
+    // TODO: The timeout for 'onTransferReady' should depend on the buffer size.
+    static constexpr auto kEventTimeoutMs = std::chrono::milliseconds(3000);
 
     StreamEventReceiver* getEventReceiver() { return this; }
     std::tuple<int, Event> getLastEvent() const override {
@@ -4236,15 +4238,17 @@
 enum {
     NAMED_CMD_NAME,
     NAMED_CMD_MIN_INTERFACE_VERSION,
+    NAMED_CMD_FEATURE_PROPERTY,
     NAMED_CMD_DELAY_MS,
     NAMED_CMD_STREAM_TYPE,
     NAMED_CMD_CMDS,
     NAMED_CMD_VALIDATE_POS_INCREASE
 };
-enum class StreamTypeFilter { ANY, SYNC, ASYNC };
+enum class StreamTypeFilter { ANY, SYNC, ASYNC, OFFLOAD };
 using NamedCommandSequence =
-        std::tuple<std::string, int /*minInterfaceVersion*/, int /*cmdDelayMs*/, StreamTypeFilter,
-                   std::shared_ptr<StateSequence>, bool /*validatePositionIncrease*/>;
+        std::tuple<std::string, int /*minInterfaceVersion*/, std::string /*featureProperty*/,
+                   int /*cmdDelayMs*/, StreamTypeFilter, std::shared_ptr<StateSequence>,
+                   bool /*validatePositionIncrease*/>;
 enum { PARAM_MODULE_NAME, PARAM_CMD_SEQ, PARAM_SETUP_SEQ };
 using StreamIoTestParameters =
         std::tuple<std::string /*moduleName*/, NamedCommandSequence, bool /*useSetupSequence2*/>;
@@ -4255,11 +4259,24 @@
     void SetUp() override {
         ASSERT_NO_FATAL_FAILURE(SetUpImpl(std::get<PARAM_MODULE_NAME>(GetParam())));
         ASSERT_GE(aidlVersion, kAidlVersion1);
-        if (const int minVersion =
-                    std::get<NAMED_CMD_MIN_INTERFACE_VERSION>(std::get<PARAM_CMD_SEQ>(GetParam()));
-            aidlVersion < minVersion) {
+        const int minVersion =
+                std::get<NAMED_CMD_MIN_INTERFACE_VERSION>(std::get<PARAM_CMD_SEQ>(GetParam()));
+        if (aidlVersion < minVersion) {
             GTEST_SKIP() << "Skip for audio HAL version lower than " << minVersion;
         }
+        // When an associated feature property is defined, need to check that either that the HAL
+        // exposes this property, or it's of the version 'NAMED_CMD_MIN_INTERFACE_VERSION' + 1
+        // which must have this functionality implemented by default.
+        if (const std::string featureProperty =
+                    std::get<NAMED_CMD_FEATURE_PROPERTY>(std::get<PARAM_CMD_SEQ>(GetParam()));
+            !featureProperty.empty() && aidlVersion < (minVersion + 1)) {
+            std::vector<VendorParameter> parameters;
+            ScopedAStatus result = module->getVendorParameters({featureProperty}, &parameters);
+            if (!result.isOk() || parameters.size() != 1) {
+                GTEST_SKIP() << "Skip as audio HAL does not support feature \"" << featureProperty
+                             << "\"";
+            }
+        }
         ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig());
     }
 
@@ -4300,10 +4317,18 @@
                             isBitPositionFlagSet(portConfig.flags.value()
                                                          .template get<AudioIoFlags::Tag::output>(),
                                                  AudioOutputFlags::NON_BLOCKING);
+            const bool isOffload =
+                    IOTraits<Stream>::is_input
+                            ? false
+                            : isBitPositionFlagSet(
+                                      portConfig.flags.value()
+                                              .template get<AudioIoFlags::Tag::output>(),
+                                      AudioOutputFlags::COMPRESS_OFFLOAD);
             if (auto streamType =
                         std::get<NAMED_CMD_STREAM_TYPE>(std::get<PARAM_CMD_SEQ>(GetParam()));
                 (isNonBlocking && streamType == StreamTypeFilter::SYNC) ||
-                (!isNonBlocking && streamType == StreamTypeFilter::ASYNC)) {
+                (!isNonBlocking && streamType == StreamTypeFilter::ASYNC) ||
+                (!isOffload && streamType == StreamTypeFilter::OFFLOAD)) {
                 continue;
             }
             WithDebugFlags delayTransientStates = WithDebugFlags::createNested(*debug);
@@ -4760,6 +4785,18 @@
 
 // TODO: Add async test cases for input once it is implemented.
 
+// Allow optional routing via the TRANSFERRING state on bursts.
+StateDag::Node makeAsyncBurstCommands(StateDag* d, size_t burstCount, StateDag::Node last) {
+    using State = StreamDescriptor::State;
+    std::reference_wrapper<std::remove_reference_t<StateDag::Node>> prev = last;
+    for (size_t i = 0; i < burstCount; ++i) {
+        StateDag::Node active = d->makeNode(State::ACTIVE, kBurstCommand, prev);
+        active.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, prev));
+        prev = active;
+    }
+    return prev;
+}
+
 std::shared_ptr<StateSequence> makeBurstCommands(bool isSync, size_t burstCount,
                                                  bool standbyInputWhenDone) {
     using State = StreamDescriptor::State;
@@ -4776,25 +4813,21 @@
                 d->makeNodes(State::ACTIVE, kBurstCommand, burstCount, last));
         d->makeNode(State::STANDBY, kStartCommand, idle);
     } else {
-        StateDag::Node active2 = d->makeNode(State::ACTIVE, kBurstCommand, last);
-        StateDag::Node active = d->makeNode(State::ACTIVE, kBurstCommand, active2);
+        StateDag::Node active = makeAsyncBurstCommands(d.get(), burstCount, last);
         StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
-        // Allow optional routing via the TRANSFERRING state on bursts.
-        active2.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, last));
-        active.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active2));
         idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
         d->makeNode(State::STANDBY, kStartCommand, idle);
     }
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kReadSeq =
-        std::make_tuple(std::string("Read"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+        std::make_tuple(std::string("Read"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
                         makeBurstCommands(true), true /*validatePositionIncrease*/);
 static const NamedCommandSequence kWriteSyncSeq =
-        std::make_tuple(std::string("Write"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+        std::make_tuple(std::string("Write"), kAidlVersion1, "", 0, StreamTypeFilter::SYNC,
                         makeBurstCommands(true), true /*validatePositionIncrease*/);
 static const NamedCommandSequence kWriteAsyncSeq =
-        std::make_tuple(std::string("Write"), kAidlVersion1, 0, StreamTypeFilter::ASYNC,
+        std::make_tuple(std::string("Write"), kAidlVersion1, "", 0, StreamTypeFilter::ASYNC,
                         makeBurstCommands(false), true /*validatePositionIncrease*/);
 
 std::shared_ptr<StateSequence> makeAsyncDrainCommands(bool isInput) {
@@ -4824,10 +4857,10 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kWriteDrainAsyncSeq = std::make_tuple(
-        std::string("WriteDrain"), kAidlVersion1, kStreamTransientStateTransitionDelayMs,
+        std::string("WriteDrain"), kAidlVersion1, "", kStreamTransientStateTransitionDelayMs,
         StreamTypeFilter::ASYNC, makeAsyncDrainCommands(false), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kDrainInSeq =
-        std::make_tuple(std::string("Drain"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+        std::make_tuple(std::string("Drain"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
                         makeAsyncDrainCommands(true), false /*validatePositionIncrease*/);
 
 std::shared_ptr<StateSequence> makeDrainOutCommands(bool isSync) {
@@ -4849,10 +4882,10 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kDrainOutSyncSeq =
-        std::make_tuple(std::string("Drain"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+        std::make_tuple(std::string("Drain"), kAidlVersion1, "", 0, StreamTypeFilter::SYNC,
                         makeDrainOutCommands(true), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kDrainOutAsyncSeq =
-        std::make_tuple(std::string("Drain"), kAidlVersion3, 0, StreamTypeFilter::ASYNC,
+        std::make_tuple(std::string("Drain"), kAidlVersion3, "", 0, StreamTypeFilter::ASYNC,
                         makeDrainOutCommands(false), false /*validatePositionIncrease*/);
 
 std::shared_ptr<StateSequence> makeDrainEarlyOutCommands() {
@@ -4873,9 +4906,32 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kDrainEarlyOutAsyncSeq =
-        std::make_tuple(std::string("DrainEarly"), kAidlVersion3, 0, StreamTypeFilter::ASYNC,
+        std::make_tuple(std::string("DrainEarly"), kAidlVersion3, "", 0, StreamTypeFilter::ASYNC,
                         makeDrainEarlyOutCommands(), false /*validatePositionIncrease*/);
 
+// DRAINING_en ->(onDrainReady) DRAINING_en_sent ->(onDrainReady) IDLE | TRANSFERRING
+std::shared_ptr<StateSequence> makeDrainEarlyOffloadCommands() {
+    using State = StreamDescriptor::State;
+    auto d = std::make_unique<StateDag>();
+    StateDag::Node lastIdle = d->makeFinalNode(State::IDLE);
+    StateDag::Node lastTransferring = d->makeFinalNode(State::TRANSFERRING);
+    // The second onDrainReady event.
+    StateDag::Node continueDraining =
+            d->makeNode(State::DRAINING, kDrainReadyEvent, lastIdle, lastTransferring);
+    // The first onDrainReady event.
+    StateDag::Node draining = d->makeNode(State::DRAINING, kDrainReadyEvent, continueDraining);
+    StateDag::Node drain = d->makeNode(State::ACTIVE, kDrainOutEarlyCommand, draining);
+    StateDag::Node active = makeAsyncBurstCommands(d.get(), 10, drain);
+    StateDag::Node idle = d->makeNode(State::IDLE, kBurstCommand, active);
+    idle.children().push_back(d->makeNode(State::TRANSFERRING, kTransferReadyEvent, active));
+    d->makeNode(State::STANDBY, kStartCommand, idle);
+    return std::make_shared<StateSequenceFollower>(std::move(d));
+}
+static const NamedCommandSequence kDrainEarlyOffloadSeq =
+        std::make_tuple(std::string("DrainEarly"), kAidlVersion3, "aosp.clipTransitionSupport", 0,
+                        StreamTypeFilter::OFFLOAD, makeDrainEarlyOffloadCommands(),
+                        true /*validatePositionIncrease*/);
+
 std::shared_ptr<StateSequence> makeDrainPauseOutCommands(bool isSync) {
     using State = StreamDescriptor::State;
     auto d = std::make_unique<StateDag>();
@@ -4896,11 +4952,11 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kDrainPauseOutSyncSeq =
-        std::make_tuple(std::string("DrainPause"), kAidlVersion1,
+        std::make_tuple(std::string("DrainPause"), kAidlVersion1, "",
                         kStreamTransientStateTransitionDelayMs, StreamTypeFilter::SYNC,
                         makeDrainPauseOutCommands(true), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kDrainPauseOutAsyncSeq =
-        std::make_tuple(std::string("DrainPause"), kAidlVersion1,
+        std::make_tuple(std::string("DrainPause"), kAidlVersion1, "",
                         kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
                         makeDrainPauseOutCommands(false), false /*validatePositionIncrease*/);
 
@@ -4919,7 +4975,7 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kDrainEarlyPauseOutAsyncSeq =
-        std::make_tuple(std::string("DrainEarlyPause"), kAidlVersion3,
+        std::make_tuple(std::string("DrainEarlyPause"), kAidlVersion3, "",
                         kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
                         makeDrainEarlyPauseOutCommands(), false /*validatePositionIncrease*/);
 
@@ -4963,13 +5019,13 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kStandbyInSeq =
-        std::make_tuple(std::string("Standby"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+        std::make_tuple(std::string("Standby"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
                         makeStandbyCommands(true, false), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kStandbyOutSyncSeq =
-        std::make_tuple(std::string("Standby"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+        std::make_tuple(std::string("Standby"), kAidlVersion1, "", 0, StreamTypeFilter::SYNC,
                         makeStandbyCommands(false, true), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kStandbyOutAsyncSeq =
-        std::make_tuple(std::string("Standby"), kAidlVersion1,
+        std::make_tuple(std::string("Standby"), kAidlVersion1, "",
                         kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
                         makeStandbyCommands(false, false), false /*validatePositionIncrease*/);
 
@@ -5006,15 +5062,15 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kPauseInSeq =
-        std::make_tuple(std::string("Pause"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+        std::make_tuple(std::string("Pause"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
                         makePauseCommands(true, false), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kPauseOutSyncSeq =
-        std::make_tuple(std::string("Pause"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+        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,
-                        StreamTypeFilter::ASYNC, makePauseCommands(false, false),
-                        false /*validatePositionIncrease*/);
+        std::make_tuple(std::string("Pause"), kAidlVersion3, "",
+                        kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
+                        makePauseCommands(false, false), false /*validatePositionIncrease*/);
 
 std::shared_ptr<StateSequence> makeFlushCommands(bool isInput, bool isSync) {
     using State = StreamDescriptor::State;
@@ -5042,15 +5098,15 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kFlushInSeq =
-        std::make_tuple(std::string("Flush"), kAidlVersion1, 0, StreamTypeFilter::ANY,
+        std::make_tuple(std::string("Flush"), kAidlVersion1, "", 0, StreamTypeFilter::ANY,
                         makeFlushCommands(true, false), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kFlushOutSyncSeq =
-        std::make_tuple(std::string("Flush"), kAidlVersion1, 0, StreamTypeFilter::SYNC,
+        std::make_tuple(std::string("Flush"), kAidlVersion1, "", 0, StreamTypeFilter::SYNC,
                         makeFlushCommands(false, true), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kFlushOutAsyncSeq =
-        std::make_tuple(std::string("Flush"), kAidlVersion1, kStreamTransientStateTransitionDelayMs,
-                        StreamTypeFilter::ASYNC, makeFlushCommands(false, false),
-                        false /*validatePositionIncrease*/);
+        std::make_tuple(std::string("Flush"), kAidlVersion1, "",
+                        kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
+                        makeFlushCommands(false, false), false /*validatePositionIncrease*/);
 
 std::shared_ptr<StateSequence> makeDrainPauseFlushOutCommands(bool isSync) {
     using State = StreamDescriptor::State;
@@ -5070,11 +5126,11 @@
     return std::make_shared<StateSequenceFollower>(std::move(d));
 }
 static const NamedCommandSequence kDrainPauseFlushOutSyncSeq =
-        std::make_tuple(std::string("DrainPauseFlush"), kAidlVersion1,
+        std::make_tuple(std::string("DrainPauseFlush"), kAidlVersion1, "",
                         kStreamTransientStateTransitionDelayMs, StreamTypeFilter::SYNC,
                         makeDrainPauseFlushOutCommands(true), false /*validatePositionIncrease*/);
 static const NamedCommandSequence kDrainPauseFlushOutAsyncSeq =
-        std::make_tuple(std::string("DrainPauseFlush"), kAidlVersion1,
+        std::make_tuple(std::string("DrainPauseFlush"), kAidlVersion1, "",
                         kStreamTransientStateTransitionDelayMs, StreamTypeFilter::ASYNC,
                         makeDrainPauseFlushOutCommands(false), false /*validatePositionIncrease*/);
 
@@ -5087,6 +5143,8 @@
             return "Sync";
         case StreamTypeFilter::ASYNC:
             return "Async";
+        case StreamTypeFilter::OFFLOAD:
+            return "Offload";
     }
     return std::string("Unknown").append(std::to_string(static_cast<int32_t>(filter)));
 }
@@ -5117,10 +5175,10 @@
                                          kDrainOutSyncSeq, kDrainOutAsyncSeq,
                                          kDrainEarlyOutAsyncSeq, kDrainPauseOutSyncSeq,
                                          kDrainPauseOutAsyncSeq, kDrainEarlyPauseOutAsyncSeq,
-                                         kStandbyOutSyncSeq, kStandbyOutAsyncSeq,
-                                         kPauseOutSyncSeq,  // kPauseOutAsyncSeq,
-                                         kFlushOutSyncSeq, kFlushOutAsyncSeq,
-                                         kDrainPauseFlushOutSyncSeq, kDrainPauseFlushOutAsyncSeq),
+                                         kStandbyOutSyncSeq, kStandbyOutAsyncSeq, kPauseOutSyncSeq,
+                                         kPauseOutAsyncSeq, kFlushOutSyncSeq, kFlushOutAsyncSeq,
+                                         kDrainPauseFlushOutSyncSeq, kDrainPauseFlushOutAsyncSeq,
+                                         kDrainEarlyOffloadSeq),
                          testing::Values(false, true)),
         GetStreamIoTestName);
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioStreamIoOut);
diff --git a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
index a19aa56..5621285 100644
--- a/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectFactoryTargetTest.cpp
@@ -56,7 +56,7 @@
 /// Effect factory testing.
 class EffectFactoryTest : public testing::TestWithParam<std::string> {
   public:
-    void SetUp() override { connectAndGetFactory(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(connectAndGetFactory()); }
 
     void TearDown() override {
         for (auto& effect : mEffects) {
@@ -253,7 +253,7 @@
     creatAndDestroyDescs(descs);
 
     restartAndGetFactory();
-    connectAndGetFactory();
+    ASSERT_NO_FATAL_FAILURE(connectAndGetFactory());
     creatAndDestroyDescs(descs);
 }
 
@@ -265,7 +265,7 @@
     std::vector<std::shared_ptr<IEffect>> effects = createWithDescs(descs);
 
     restartAndGetFactory();
-    connectAndGetFactory();
+    ASSERT_NO_FATAL_FAILURE(connectAndGetFactory());
     destroyEffects(effects, EX_ILLEGAL_ARGUMENT);
 }
 
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index 5c5be3a..720a040 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -190,7 +190,7 @@
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
 
-    void SetUp() override { SetUpDownmix(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDownmix()); }
 
     void TearDown() override { TearDownDownmix(); }
 
@@ -216,7 +216,7 @@
 
     void SetUp() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
-        SetUpDownmix(mInputChannelLayout);
+        ASSERT_NO_FATAL_FAILURE(SetUpDownmix(mInputChannelLayout));
         if (int32_t version;
             mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
             GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
@@ -288,7 +288,7 @@
             case AudioChannelLayout::CHANNEL_TOP_BACK_LEFT:
             case AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT:
             case AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT:
-                checkAtLeft(position);
+                ASSERT_NO_FATAL_FAILURE(checkAtLeft(position));
                 break;
 
             case AudioChannelLayout::CHANNEL_FRONT_RIGHT:
@@ -300,7 +300,7 @@
             case AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT:
             case AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT:
             case AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2:
-                checkAtRight(position);
+                ASSERT_NO_FATAL_FAILURE(checkAtRight(position));
                 break;
 
             case AudioChannelLayout::CHANNEL_FRONT_CENTER:
@@ -311,17 +311,17 @@
             case AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER:
             case AudioChannelLayout::CHANNEL_TOP_CENTER:
             case AudioChannelLayout::CHANNEL_TOP_BACK_CENTER:
-                checkAtCenter(position);
+                ASSERT_NO_FATAL_FAILURE(checkAtCenter(position));
                 break;
 
             case AudioChannelLayout::CHANNEL_LOW_FREQUENCY:
                 // If CHANNEL_LOW_FREQUENCY_2 is supported
                 if (mInputChannelLayout & AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2) {
                     // Validate that only Left channel has audio
-                    checkAtLeft(position);
+                    ASSERT_NO_FATAL_FAILURE(checkAtLeft(position));
                 } else {
                     // Validate that both channels have audio
-                    checkAtCenter(position);
+                    ASSERT_NO_FATAL_FAILURE(checkAtCenter(position));
                 }
                 break;
         }
@@ -371,7 +371,7 @@
     }
 
     void SetUp() override {
-        SetUpDownmix(mInputChannelLayout);
+        ASSERT_NO_FATAL_FAILURE(SetUpDownmix(mInputChannelLayout));
         if (int32_t version;
             mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
             GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
@@ -406,7 +406,7 @@
                         mInputChannelCount /*channelCount*/, kMaxDownmixSample);
     ASSERT_NO_FATAL_FAILURE(
             processAndWriteToOutput(mInputBuffer, mOutputBuffer, mEffect, &mOpenEffectReturn));
-    validateOutput();
+    ASSERT_NO_FATAL_FAILURE(validateOutput());
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 95bcaf0..2ce7b51 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -39,6 +39,8 @@
 using aidl::android::hardware::audio::effect::Parameter;
 using android::hardware::audio::common::testing::detail::TestExecutionTracer;
 
+constexpr int32_t kMinDataTestHalVersion = 3;
+
 /**
  * Here we focus on specific parameter checking, general IEffect interfaces testing performed in
  * VtsAudioEffectTargetTest.
@@ -120,6 +122,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);
@@ -131,13 +141,32 @@
     void addLimiterConfig(const std::vector<DynamicsProcessing::LimiterConfig>& cfg);
     void addInputGain(const std::vector<DynamicsProcessing::InputGain>& inputGain);
 
+    void checkHalVersion();
+
     static constexpr float kPreferredProcessingDurationMs = 10.0f;
     static constexpr int kBandCount = 5;
     static constexpr int kSamplingFrequency = 44100;
     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 +445,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;
@@ -491,6 +552,13 @@
     mTags.push_back({DynamicsProcessing::inputGain, dp});
 }
 
+void DynamicsProcessingTestHelper::checkHalVersion() {
+    if (int32_t version;
+        mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
+        GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
+    }
+}
+
 void fillLimiterConfig(std::vector<DynamicsProcessing::LimiterConfig>& limiterConfigList,
                        int channelIndex, bool enable, int linkGroup, float attackTime,
                        float releaseTime, float ratio, float threshold, float postGain) {
@@ -527,6 +595,15 @@
                                              .postGainDb = postGainDb};
 }
 
+DynamicsProcessing::EqBandConfig creatEqBandConfig(int channel, int band, float cutOffFreqHz,
+                                                   float gainDb, bool enable) {
+    return DynamicsProcessing::EqBandConfig{.channel = channel,
+                                            .band = band,
+                                            .enable = enable,
+                                            .cutoffFrequencyHz = cutOffFreqHz,
+                                            .gainDb = gainDb};
+}
+
 /**
  * Test DynamicsProcessing Engine Configuration
  */
@@ -558,7 +635,7 @@
         fillEngineArchConfig(mCfg, GetParam());
     };
 
-    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
@@ -610,7 +687,7 @@
         : DynamicsProcessingTestHelper(std::get<INPUT_GAIN_INSTANCE_NAME>(GetParam())),
           mInputGain(std::get<INPUT_GAIN_PARAM>(GetParam())) {};
 
-    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
@@ -650,11 +727,8 @@
     }
 
     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);
+        ASSERT_NO_FATAL_FAILURE(
+                setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb));
     }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -665,8 +739,6 @@
     }
 
     std::vector<DynamicsProcessing::InputGain> mInputGain;
-    std::vector<float> mInput;
-    float mInputDb;
 };
 
 TEST_P(DynamicsProcessingInputGainDataTest, SetAndGetInputGain) {
@@ -735,7 +807,7 @@
         fillLimiterConfig(mLimiterConfigList, GetParam());
     }
 
-    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
@@ -786,12 +858,8 @@
     }
 
     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);
+                setUpDataTest({static_cast<int>(kInputFrequency)}, kSineFullScaleDb));
     }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
@@ -825,11 +893,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 +914,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 +941,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 +959,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 +969,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 +992,7 @@
         if (isEnabled) {
             EXPECT_NE(mInputDb, calculateDb(output, kStartIndex));
         } else {
-            EXPECT_NEAR(mInputDb, calculateDb(output, kStartIndex), kToleranceDb);
+            EXPECT_NEAR(mInputDb, calculateDb(output, kStartIndex), kLimiterTestToleranceDb);
         }
     }
 }
@@ -963,7 +1028,7 @@
         : DynamicsProcessingTestHelper(std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(GetParam())),
           mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())) {}
 
-    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
@@ -1025,13 +1090,10 @@
                       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),
+                                         true));
     }
 }
 
@@ -1043,7 +1105,7 @@
         fillEqBandConfig(mCfgs, GetParam());
     }
 
-    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
@@ -1147,6 +1209,130 @@
         });
 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, bool enable) {
+        cfgs.push_back(creatEqBandConfig(channelIndex, bandIndex, static_cast<float>(cutOffFreqHz),
+                                         gainDb, enable));
+    }
+
+    void validateOutput(const std::vector<float>& output, float gainDb, size_t bandIndex,
+                        bool enable) {
+        std::vector<float> outputMag(mBinOffsets.size());
+        EXPECT_NO_FATAL_FAILURE(getMagnitudeValue(output, outputMag));
+        if (gainDb == 0 || !enable) {
+            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, bool enable = true) {
+        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, enable);
+                fillEqBandConfig(mCfgs, channelIndex, i ^ 1, kCutoffFreqHz[i ^ 1], 0, enable);
+            }
+            ASSERT_NO_FATAL_FAILURE(setEqParamAndProcess(output, isPreEq));
+
+            if (isAllParamsValid()) {
+                ASSERT_NO_FATAL_FAILURE(validateOutput(output, gainDb, i, enable));
+            }
+            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*/));
+    }
+}
+
+TEST_P(DynamicsProcessingEqBandConfigDataTest, PreEqEnableDisable) {
+    ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(10 /*gain dB*/, true /*pre-equalizer*/,
+                                                   false /*disable equalizer*/));
+}
+
+TEST_P(DynamicsProcessingEqBandConfigDataTest, PostEqEnableDisable) {
+    ASSERT_NO_FATAL_FAILURE(analyseMultiBandOutput(10 /*gain dB*/, false /*post-equalizer*/,
+                                                   false /*disable 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
  */
@@ -1211,7 +1397,7 @@
         fillMbcBandConfig(mCfgs, GetParam());
     }
 
-    void SetUp() override { SetUpDynamicsProcessingEffect(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpDynamicsProcessingEffect()); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
@@ -1259,24 +1445,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);
@@ -1293,23 +1473,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]);
@@ -1318,17 +1487,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));
 
@@ -1345,8 +1513,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;
@@ -1356,20 +1522,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) {
@@ -1396,11 +1549,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,
@@ -1417,6 +1570,51 @@
     }
 }
 
+TEST_P(DynamicsProcessingMbcBandConfigDataTest, IncreasingPreGain) {
+    /*
+    Depending on the pregain values, samples undergo either compression or expansion process.
+    At -6 dB input,
+    - Expansion is expected at -60 dB,
+    - Compression at 10, 34 and 60 dB
+    - No compression or expansion at -34, -10, -1 dB.
+     */
+    std::vector<float> preGainDbValues = {-60, -34, -10, -1, 10, 34, 60};
+    std::vector<float> output(mInput.size());
+    float thresholdDb = -7;
+    float noiseGateDb = -40;
+    std::vector<float> ratioValues = {1, 1.5, 2, 2.5, 3};
+    for (float ratio : ratioValues) {
+        for (float preGainDb : preGainDbValues) {
+            float expectedOutputDb;
+            float inputWithPreGain = mInputDb + preGainDb;
+            if (inputWithPreGain > thresholdDb) {
+                SCOPED_TRACE("Compressor ratio: " + std::to_string(ratio));
+                expectedOutputDb =
+                        (inputWithPreGain - thresholdDb) / ratio + thresholdDb - preGainDb;
+            } else if (inputWithPreGain < noiseGateDb) {
+                SCOPED_TRACE("Expander ratio: " + std::to_string(ratio));
+                expectedOutputDb =
+                        (inputWithPreGain - noiseGateDb) * ratio + noiseGateDb - preGainDb;
+            } else {
+                expectedOutputDb = mInputDb;
+            }
+            cleanUpMbcConfig();
+            for (int i = 0; i < mChannelCount; i++) {
+                fillMbcBandConfig(mCfgs, i, thresholdDb, ratio /*compressor ratio*/, noiseGateDb,
+                                  ratio /*expander ratio*/, 0 /*band index*/,
+                                  2000 /*cutoffFrequency*/, preGainDb, kDefaultPostGainDb);
+            }
+            EXPECT_NO_FATAL_FAILURE(setMbcParamsAndProcess(output));
+            if (!isAllParamsValid()) {
+                continue;
+            }
+            float outputDb = calculateDb(output, kStartIndex);
+            EXPECT_NEAR(outputDb, expectedOutputDb, kToleranceDb)
+                    << "PreGain: " << preGainDb << ", OutputDb: " << outputDb;
+        }
+    }
+}
+
 INSTANTIATE_TEST_SUITE_P(DynamicsProcessingTest, DynamicsProcessingMbcBandConfigDataTest,
                          testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                  IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 0222923..9b1a3b3 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -305,7 +305,7 @@
         : EnvironmentalReverbHelper(std::get<DESCRIPTOR_INDEX>(GetParam())) {
         std::tie(mTag, mParamValue) = std::get<TAG_VALUE_PAIR>(GetParam());
     }
-    void SetUp() override { SetUpReverb(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpReverb()); }
     void TearDown() override { TearDownReverb(); }
 
     EnvironmentalReverb::Tag mTag;
@@ -350,7 +350,7 @@
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
         ASSERT_NO_FATAL_FAILURE(
                 generateSineWave(kInputFrequency, mInput, 1.0, kSamplingFrequency, mChannelLayout));
-        SetUpReverb();
+        ASSERT_NO_FATAL_FAILURE(SetUpReverb());
     }
     void TearDown() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
@@ -387,11 +387,11 @@
 };
 
 TEST_P(EnvironmentalReverbDataTest, IncreasingParamValue) {
-    assertEnergyIncreasingWithParameter(false);
+    ASSERT_NO_FATAL_FAILURE(assertEnergyIncreasingWithParameter(false));
 }
 
 TEST_P(EnvironmentalReverbDataTest, WithBypassEnabled) {
-    assertZeroEnergyWithBypass(true);
+    ASSERT_NO_FATAL_FAILURE(assertZeroEnergyWithBypass(true));
 }
 
 INSTANTIATE_TEST_SUITE_P(
@@ -420,7 +420,7 @@
     }
     void SetUp() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
-        SetUpReverb();
+        ASSERT_NO_FATAL_FAILURE(SetUpReverb());
         createEnvParam(EnvironmentalReverb::roomLevelMb, kMinRoomLevel);
         ASSERT_NO_FATAL_FAILURE(
                 setAndVerifyParam(EX_NONE, mEnvParam, EnvironmentalReverb::roomLevelMb));
@@ -478,7 +478,7 @@
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
         ASSERT_NO_FATAL_FAILURE(
                 generateSineWave(kInputFrequency, mInput, 1.0, kSamplingFrequency, mChannelLayout));
-        SetUpReverb();
+        ASSERT_NO_FATAL_FAILURE(SetUpReverb());
     }
     void TearDown() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
@@ -559,7 +559,7 @@
             ASSERT_NO_FATAL_FAILURE(generateSineWave(kInputFrequency, mInput, 1.0,
                                                      kSamplingFrequency, mChannelLayout));
         }
-        SetUpReverb();
+        ASSERT_NO_FATAL_FAILURE(SetUpReverb());
     }
     void TearDown() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index 0c931ff..86177fc 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -18,10 +18,10 @@
 #include <string>
 #include <vector>
 
+#define LOG_TAG "VtsHalEqualizerTest"
 #include <aidl/Gtest.h>
 #include <aidl/android/hardware/audio/effect/IEffect.h>
 #include <aidl/android/hardware/audio/effect/IFactory.h>
-#define LOG_TAG "VtsHalEqualizerTest"
 #include <android-base/logging.h>
 #include <android-base/properties.h>
 #include <android/binder_interface_utils.h>
@@ -48,8 +48,8 @@
  */
 
 enum ParamName { PARAM_INSTANCE_NAME, PARAM_PRESET, PARAM_BAND_LEVEL };
-using EqualizerParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
-                                           std::vector<Equalizer::BandLevel>>;
+using EqualizerTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
+                                      std::vector<Equalizer::BandLevel>>;
 
 /*
 Testing parameter range, assuming the parameter supported by effect is in this range.
@@ -58,38 +58,34 @@
 */
 const std::vector<int> kBandLevels = {0, -10, 10};  // needs update with implementation
 
-class EqualizerTest : public ::testing::TestWithParam<EqualizerParamTestParam>,
-                      public EffectHelper {
+class EqualizerTestHelper : public EffectHelper {
   public:
-    EqualizerTest()
-        : mPresetIndex(std::get<PARAM_PRESET>(GetParam())),
-          mBandLevel(std::get<PARAM_BAND_LEVEL>(GetParam())) {
-        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    EqualizerTestHelper(std::pair<std::shared_ptr<IFactory>, Descriptor> descPair,
+                        int presetIndex = 0,
+                        std::vector<Equalizer::BandLevel> bandLevel =
+                                std::vector<Equalizer::BandLevel>{
+                                        Equalizer::BandLevel({.index = 0, .levelMb = 0})})
+        : mFactory(descPair.first), mPresetIndex(presetIndex), mBandLevel(bandLevel) {
+        mDescriptor = descPair.second;
     }
 
-    void SetUp() override {
+    void SetUpEqualizer() {
         ASSERT_NE(nullptr, mFactory);
         ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
 
         Parameter::Common common = createParamCommon(
                 0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
                 kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
-        IEffect::OpenEffectReturn ret;
-        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &ret, EX_NONE));
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, std::nullopt, &mOpenEffectReturn, EX_NONE));
         ASSERT_NE(nullptr, mEffect);
     }
-    void TearDown() override {
+
+    void TearDownEqualizer() {
         ASSERT_NO_FATAL_FAILURE(close(mEffect));
         ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+        mOpenEffectReturn = IEffect::OpenEffectReturn{};
     }
 
-    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
-    std::shared_ptr<IFactory> mFactory;
-    std::shared_ptr<IEffect> mEffect;
-    Descriptor mDescriptor;
-    int mPresetIndex;
-    std::vector<Equalizer::BandLevel> mBandLevel;
-
     void SetAndGetEqualizerParameters() {
         ASSERT_NE(nullptr, mEffect);
         for (auto& it : mTags) {
@@ -167,26 +163,45 @@
         mTags.push_back({Equalizer::preset, Equalizer::make<Equalizer::preset>(preset)});
     }
 
-    void addBandLevelsParam(std::vector<Equalizer::BandLevel>& bandLevels) {
+    void addBandLevelsParam(const std::vector<Equalizer::BandLevel>& bandLevels) {
         mTags.push_back(
                 {Equalizer::bandLevels, Equalizer::make<Equalizer::bandLevels>(bandLevels)});
     }
 
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    const std::shared_ptr<IFactory> mFactory;
+    const int mPresetIndex;
+    const std::vector<Equalizer::BandLevel> mBandLevel;
+    std::shared_ptr<IEffect> mEffect;
+    IEffect::OpenEffectReturn mOpenEffectReturn;
+
   private:
     std::vector<std::pair<Equalizer::Tag, Equalizer>> mTags;
-
     void CleanUp() { mTags.clear(); }
 };
 
-TEST_P(EqualizerTest, SetAndGetParams) {
+class EqualizerParamTest : public ::testing::TestWithParam<EqualizerTestParam>,
+                           public EqualizerTestHelper {
+  public:
+    EqualizerParamTest()
+        : EqualizerTestHelper(std::get<PARAM_INSTANCE_NAME>(GetParam()),
+                              std::get<PARAM_PRESET>(GetParam()),
+                              std::get<PARAM_BAND_LEVEL>(GetParam())) {}
+
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpEqualizer()); }
+
+    void TearDown() override { ASSERT_NO_FATAL_FAILURE(TearDownEqualizer()); }
+};
+
+TEST_P(EqualizerParamTest, SetAndGetParams) {
     addBandLevelsParam(mBandLevel);
     addPresetParam(mPresetIndex);
-    EXPECT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
+    ASSERT_NO_FATAL_FAILURE(SetAndGetEqualizerParameters());
 }
 
 std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
 INSTANTIATE_TEST_SUITE_P(
-        EqualizerTest, EqualizerTest,
+        EqualizerParamTest, EqualizerParamTest,
         ::testing::Combine(
                 testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
                                           IFactory::descriptor, getEffectTypeUuidEqualizer())),
@@ -200,7 +215,7 @@
                                 [](std::set<std::vector<Equalizer::BandLevel>>& bandLevels) {
                                     return bandLevels;
                                 }))),
-        [](const testing::TestParamInfo<EqualizerTest::ParamType>& info) {
+        [](const testing::TestParamInfo<EqualizerParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string bandLevel =
                     ::android::internal::ToString(std::get<PARAM_BAND_LEVEL>(info.param));
@@ -211,7 +226,7 @@
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
         });
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerTest);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EqualizerParamTest);
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index ace0597..a263bff 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;
@@ -133,7 +135,7 @@
         std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
     }
 
-    void SetUp() override { SetUpLoudnessEnhancer(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpLoudnessEnhancer()); }
     void TearDown() override { TearDownLoudnessEnhancer(); }
     int mParamGainMb = 0;
 };
@@ -164,7 +166,7 @@
 
     void SetUp() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
-        SetUpLoudnessEnhancer();
+        ASSERT_NO_FATAL_FAILURE(SetUpLoudnessEnhancer());
 
         // Creating AidlMessageQueues
         mStatusMQ = std::make_unique<EffectHelper::StatusMQ>(mOpenEffectReturn.statusMQ);
@@ -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());
 
@@ -255,13 +261,13 @@
 TEST_P(LoudnessEnhancerDataTest, IncreasingGains) {
     static const std::vector<int> kIncreasingGains = {50, 100};
 
-    assertSequentialGains(kIncreasingGains, true /*isIncreasing*/);
+    ASSERT_NO_FATAL_FAILURE(assertSequentialGains(kIncreasingGains, true /*isIncreasing*/));
 }
 
 TEST_P(LoudnessEnhancerDataTest, DecreasingGains) {
     static const std::vector<int> kDecreasingGains = {-50, -100};
 
-    assertSequentialGains(kDecreasingGains, false /*isIncreasing*/);
+    ASSERT_NO_FATAL_FAILURE(assertSequentialGains(kDecreasingGains, false /*isIncreasing*/));
 }
 
 TEST_P(LoudnessEnhancerDataTest, MinimumGain) {
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index c5a9bad..0618048 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -141,12 +141,12 @@
 
 TEST_P(NSParamTest, SetAndGetLevel) {
     addLevelParam(mLevel);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 TEST_P(NSParamTest, SetAndGetType) {
     addLevelParam(mLevel);
-    SetAndGetParameters();
+    ASSERT_NO_FATAL_FAILURE(SetAndGetParameters());
 }
 
 INSTANTIATE_TEST_SUITE_P(
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index f127c81..3fbda96 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -187,13 +187,13 @@
     std::vector<PresetReverb::Presets> roomPresets = {PresetReverb::Presets::LARGEROOM,
                                                       PresetReverb::Presets::MEDIUMROOM,
                                                       PresetReverb::Presets::SMALLROOM};
-    validateIncreasingEnergy(roomPresets);
+    ASSERT_NO_FATAL_FAILURE(validateIncreasingEnergy(roomPresets));
 }
 
 TEST_P(PresetReverbProcessTest, DecreasingHallSize) {
     std::vector<PresetReverb::Presets> hallPresets = {PresetReverb::Presets::LARGEHALL,
                                                       PresetReverb::Presets::MEDIUMHALL};
-    validateIncreasingEnergy(hallPresets);
+    ASSERT_NO_FATAL_FAILURE(validateIncreasingEnergy(hallPresets));
 }
 
 TEST_P(PresetReverbProcessTest, PresetPlate) {
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index f019e2a..586ed67 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -183,7 +183,7 @@
         generateInputBuffer(mInputBuffer, 0, true, mChannelCount, kMaxAudioSampleValue);
     }
 
-    void SetUp() override { SetUpVisualizer(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpVisualizer()); }
 
     void TearDown() override { TearDownVisualizer(); }
 
@@ -252,7 +252,7 @@
                                std::get<PARAM_SCALING_MODE>(GetParam()),
                                std::get<PARAM_MEASUREMENT_MODE>(GetParam())) {}
 
-    void SetUp() override { SetUpVisualizer(); }
+    void SetUp() override { ASSERT_NO_FATAL_FAILURE(SetUpVisualizer()); }
 
     void TearDown() override { TearDownVisualizer(); }
 };
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 9ca4366..cb1b94b 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -40,7 +40,8 @@
      * Note that this property only represents the minimum value at boot time
      * and may not represent the current actual minimum value.
      *
-     * Only applicable for {@code INT32} type property. Ignored for other types.
+     * Only applicable for {@code INT32} type property. For other types, must be
+     * 0.
      *
      * For certain properties, this field must be specified, see
      * {@code VehicleProperty} documentation.
@@ -60,10 +61,13 @@
      * boot time, both {@code minInt32Value} and {@code maxInt32Value} must be
      * set to 0.
      *
-     * Note that this property only represents the minimum value at boot time
-     * and may not represent the current actual minimum value.
+     * Note that this property only represents the maximum value at boot time
+     * and may not represent the current actual maximum value.
      *
-     * Only applicable for {@code INT32} type property. Ignored for other types.
+     * Only applicable for {@code INT32} type property. For other types, must be
+     * 0.
+     *
+     * Must be larger or equal to {@code minInt32Value}.
      *
      * For certain properties, this field must be specified, see
      * {@code VehicleProperty} documentation.
@@ -86,7 +90,8 @@
      * Note that this property only represents the minimum value at boot time
      * and may not represent the current actual minimum value.
      *
-     * Only applicable for {@code INT64} type property. Ignored for other types.
+     * Only applicable for {@code INT64} type property. For other types, must be
+     * 0.
      *
      * For certain properties, this field must be specified, see
      * {@code VehicleProperty} documentation.
@@ -106,10 +111,13 @@
      * boot time, both {@code minInt64Value} and {@code maxInt64Value} must be
      * set to 0.
      *
-     * Note that this property only represents the minimum value at boot time
-     * and may not represent the current actual minimum value.
+     * Note that this property only represents the maximum value at boot time
+     * and may not represent the current actual maximum value.
      *
-     * Only applicable for {@code INT64} type property. Ignored for other types.
+     * Only applicable for {@code INT64} type property. For other types, must be
+     * 0.
+     *
+     * Must be larger or equal to {@code minInt64Value}.
      *
      * For certain properties, this field must be specified, see
      * {@code VehicleProperty} documentation.
@@ -132,7 +140,8 @@
      * Note that this property only represents the minimum value at boot time
      * and may not represent the current actual minimum value.
      *
-     * Only applicable for {@code FLOAT} type property. Ignored for other types.
+     * Only applicable for {@code FLOAT} type property. For other types, must be
+     * 0.
      *
      * For certain properties, this field must be specified, see
      * {@code VehicleProperty} documentation.
@@ -152,10 +161,13 @@
      * boot time, both {@code minFloatValue} and {@code maxFloatValue} must be
      * set to 0.
      *
-     * Note that this property only represents the minimum value at boot time
-     * and may not represent the current actual minimum value.
+     * Note that this property only represents the maximum value at boot time
+     * and may not represent the current actual maximum value.
      *
-     * Only applicable for {@code FLOAT} type property. Ignored for other types.
+     * Only applicable for {@code FLOAT} type property. For other types, must be
+     * 0.
+     *
+     * Must be larger or equal to {@code minFloatValue}.
      *
      * For certain properties, this field must be specified, see
      * {@code VehicleProperty} documentation.
diff --git a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
index 92681de..e7c03ad 100644
--- a/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
+++ b/automotive/vehicle/aidl/emu_metadata/android.hardware.automotive.vehicle-types-meta.json
@@ -1215,7 +1215,7 @@
             {
                 "name": "REMOVE_USER",
                 "value": 299896586,
-                "description": "Called by the Android System after an Android user was removed.\nThe HAL can use this property to remove its equivalent user.\nThis is write-only call - the Android System is not expecting a reply from the HAL. Hence, this request should not fail - if the equivalent HAL user cannot be removed, then HAL should mark it as inactive or recover in some other way.\nThe request is made by setting the VehiclePropValue with the contents defined by RemoveUserRequest.\nFor example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request would be:\nint32[0]: 42  \/\/ request id int32[1]: 11  \/\/ (Android user id of the removed user) int32[2]: 0   \/\/ (Android user flags of the removed user) int32[3]: 10  \/\/ current user int32[4]: 0   \/\/ current user flags (none) int32[5]: 2   \/\/ number of users int32[6]: 0   \/\/ 1st user (user 0) int32[7]: 0   \/\/ 1st user flags (none) int32[8]: 10  \/\/ 2nd user (user 10) int32[9]: 0   \/\/ 2nd user flags (none)"
+                "description": "Called by the Android System after an Android user was removed.\nThe HAL can use this property to remove its equivalent user.\nThis is write-only call - the Android System is not expecting a reply from the HAL. Hence, this request should not fail - if the equivalent HAL user cannot be removed, then HAL should mark it as inactive or recover in some other way.\nThe request is made by setting the VehiclePropValue with the contents defined by RemoveUserRequest.\nFor example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request would be:\nint32[0]: 42  \/\/ request id int32[1]: 11  \/\/ (Android user id of the removed user) int32[2]: 0   \/\/ (Android user flags of the removed user) int32[3]: 10  \/\/ current user int32[4]: 0   \/\/ current user flags (none) int32[5]: 2   \/\/ number of users int32[6]: 0   \/\/ 1st user (user 0) int32[7]: 0   \/\/ 1st user flags (none) int32[8]: 10  \/\/ 2nd user (user 10) int32[9]: 0   \/\/ 2nd user flags (none)\nBefore Android B, this property's change mode was defined as STATIC although the property value may be updated from Android side. For backward compatibility, we still allow STATIC as change mode, but for new implementations, ON_CHANGE should be used instead."
             },
             {
                 "name": "USER_IDENTIFICATION_ASSOCIATION",
diff --git a/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
index ca07ecf..685b010 100644
--- a/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
@@ -235,7 +235,7 @@
         {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::SWITCH_USER, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::CREATE_USER, VehiclePropertyChangeMode::ON_CHANGE},
-        {VehicleProperty::REMOVE_USER, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::REMOVE_USER, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::EVS_SERVICE_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::POWER_POLICY_REQ, VehiclePropertyChangeMode::ON_CHANGE},
diff --git a/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
index cf44887..39a9c42 100644
--- a/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
@@ -233,7 +233,7 @@
         Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.SWITCH_USER, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.CREATE_USER, VehiclePropertyChangeMode.ON_CHANGE),
-        Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.EVS_SERVICE_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.POWER_POLICY_REQ, VehiclePropertyChangeMode.ON_CHANGE),
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 2915cc1..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",
@@ -164,83 +164,47 @@
             "property": "VehicleProperty::SEAT_MEMORY_SELECT",
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::SEAT_MEMORY_SET",
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::SEAT_BELT_BUCKLED",
@@ -276,51 +240,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_BELT_HEIGHT_MOVE",
@@ -331,51 +271,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_FORE_AFT_POS",
@@ -386,51 +302,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_FORE_AFT_MOVE",
@@ -441,51 +333,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_POS",
@@ -496,51 +364,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE",
@@ -551,51 +395,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_POS",
@@ -606,51 +426,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE",
@@ -661,51 +457,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_HEIGHT_POS",
@@ -716,51 +488,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_HEIGHT_MOVE",
@@ -771,51 +519,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_DEPTH_POS",
@@ -826,51 +550,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_DEPTH_MOVE",
@@ -881,51 +581,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_TILT_POS",
@@ -936,51 +612,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_TILT_MOVE",
@@ -991,51 +643,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS",
@@ -1046,51 +674,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE",
@@ -1101,51 +705,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS",
@@ -1156,51 +736,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE",
@@ -1211,51 +767,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2",
@@ -1266,51 +798,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE",
@@ -1321,51 +829,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_ANGLE_POS",
@@ -1376,51 +860,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_ANGLE_MOVE",
@@ -1431,51 +891,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_POS",
@@ -1486,51 +922,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE",
@@ -1541,51 +953,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE",
@@ -1596,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"
             ]
         },
         {
@@ -1627,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"
             ]
         },
         {
@@ -1693,51 +1069,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE",
@@ -1748,51 +1100,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_POS",
@@ -1803,51 +1131,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -10,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -10,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE",
@@ -1858,51 +1162,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::SEAT_WALK_IN_POS",
@@ -1913,24 +1193,18 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 5,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 5,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 5
         },
         {
             "property": "VehicleProperty::SEAT_AIRBAGS_DEPLOYED",
@@ -1948,7 +1222,10 @@
                         "VehicleAirbagLocation::LEFT_SIDE",
                         "VehicleAirbagLocation::RIGHT_SIDE",
                         "VehicleAirbagLocation::CURTAIN"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 },
                 {
                     "areaId": "Constants::SEAT_1_RIGHT",
@@ -1958,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
+                    }
                 }
             ]
         },
@@ -2186,6 +1472,21 @@
                 60,
                 80,
                 100
+            ],
+            "areas": [
+                {
+                    "areaId": 0
+                }
+            ],
+            "hasSupportedValueInfo": {
+                "hasSupportedValuesList": true
+            },
+            "supportedValues": [
+                20,
+                40,
+                60,
+                80,
+                100
             ]
         },
         {
@@ -2272,45 +1573,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::WHEEL_FRONT_LEFT",
-                    "minFloatValue": 193.0,
-                    "maxFloatValue": 300.0,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WHEEL_FRONT_LEFT"
                 },
                 {
-                    "areaId": "Constants::WHEEL_FRONT_RIGHT",
-                    "minFloatValue": 193.0,
-                    "maxFloatValue": 300.0,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT"
                 },
                 {
-                    "areaId": "Constants::WHEEL_REAR_LEFT",
-                    "minFloatValue": 193.0,
-                    "maxFloatValue": 300.0,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WHEEL_REAR_LEFT"
                 },
                 {
-                    "areaId": "Constants::WHEEL_REAR_RIGHT",
-                    "minFloatValue": 193.0,
-                    "maxFloatValue": 300.0,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "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",
@@ -2423,13 +1706,7 @@
                             0
                         ]
                     },
-                    "areaId": "Constants::WHEEL_FRONT_LEFT",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WHEEL_FRONT_LEFT"
                 },
                 {
                     "defaultValue": {
@@ -2437,13 +1714,7 @@
                             0
                         ]
                     },
-                    "areaId": "Constants::WHEEL_FRONT_RIGHT",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT"
                 },
                 {
                     "defaultValue": {
@@ -2451,13 +1722,7 @@
                             0
                         ]
                     },
-                    "areaId": "Constants::WHEEL_REAR_RIGHT",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WHEEL_REAR_RIGHT"
                 },
                 {
                     "defaultValue": {
@@ -2465,17 +1730,17 @@
                             0
                         ]
                     },
-                    "areaId": "Constants::WHEEL_REAR_LEFT",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "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",
@@ -2533,15 +1798,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::EV_STOPPING_MODE",
@@ -2552,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"
             ]
         },
         {
@@ -2960,51 +2228,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": 1,
-                    "maxInt32Value": 7,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 1,
+            "maxInt32Value": 7
         },
         {
             "property": "VehicleProperty::HVAC_FAN_DIRECTION",
@@ -3072,52 +2316,28 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "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",
@@ -3128,16 +2348,16 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "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",
@@ -3148,52 +2368,28 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "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",
@@ -3204,15 +2400,15 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 2
         },
         {
             "property": "VehicleProperty::HVAC_TEMPERATURE_CURRENT",
@@ -3248,49 +2444,19 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_LEFT",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_RIGHT",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::SEAT_2_CENTER",
-                    "minFloatValue": 17.5,
-                    "maxFloatValue": 32.5,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_2_CENTER"
                 }
             ],
             "comment":
@@ -3302,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
             ]
         },
         {
@@ -3442,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"
             ]
         },
         {
@@ -3524,51 +2733,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::DOOR_1_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::DOOR_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::DOOR_2_LEFT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::DOOR_2_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::DOOR_REAR",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_REAR"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::DOOR_MOVE",
@@ -3579,42 +2764,24 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::DOOR_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::DOOR_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::DOOR_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::DOOR_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::DOOR_2_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::MIRROR_Z_POS",
@@ -3625,33 +2792,21 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -3,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::MIRROR_Z_MOVE",
@@ -3662,33 +2817,21 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::MIRROR_Y_POS",
@@ -3699,33 +2842,21 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
-                    "minInt32Value": -3,
-                    "maxInt32Value": 3,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -3,
+            "maxInt32Value": 3
         },
         {
             "property": "VehicleProperty::MIRROR_Y_MOVE",
@@ -3736,33 +2867,21 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT"
                 },
                 {
-                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::MIRROR_LOCK",
@@ -3883,51 +3002,27 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::WINDOW_1_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WINDOW_1_LEFT"
                 },
                 {
-                    "areaId": "Constants::WINDOW_1_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WINDOW_1_RIGHT"
                 },
                 {
-                    "areaId": "Constants::WINDOW_2_LEFT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WINDOW_2_LEFT"
                 },
                 {
-                    "areaId": "Constants::WINDOW_2_RIGHT",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WINDOW_2_RIGHT"
                 },
                 {
-                    "areaId": "Constants::WINDOW_ROOF_TOP_1",
-                    "minInt32Value": -1,
-                    "maxInt32Value": 1,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::WINDOW_ROOF_TOP_1"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -1,
+            "maxInt32Value": 1
         },
         {
             "property": "VehicleProperty::WINDSHIELD_WIPERS_PERIOD",
@@ -3938,24 +3033,18 @@
             },
             "areas": [
                 {
-                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3000,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
                 },
                 {
-                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 3000,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 3000
         },
         {
             "property": "VehicleProperty::WINDSHIELD_WIPERS_STATE",
@@ -3971,14 +3060,20 @@
                         "WindshieldWipersState::OFF",
                         "WindshieldWipersState::ON",
                         "WindshieldWipersState::SERVICE"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 },
                 {
                     "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
                     "supportedEnumValues": [
                         "WindshieldWipersState::OFF",
                         "WindshieldWipersState::ON"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 }
             ]
         },
@@ -4007,7 +3102,10 @@
                         "WindshieldWipersSwitch::CONTINUOUS_LEVEL_5",
                         "WindshieldWipersSwitch::AUTO",
                         "WindshieldWipersSwitch::SERVICE"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 },
                 {
                     "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
@@ -4019,7 +3117,10 @@
                         "WindshieldWipersSwitch::CONTINUOUS_LEVEL_2",
                         "WindshieldWipersSwitch::AUTO",
                         "WindshieldWipersSwitch::SERVICE"
-                    ]
+                    ],
+                    "hasSupportedValueInfo": {
+                        "hasSupportedValuesList": true
+                    }
                 }
             ]
         },
@@ -4032,15 +3133,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::STEERING_WHEEL_DEPTH_MOVE",
@@ -4051,15 +3152,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -2,
+            "maxInt32Value": 2
         },
         {
             "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_POS",
@@ -4070,15 +3171,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE",
@@ -4089,15 +3190,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": -2,
-                    "maxInt32Value": 2,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": -2,
+            "maxInt32Value": 2
         },
         {
             "property": "VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED",
@@ -4132,15 +3233,15 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT",
-                    "minInt32Value": 0,
-                    "maxInt32Value": 10,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::SEAT_1_RIGHT"
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minInt32Value": 0,
+            "maxInt32Value": 10
         },
         {
             "property": "VehicleProperty::GLOVE_BOX_LOCKED",
@@ -4359,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"
             ]
         },
         {
@@ -4449,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"
             ]
         },
         {
@@ -5344,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"
             ]
         },
         {
@@ -5377,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"
             ]
         },
         {
@@ -5399,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"
             ]
         },
         {
@@ -5439,15 +4558,15 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minFloatValue": 20.0,
-                    "maxFloatValue": 35.0,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": 0
                 }
-            ]
+            ],
+            "hasSupportedValueInfo": {
+                "hasMinSupportedValue": true,
+                "hasMaxSupportedValue": true
+            },
+            "minFloatValue": 20.0,
+            "maxFloatValue": 35.0
         },
         {
             "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP",
@@ -5474,17 +4593,17 @@
             },
             "areas": [
                 {
-                    "areaId": 0,
-                    "minInt32Value": 0,
-                    "maxInt32Value": 200000,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "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",
@@ -5503,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"
             ]
         },
         {
@@ -5521,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"
             ]
         },
         {
@@ -5547,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"
             ]
         },
         {
@@ -5580,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"
             ]
         },
         {
@@ -5606,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"
             ]
         },
         {
@@ -5632,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"
             ]
         },
         {
@@ -5678,10 +4815,10 @@
             "property": "VehicleProperty::VHAL_HEARTBEAT",
             "areas": [
                 {
-                    "areaId": 0,
-                    "supportVariableUpdateRate": false
+                    "areaId": 0
                 }
-            ]
+            ],
+            "supportVariableUpdateRate": false
         },
         {
             "property": "VehicleProperty::CLUSTER_SWITCH_UI",
@@ -5745,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",
@@ -5803,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"
             ]
         },
         {
@@ -5834,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"
             ]
         },
         {
@@ -5864,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"
             ]
         },
         {
@@ -5906,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"
             ]
         },
         {
@@ -5936,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"
             ]
         },
         {
@@ -5970,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"
             ]
         },
         {
@@ -6002,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"
             ]
         },
         {
@@ -6031,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"
             ]
         },
         {
@@ -6060,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"
             ]
         },
         {
@@ -6094,17 +5249,20 @@
             },
             "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"
             ]
         },
         {
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 5779050..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,13 +76,7 @@
                             1.0
                         ]
                     },
-                    "areaId": "Constants::HVAC_LEFT",
-                    "minFloatValue": -10.0,
-                    "maxFloatValue": 10.0,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "areaId": "Constants::HVAC_LEFT"
                 },
                 {
                     "defaultValue": {
@@ -89,17 +84,17 @@
                             2.0
                         ]
                     },
-                    "areaId": "Constants::HVAC_RIGHT",
-                    "minFloatValue": -10.0,
-                    "maxFloatValue": 10.0,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true
-                    }
+                    "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",
@@ -110,14 +105,7 @@
                             2
                         ]
                     },
-                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100,
-                    "hasSupportedValueInfo": {
-                        "hasMinSupportedValue": true,
-                        "hasMaxSupportedValue": true,
-                        "hasSupportedValuesList": true
-                    }
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
                 },
                 {
                     "defaultValue": {
@@ -125,9 +113,7 @@
                             0
                         ]
                     },
-                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
-                    "minInt32Value": -100,
-                    "maxInt32Value": 100
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
                 },
                 {
                     "defaultValue": {
@@ -135,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",
@@ -219,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 b9d315a..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,6 @@
     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>
@@ -199,6 +203,10 @@
     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,
@@ -327,9 +335,6 @@
                                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);
@@ -339,6 +344,8 @@
     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,
@@ -372,8 +379,13 @@
     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>> parseValues(
-            const std::vector<std::string>& options, size_t index);
+    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 c174e92..be909c5 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,46 +416,16 @@
     return configsByPropId;
 }
 
-template <>
-void FakeVehicleHardware::setMinSupportedValueLocked(int32_t propId, int32_t areaId,
-                                                     int32_t minValue) {
+template <class T>
+void FakeVehicleHardware::setMinSupportedValueLocked(int32_t propId, int32_t areaId, T minValue) {
     mMinSupportedValueByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
-            RawPropValues{.int32Values = {minValue}};
+            createRawPropValues<T>(minValue);
 }
 
-template <>
-void FakeVehicleHardware::setMaxSupportedValueLocked(int32_t propId, int32_t areaId,
-                                                     int32_t maxValue) {
+template <class T>
+void FakeVehicleHardware::setMaxSupportedValueLocked(int32_t propId, int32_t areaId, T maxValue) {
     mMaxSupportedValueByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
-            RawPropValues{.int32Values = {maxValue}};
-}
-
-template <>
-void FakeVehicleHardware::setMinSupportedValueLocked(int32_t propId, int32_t areaId,
-                                                     int64_t minValue) {
-    mMinSupportedValueByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
-            RawPropValues{.int64Values = {minValue}};
-}
-
-template <>
-void FakeVehicleHardware::setMaxSupportedValueLocked(int32_t propId, int32_t areaId,
-                                                     int64_t maxValue) {
-    mMaxSupportedValueByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
-            RawPropValues{.int64Values = {maxValue}};
-}
-
-template <>
-void FakeVehicleHardware::setMinSupportedValueLocked(int32_t propId, int32_t areaId,
-                                                     float minValue) {
-    mMinSupportedValueByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
-            RawPropValues{.floatValues = {minValue}};
-}
-
-template <>
-void FakeVehicleHardware::setMaxSupportedValueLocked(int32_t propId, int32_t areaId,
-                                                     float maxValue) {
-    mMaxSupportedValueByPropIdAreaId[PropIdAreaId{.propId = propId, .areaId = areaId}] =
-            RawPropValues{.floatValues = {maxValue}};
+            createRawPropValues<T>(maxValue);
 }
 
 void FakeVehicleHardware::init(int32_t s2rS2dConfig) {
@@ -470,12 +458,7 @@
                 if (!areaConfig.hasSupportedValueInfo.has_value()) {
                     continue;
                 }
-                if (!areaConfig.hasSupportedValueInfo->hasMinSupportedValue &&
-                    !areaConfig.hasSupportedValueInfo->hasMaxSupportedValue) {
-                    continue;
-                }
                 if (areaConfig.hasSupportedValueInfo->hasMinSupportedValue) {
-                    RawPropValues rawPropValues = {};
                     switch (propertyType) {
                         case toInt(VehiclePropertyType::INT32):
                             setMinSupportedValueLocked(cfg.prop, areaConfig.areaId,
@@ -497,7 +480,6 @@
                     }
                 }
                 if (areaConfig.hasSupportedValueInfo->hasMaxSupportedValue) {
-                    RawPropValues rawPropValues = {};
                     switch (propertyType) {
                         case toInt(VehiclePropertyType::INT32):
                             setMaxSupportedValueLocked(cfg.prop, areaConfig.areaId,
@@ -513,11 +495,71 @@
                             break;
                         default:
                             ALOGE("hasMaxSupportedValue must only be true for INT32, INT64 or "
-                                  "FLOAT "
-                                  "type property");
+                                  "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);
+                    }
+                }
             }
         }
     }
@@ -1901,44 +1943,131 @@
     return result;
 }
 
-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 StringPrintf("Not enough arguments\n");
-    }
-    size_t index = 1;
+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 StringPrintf("Failed to set min/max supported value: propId not valid: %s\n",
-                            propIdStr.c_str());
+        return Error() << "propId not valid: " << propIdStr;
     }
     int32_t propId = maybePropId.value();
     auto configResult = mServerSidePropStore->getPropConfig(propId);
     if (!configResult.ok()) {
-        return "Failed to set min/max supported value: property not supported\n";
+        return Error() << "property not supported";
     }
     std::string areaIdStr = "0";
     int32_t areaId = 0;
     if (EqualsIgnoreCase(options[index], "-a")) {
         index++;
         if (index >= options.size()) {
-            return StringPrintf("Not enough arguments\n");
+            return Error() << "Not enough arguments";
         }
         areaIdStr = options[index];
         auto maybeAreaId = parseAreaId(options, index, propId);
         if (!maybeAreaId.ok()) {
-            return StringPrintf("Failed to set min/max supported value: areaId not valid: %s\n",
-                                areaIdStr.c_str());
+            return Error() << "areaId not valid: " << areaIdStr;
         }
         areaId = maybeAreaId.value();
         index++;
     }
+    return DumpOptionPropIdAreaIdInfo{
+            .propId = propId, .areaId = areaId, .propIdStr = propIdStr, .areaIdStr = areaIdStr};
+}
 
-    if (index + 1 >= options.size()) {
-        return StringPrintf("Not enough arguments\n");
+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 Error() << "Failed to set min/max supported value: MinValue: " << minValue
+                       << " must not > MaxValue: " << maxValue;
+    }
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        setMinSupportedValueLocked(propId, areaId, minValue);
+        setMaxSupportedValueLocked(propId, areaId, maxValue);
+    }
+    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):
@@ -1962,90 +2091,52 @@
     }
 
     triggerSupportedValueChange(propId, areaId);
-    return StringPrintf("Min/Max supported value for propId: %s, areaId: %s set", propIdStr.c_str(),
-                        areaIdStr.c_str());
-}
-
-template <class T>
-Result<void> FakeVehicleHardware::parseAndSetMinMaxValue(int32_t propId, int32_t areaId,
-                                                         const std::vector<std::string>& options,
-                                                         size_t index) {
-    auto valuesResult = parseValues<T>(options, index);
-    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 Error() << "Failed to set min/max supported value: MinValue: " << minValue
-                       << " must not > MaxValue: " << maxValue;
-    }
-    {
-        std::scoped_lock<std::mutex> lockGuard(mLock);
-        setMinSupportedValueLocked(propId, areaId, minValue);
-        setMaxSupportedValueLocked(propId, areaId, maxValue);
-    }
-    return {};
-}
-
-template <class T>
-Result<std::vector<T>> FakeVehicleHardware::parseValues(const std::vector<std::string>& options,
-                                                        size_t index) {
-    std::vector<T> values;
-    for (size_t i = index; i < index + 2; 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 parseValues for float type.
-template <>
-Result<std::vector<float>> FakeVehicleHardware::parseValues(const std::vector<std::string>& options,
-                                                            size_t index) {
-    std::vector<float> values;
-    for (size_t i = index; i < index + 2; 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;
+    return StringPrintf("Min/Max supported value for propId: %s, areaId: %s set\n",
+                        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\n",
+                        maybeInfo->propIdStr.c_str(), maybeInfo->propIdStr.c_str());
 }
 
 void FakeVehicleHardware::triggerSupportedValueChange(int32_t propId, int32_t areaId) {
@@ -2060,56 +2151,44 @@
     }});
 }
 
-// Triggers supported value change for all areaIds that specify hasSupportedValueInfo.
-void FakeVehicleHardware::triggerSupportedValueChange(const VehiclePropConfig& config) {
-    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));
-}
-
 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 <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 -5.1 5.1\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() {
@@ -2629,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 617d2d2..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;
@@ -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) {
@@ -2892,8 +2893,9 @@
     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(
@@ -2907,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>>({
@@ -2921,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;
@@ -4073,25 +4172,32 @@
 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_property/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 2f1b277..cf9ea10 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -5716,7 +5716,11 @@
      * int32[8]: 10  // 2nd user (user 10)
      * int32[9]: 0   // 2nd user flags (none)
      *
-     * @change_mode VehiclePropertyChangeMode.STATIC
+     * Before Android B, this property's change mode was defined as STATIC although the property
+     * value may be updated from Android side. For backward compatibility, we still allow STATIC
+     * as change mode, but for new implementations, ON_CHANGE should be used instead.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
      * @version 2
      */
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
index 44a810e..592cadd 100755
--- a/automotive/vehicle/tools/generate_annotation_enums.py
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -51,17 +51,17 @@
 SCRIPT_PATH = 'hardware/interfaces/automotive/vehicle/tools/generate_annotation_enums.py'
 
 TAB = '    '
-RE_ENUM_START = re.compile('\s*enum VehicleProperty \{')
-RE_ENUM_END = re.compile('\s*\}\;')
-RE_COMMENT_BEGIN = re.compile('\s*\/\*\*?')
-RE_COMMENT_END = re.compile('\s*\*\/')
-RE_CHANGE_MODE = re.compile('\s*\* @change_mode (\S+)\s*')
-RE_VERSION = re.compile('\s*\* @version (\S+)\s*')
-RE_ACCESS = re.compile('\s*\* @access (\S+)\s*')
-RE_DATA_ENUM = re.compile('\s*\* @data_enum (\S+)\s*')
-RE_UNIT = re.compile('\s*\* @unit (\S+)\s+')
-RE_VALUE = re.compile('\s*(\w+)\s*=(.*)')
-RE_ANNOTATION = re.compile('\s*\* @(\S+)\s*')
+RE_ENUM_START = re.compile(r'\s*enum VehicleProperty \{')
+RE_ENUM_END = re.compile(r'\s*\}\;')
+RE_COMMENT_BEGIN = re.compile(r'\s*\/\*\*?')
+RE_COMMENT_END = re.compile(r'\s*\*\/')
+RE_CHANGE_MODE = re.compile(r'\s*\* @change_mode (\S+)\s*')
+RE_VERSION = re.compile(r'\s*\* @version (\S+)\s*')
+RE_ACCESS = re.compile(r'\s*\* @access (\S+)\s*')
+RE_DATA_ENUM = re.compile(r'\s*\* @data_enum (\S+)\s*')
+RE_UNIT = re.compile(r'\s*\* @unit (\S+)\s+')
+RE_VALUE = re.compile(r'\s*(\w+)\s*=(.*)')
+RE_ANNOTATION = re.compile(r'\s*\* @(\S+)\s*')
 
 SUPPORTED_ANNOTATIONS = ['change_mode', 'access', 'unit', 'data_enum', 'data_enum_bit_flags',
     'version', 'require_min_max_supported_value', 'require_supported_values_list',
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 7f5e06d..f249cf6 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -1248,9 +1248,21 @@
         }
     }
 
-    EXPECT_EQ(actualChangeMode, expectedChangeMode)
-            << StringPrintf("Expect to get VehiclePropertyChangeMode: %i, got %i",
-                            expectedChangeMode, actualChangeMode);
+    if (actualPropId != toInt(VehicleProperty::REMOVE_USER)) {
+        EXPECT_EQ(actualChangeMode, expectedChangeMode)
+                << StringPrintf("Expect to get VehiclePropertyChangeMode: %i, got %i",
+                                expectedChangeMode, actualChangeMode);
+    } else {
+        // Special logic for REMOVE_USER property. We allow both STATIC and ON_CHANGE change mode
+        // because historically we define the change mode to be STATIC which is incorrect, it should
+        // be on_change. For backward compatibility, we have to allow both.
+        EXPECT_THAT(actualChangeMode, ::testing::AnyOf(toInt(VehiclePropertyChangeMode::STATIC),
+                                                       toInt(VehiclePropertyChangeMode::ON_CHANGE)))
+                << StringPrintf(
+                           "Expect to get VehiclePropertyChangeMode as one of: "
+                           "[STATIC, ON_CHANGE], got %i",
+                           actualChangeMode);
+    }
 
     std::unordered_set<std::string> annotations;
     auto it = AnnotationsForVehicleProperty.find(param.propId);
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/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index a52d761..2fde910 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -2843,11 +2843,11 @@
 
     if (asymmetric) {
       source_ase_requriement.aseConfiguration.codecConfiguration = {
-          CodecSpecificConfigurationLtv::SamplingFrequency::HZ8000,
+          CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
           CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
     } else {
       source_ase_requriement.aseConfiguration.codecConfiguration = {
-          CodecSpecificConfigurationLtv::SamplingFrequency::HZ16000,
+          CodecSpecificConfigurationLtv::SamplingFrequency::HZ32000,
           CodecSpecificConfigurationLtv::FrameDuration::US10000, allocation};
     }
 
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertUrgency.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertUrgency.aidl
index c7bfdbc..daebb4e 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/AlertUrgency.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertUrgency.aidl
@@ -17,7 +17,7 @@
 package android.hardware.broadcastradio;
 
 /**
- * The severity of the subject event of the emergency alert message.
+ * The urgency of the subject event of the emergency alert message.
  *
  * <p>(see ITU-T X.1303 bis for more info).
  */
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/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index ec61eec..92f69bd 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -171,8 +171,8 @@
         ALOGI("validateManualFlashStrengthControlKeys: Testing camera device %s", name.c_str());
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> cameraDevice;
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                &cameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &cameraDevice /*out*/));
         ndk::ScopedAStatus ret = cameraDevice->getCameraCharacteristics(&meta);
         ASSERT_TRUE(ret.isOk());
         const camera_metadata_t* staticMeta =
@@ -305,7 +305,8 @@
         }
 
         CameraMetadata meta;
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/, &device /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &device /*out*/));
 
         std::vector<AvailableStream> outputStreams;
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
@@ -634,7 +635,8 @@
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> device;
 
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/, &device /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &device /*out*/));
 
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
         outputStreams.clear();
@@ -712,8 +714,9 @@
             ASSERT_TRUE(idToNameMap.end() != it);
             std::string name = it->second;
 
-            openEmptyDeviceSession(name, mProvider, &cti.session /*out*/, &cti.staticMeta /*out*/,
-                                   &cti.cameraDevice /*out*/);
+            ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &cti.session /*out*/,
+                                                           &cti.staticMeta /*out*/,
+                                                           &cti.cameraDevice /*out*/));
 
             outputStreams.clear();
             camera_metadata_t* staticMeta =
@@ -795,8 +798,8 @@
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> cameraDevice;
 
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &cameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &cameraDevice /*out*/));
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
         outputStreams.clear();
 
@@ -933,8 +936,8 @@
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> cameraDevice;
 
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &cameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &cameraDevice /*out*/));
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
 
         Status rc = isZSLModeAvailable(staticMeta);
@@ -1086,8 +1089,8 @@
         CameraMetadata meta;
 
         std::shared_ptr<ICameraDevice> unusedCameraDevice;
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &unusedCameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &unusedCameraDevice /*out*/));
         camera_metadata_t* staticMetaBuffer =
                 reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
 
@@ -1196,8 +1199,8 @@
         CameraMetadata meta;
 
         std::shared_ptr<ICameraDevice> cameraDevice;
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &cameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &cameraDevice /*out*/));
 
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
 
@@ -1291,8 +1294,8 @@
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> cameraDevice;
 
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &cameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &cameraDevice /*out*/));
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
 
         Status rc = isConstrainedModeAvailable(staticMeta);
@@ -1434,8 +1437,8 @@
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> cameraDevice;
 
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &cameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &cameraDevice /*out*/));
 
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
 
@@ -1557,8 +1560,8 @@
         CameraMetadata metadata;
 
         std::shared_ptr<ICameraDevice> unusedDevice;
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &metadata /*out*/,
-                               &unusedDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &metadata /*out*/, &unusedDevice /*out*/));
 
         camera_metadata_t* staticMeta =
                 reinterpret_cast<camera_metadata_t*>(metadata.metadata.data());
@@ -1801,7 +1804,8 @@
         CameraMetadata meta;
 
         std::shared_ptr<ICameraDevice> unusedDevice;
-        openEmptyDeviceSession(name, mProvider, &mSession, &meta, &unusedDevice);
+        ASSERT_NO_FATAL_FAILURE(
+                openEmptyDeviceSession(name, mProvider, &mSession, &meta, &unusedDevice));
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
         if (!isUltraHighResolution(staticMeta)) {
             ndk::ScopedAStatus ret = mSession->close();
@@ -1966,7 +1970,7 @@
         ASSERT_TRUE(matchDeviceName(name, mProviderType, &version, &deviceId));
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> device;
-        openEmptyDeviceSession(name, mProvider, &mSession, &meta, &device);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession, &meta, &device));
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
         if (!is10BitDynamicRangeCapable(staticMeta)) {
             ndk::ScopedAStatus ret = mSession->close();
@@ -2209,8 +2213,8 @@
         CameraMetadata meta;
         settings.metadata.clear();
         std::shared_ptr<ICameraDevice> unusedDevice;
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &unusedDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &unusedDevice /*out*/));
         camera_metadata_t* staticMetaBuffer =
                 clone_camera_metadata(reinterpret_cast<camera_metadata_t*>(meta.metadata.data()));
         ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
@@ -2435,8 +2439,8 @@
         CameraMetadata meta;
         {
             std::shared_ptr<ICameraDevice> unusedDevice;
-            openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                                   &unusedDevice);
+            ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                           &meta /*out*/, &unusedDevice));
             camera_metadata_t* staticMetaBuffer = clone_camera_metadata(
                     reinterpret_cast<camera_metadata_t*>(meta.metadata.data()));
             ::android::hardware::camera::common::V1_0::helper::CameraMetadata staticMeta(
@@ -3170,8 +3174,8 @@
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> cameraDevice;
 
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &cameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &cameraDevice /*out*/));
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
 
         if (is10BitDynamicRangeCapable(staticMeta)) {
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 44af306..75ad532 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -1814,7 +1814,7 @@
     ALOGI("getCameraDeviceInterface returns status:%d:%d", ret.getExceptionCode(),
           ret.getServiceSpecificError());
     ASSERT_TRUE(ret.isOk());
-    ASSERT_NE(device, nullptr);
+    ASSERT_NE(*device, nullptr);
 
     std::shared_ptr<EmptyDeviceCb> cb = ndk::SharedRefBase::make<EmptyDeviceCb>();
     ret = (*device)->open(cb, session);
@@ -2462,8 +2462,8 @@
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> cameraDevice;
 
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &cameraDevice /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &cameraDevice /*out*/));
 
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
         // Check if camera support depth only or doesn't support stream use case capability
@@ -3731,7 +3731,7 @@
         ASSERT_TRUE(matchDeviceName(name, mProviderType, &version, &deviceId));
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> device;
-        openEmptyDeviceSession(name, mProvider, &mSession, &meta, &device);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession, &meta, &device));
         camera_metadata_t* staticMeta = reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
 
         // Device does not report color spaces, skip.
@@ -3952,8 +3952,8 @@
     for (const auto& name : cameraDeviceNames) {
         CameraMetadata meta;
         std::shared_ptr<ICameraDevice> device;
-        openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
-                               &device /*out*/);
+        ASSERT_NO_FATAL_FAILURE(openEmptyDeviceSession(name, mProvider, &mSession /*out*/,
+                                                       &meta /*out*/, &device /*out*/));
         camera_metadata_t* staticMeta =
                 clone_camera_metadata(reinterpret_cast<camera_metadata_t*>(meta.metadata.data()));
 
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.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 8d5a50a..85702e2 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -523,6 +523,14 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" exclusive-to="virtual-machine">
+        <name>android.hardware.security.see.storage</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureStorage</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.secureclock</name>
         <version>1</version>
diff --git a/compatibility_matrices/compatibility_matrix.202604.xml b/compatibility_matrices/compatibility_matrix.202604.xml
index e5e2abf..46b04c9 100644
--- a/compatibility_matrices/compatibility_matrix.202604.xml
+++ b/compatibility_matrices/compatibility_matrix.202604.xml
@@ -396,7 +396,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.config</name>
-        <version>3-4</version>
+        <version>3-5</version>
         <interface>
             <name>IRadioConfig</name>
             <instance>default</instance>
@@ -404,7 +404,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.data</name>
-        <version>3-4</version>
+        <version>3-5</version>
         <interface>
             <name>IRadioData</name>
             <instance>slot1</instance>
@@ -414,7 +414,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.messaging</name>
-        <version>3-4</version>
+        <version>3-5</version>
         <interface>
             <name>IRadioMessaging</name>
             <instance>slot1</instance>
@@ -424,7 +424,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.modem</name>
-        <version>3-4</version>
+        <version>3-5</version>
         <interface>
             <name>IRadioModem</name>
             <instance>slot1</instance>
@@ -434,7 +434,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.network</name>
-        <version>3-4</version>
+        <version>3-5</version>
         <interface>
             <name>IRadioNetwork</name>
             <instance>slot1</instance>
@@ -444,7 +444,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.sim</name>
-        <version>3-4</version>
+        <version>3-5</version>
         <interface>
             <name>IRadioSim</name>
             <instance>slot1</instance>
@@ -464,7 +464,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.voice</name>
-        <version>3-4</version>
+        <version>3-5</version>
         <interface>
             <name>IRadioVoice</name>
             <instance>slot1</instance>
@@ -474,7 +474,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.ims</name>
-        <version>2-3</version>
+        <version>2-4</version>
         <interface>
             <name>IRadioIms</name>
             <instance>slot1</instance>
@@ -484,7 +484,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.radio.ims.media</name>
-        <version>2-3</version>
+        <version>2-4</version>
         <interface>
             <name>IImsMedia</name>
             <instance>default</instance>
@@ -523,6 +523,14 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" exclusive-to="virtual-machine">
+        <name>android.hardware.security.see.storage</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureStorage</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.security.secureclock</name>
         <version>1</version>
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/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 4f2ed2f..7810213 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -58,12 +58,6 @@
         for (const auto& display : mAllDisplays) {
             // explicitly disable vsync
             EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), /*enable*/ false).isOk());
-
-            DisplayProperties& displayProperties = mDisplayProperties.at(display.getDisplayId());
-            if (ReadbackHelper::readbackSupported(displayProperties.pixelFormat,
-                                                  displayProperties.dataspace)) {
-                mDisplaysWithReadbackBuffers.push_back(&display);
-            }
         }
 
         mComposerClient->setVsyncAllowed(/*isAllowed*/ false);
@@ -150,12 +144,35 @@
             DisplayProperties displayProperties(displayId, testColorModes,
                                                 std::move(testRenderEngine),
                                                 std::move(clientCompositionDisplaySettings),
-                                                std::move(readBackBufferAttributes));
+                                                std::move(readBackBufferAttributes.format));
 
             mDisplayProperties.emplace(displayId, std::move(displayProperties));
         }
     }
 
+    // Get the dataspace and check if readback is supported given the default pixel format and the
+    // current dataspace. Dataspace can get updated after calls to
+    // ComposerClientWrapper::setColorMode so it's essential to get the latest dataspace.
+    std::pair<common::Dataspace, bool> GetDataspaceAndIfReadBackSupported(int64_t displayId) {
+        auto [status, readBackBufferAttributes] =
+                mComposerClient->getReadbackBufferAttributes(displayId);
+        if (status.isOk()) {
+            auto dataspace = readBackBufferAttributes.dataspace;
+
+            // We are making an assumption that Pixel Format never changes, so assert for this
+            // assumption. If this is not the case on any display, then we should stop caching it.
+            // The cached format is used in initializing TestRenderEngine.
+            assertPixelFormatConsistency(displayId, readBackBufferAttributes.format);
+
+            return std::make_pair(std::move(dataspace),
+                                  ReadbackHelper::readbackSupported(
+                                          mDisplayProperties.at(displayId).pixelFormat, dataspace));
+        }
+        EXPECT_NO_FATAL_FAILURE(
+                assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
+        return {common::Dataspace::UNKNOWN, false};
+    }
+
     int64_t getInvalidDisplayId() const { return mComposerClient->getInvalidDisplayId(); }
 
     void assertServiceSpecificError(const ScopedAStatus& status, int32_t serviceSpecificError) {
@@ -163,6 +180,10 @@
         ASSERT_EQ(status.getServiceSpecificError(), serviceSpecificError);
     }
 
+    void assertPixelFormatConsistency(int64_t displayId, common::PixelFormat currentPixelFormat) {
+        ASSERT_EQ(mDisplayProperties.at(displayId).pixelFormat, currentPixelFormat);
+    }
+
     std::pair<bool, ::android::sp<::android::GraphicBuffer>> allocateBuffer(
             const DisplayWrapper& display, uint32_t usage) {
         const auto width = static_cast<uint32_t>(display.getDisplayWidth());
@@ -201,10 +222,9 @@
         DisplayProperties(int64_t displayId, std::vector<ColorMode> testColorModes,
                           std::unique_ptr<TestRenderEngine> testRenderEngine,
                           ::android::renderengine::DisplaySettings clientCompositionDisplaySettings,
-                          ReadbackBufferAttributes readBackBufferAttributes)
+                          common::PixelFormat pixelFormat)
             : testColorModes(testColorModes),
-              pixelFormat(readBackBufferAttributes.format),
-              dataspace(readBackBufferAttributes.dataspace),
+              pixelFormat(pixelFormat),
               testRenderEngine(std::move(testRenderEngine)),
               clientCompositionDisplaySettings(std::move(clientCompositionDisplaySettings)),
               writer(displayId),
@@ -212,7 +232,6 @@
 
         std::vector<ColorMode> testColorModes = {};
         common::PixelFormat pixelFormat = common::PixelFormat::UNSPECIFIED;
-        common::Dataspace dataspace = common::Dataspace::UNKNOWN;
         std::unique_ptr<TestRenderEngine> testRenderEngine = nullptr;
         ::android::renderengine::DisplaySettings clientCompositionDisplaySettings = {};
         ComposerClientWriter writer;
@@ -221,7 +240,6 @@
 
     std::shared_ptr<ComposerClientWrapper> mComposerClient;
     std::vector<DisplayWrapper> mAllDisplays;
-    std::vector<const DisplayWrapper*> mDisplaysWithReadbackBuffers;
     std::unordered_map<int64_t, DisplayProperties> mDisplayProperties;
 
     static constexpr uint32_t kClientTargetSlotCount = 64;
@@ -234,19 +252,25 @@
 };
 
 TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        auto& testColorModes = mDisplayProperties.at(display->getDisplayId()).testColorModes;
+    for (const DisplayWrapper display : mAllDisplays) {
+        auto& testColorModes = mDisplayProperties.at(display.getDisplayId()).testColorModes;
         for (ColorMode mode : testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             auto layer = std::make_shared<TestColorLayer>(
-                    mComposerClient, display->getDisplayId(),
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    mComposerClient, display.getDisplayId(),
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             common::Rect coloredSquare(
-                    {0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+                    {0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
             layer->setColor(BLUE);
             layer->setDisplayFrame(coloredSquare);
             layer->setZOrder(10);
@@ -255,40 +279,38 @@
 
             // expected color for each pixel
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
-                                           coloredSquare, BLUE);
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), coloredSquare,
+                                           BLUE);
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
+            execute(display.getDisplayId());
             // if hwc cannot handle and asks for composition change, just skip the test on this
             // display->
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -297,71 +319,74 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        auto& testColorModes = mDisplayProperties.at(display->getDisplayId()).testColorModes;
+    for (const DisplayWrapper display : mAllDisplays) {
+        auto& testColorModes = mDisplayProperties.at(display.getDisplayId()).testColorModes;
         for (ColorMode mode : testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
+
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
             ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, 0, display->getDisplayWidth(), display->getDisplayHeight() / 4}, RED);
+                    expectedColors, display.getDisplayWidth(),
+                    {0, 0, display.getDisplayWidth(), display.getDisplayHeight() / 4}, RED);
             ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, display->getDisplayHeight() / 4, display->getDisplayWidth(),
-                     display->getDisplayHeight() / 2},
+                    expectedColors, display.getDisplayWidth(),
+                    {0, display.getDisplayHeight() / 4, display.getDisplayWidth(),
+                     display.getDisplayHeight() / 2},
                     GREEN);
-            ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, display->getDisplayHeight() / 2, display->getDisplayWidth(),
-                     display->getDisplayHeight()},
-                    BLUE);
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
+                                           {0, display.getDisplayHeight() / 2,
+                                            display.getDisplayWidth(), display.getDisplayHeight()},
+                                           BLUE);
 
             auto layer = std::make_shared<TestBufferLayer>(
                     mComposerClient,
-                    *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                    display->getDisplayId(), display->getDisplayWidth(),
-                    display->getDisplayHeight(), common::PixelFormat::RGBA_8888,
-                    mDisplayProperties.at(display->getDisplayId()).writer);
-            layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+                    *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                    display.getDisplayId(), display.getDisplayWidth(), display.getDisplayHeight(),
+                    common::PixelFormat::RGBA_8888,
+                    mDisplayProperties.at(display.getDisplayId()).writer);
+            layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
             layer->setZOrder(10);
             layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
             ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
 
             std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
+            execute(display.getDisplayId());
 
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -370,64 +395,69 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        auto& testColorModes = mDisplayProperties.at(display->getDisplayId()).testColorModes;
+    for (const DisplayWrapper display : mAllDisplays) {
+        auto& testColorModes = mDisplayProperties.at(display.getDisplayId()).testColorModes;
         for (ColorMode mode : testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
 
-            auto& writer = mDisplayProperties.at(display->getDisplayId()).writer;
-            auto layer = std::make_shared<TestColorLayer>(mComposerClient, display->getDisplayId(),
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
+
+            auto& writer = mDisplayProperties.at(display.getDisplayId()).writer;
+            auto layer = std::make_shared<TestColorLayer>(mComposerClient, display.getDisplayId(),
                                                           writer);
             common::Rect coloredSquare(
-                    {0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+                    {0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
             layer->setColor(BLUE);
             layer->setDisplayFrame(coloredSquare);
             layer->setZOrder(10);
-            layer->write(mDisplayProperties.at(display->getDisplayId()).writer);
+            layer->write(mDisplayProperties.at(display.getDisplayId()).writer);
 
             // This following buffer call should have no effect
             const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
                                static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
-            const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(*display, usage);
+            const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(display, usage);
             ASSERT_TRUE(graphicBufferStatus);
             const auto& buffer = graphicBuffer->handle;
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.setLayerBuffer(display->getDisplayId(), layer->getLayer(), /*slot*/ 0,
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.setLayerBuffer(display.getDisplayId(), layer->getLayer(), /*slot*/ 0,
                                            buffer,
                                            /*acquireFence*/ -1);
 
             // expected color for each pixel
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
-                                           coloredSquare, BLUE);
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), coloredSquare,
+                                           BLUE);
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
+            execute(display.getDisplayId());
 
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         }
@@ -435,20 +465,31 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetReadbackBuffer) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        ReadbackBuffer readbackBuffer(display->getDisplayId(), mComposerClient,
-                                      display->getDisplayWidth(), display->getDisplayHeight(),
-                                      mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                                      mDisplayProperties.at(display->getDisplayId()).dataspace);
+    for (const DisplayWrapper display : mAllDisplays) {
+        auto [dataspace, readbackSupported] =
+                GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+        if (!readbackSupported) {
+            continue;
+        }
+
+        ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                      display.getDisplayWidth(), display.getDisplayHeight(),
+                                      mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                      dataspace);
         ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
     }
 }
 
 TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadDisplay) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+    for (const DisplayWrapper display : mAllDisplays) {
+        auto [_, readbackSupported] = GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+        if (!readbackSupported) {
+            continue;
+        }
+
         const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
                            static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
-        const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(*display, usage);
+        const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(display, usage);
         ASSERT_TRUE(graphicBufferStatus);
         const auto& bufferHandle = graphicBuffer->handle;
         ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
@@ -463,10 +504,15 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadParameter) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+    for (const DisplayWrapper display : mAllDisplays) {
+        auto [_, readbackSupported] = GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+        if (!readbackSupported) {
+            continue;
+        }
+
         const native_handle_t bufferHandle{};
         ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
-        const auto status = mComposerClient->setReadbackBuffer(display->getDisplayId(),
+        const auto status = mComposerClient->setReadbackBuffer(display.getDisplayId(),
                                                                &bufferHandle, releaseFence);
 
         EXPECT_FALSE(status.isOk());
@@ -476,9 +522,13 @@
 }
 
 TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+    for (const DisplayWrapper display : mAllDisplays) {
+        auto [_, readbackSupported] = GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+        if (!readbackSupported) {
+            continue;
+        }
         const auto& [status, releaseFence] =
-                mComposerClient->getReadbackBufferFence(display->getDisplayId());
+                mComposerClient->getReadbackBufferFence(display.getDisplayId());
 
         EXPECT_FALSE(status.isOk());
         EXPECT_NO_FATAL_FAILURE(
@@ -488,64 +538,67 @@
 }
 
 TEST_P(GraphicsCompositionTest, ClientComposition) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+    for (const DisplayWrapper display : mAllDisplays) {
         EXPECT_TRUE(
                 mComposerClient
-                        ->setClientTargetSlotCount(display->getDisplayId(), kClientTargetSlotCount)
+                        ->setClientTargetSlotCount(display.getDisplayId(), kClientTargetSlotCount)
                         .isOk());
 
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
             ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, 0, display->getDisplayWidth(), display->getDisplayHeight() / 4}, RED);
+                    expectedColors, display.getDisplayWidth(),
+                    {0, 0, display.getDisplayWidth(), display.getDisplayHeight() / 4}, RED);
             ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, display->getDisplayHeight() / 4, display->getDisplayWidth(),
-                     display->getDisplayHeight() / 2},
+                    expectedColors, display.getDisplayWidth(),
+                    {0, display.getDisplayHeight() / 4, display.getDisplayWidth(),
+                     display.getDisplayHeight() / 2},
                     GREEN);
-            ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, display->getDisplayHeight() / 2, display->getDisplayWidth(),
-                     display->getDisplayHeight()},
-                    BLUE);
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
+                                           {0, display.getDisplayHeight() / 2,
+                                            display.getDisplayWidth(), display.getDisplayHeight()},
+                                           BLUE);
 
             auto layer = std::make_shared<TestBufferLayer>(
                     mComposerClient,
-                    *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                    display->getDisplayId(), display->getDisplayWidth(),
-                    display->getDisplayHeight(), PixelFormat::RGBA_8888,
-                    mDisplayProperties.at(display->getDisplayId()).writer);
-            layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+                    *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                    display.getDisplayId(), display.getDisplayWidth(), display.getDisplayHeight(),
+                    PixelFormat::RGBA_8888, mDisplayProperties.at(display.getDisplayId()).writer);
+            layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
             layer->setZOrder(10);
             layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
 
             std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
+            execute(display.getDisplayId());
 
             auto changedCompositionTypes =
-                    mDisplayProperties.at(display->getDisplayId())
-                            .reader.takeChangedCompositionTypes(display->getDisplayId());
+                    mDisplayProperties.at(display.getDisplayId())
+                            .reader.takeChangedCompositionTypes(display.getDisplayId());
             if (!changedCompositionTypes.empty()) {
                 ASSERT_EQ(1, changedCompositionTypes.size());
                 ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
@@ -556,11 +609,11 @@
                         static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
                         static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
                 Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
-                common::Rect damage{0, 0, display->getDisplayWidth(), display->getDisplayHeight()};
+                common::Rect damage{0, 0, display.getDisplayWidth(), display.getDisplayHeight()};
 
                 // create client target buffer
                 const auto& [graphicBufferStatus, graphicBuffer] =
-                        allocateBuffer(*display, clientUsage);
+                        allocateBuffer(display, clientUsage);
                 ASSERT_TRUE(graphicBufferStatus);
                 const auto& buffer = graphicBuffer->handle;
                 void* clientBufData;
@@ -576,29 +629,28 @@
                 int32_t clientFence;
                 const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
                 ASSERT_EQ(::android::OK, unlockStatus);
-                mDisplayProperties.at(display->getDisplayId())
-                        .writer.setClientTarget(display->getDisplayId(), /*slot*/ 0, buffer,
+                mDisplayProperties.at(display.getDisplayId())
+                        .writer.setClientTarget(display.getDisplayId(), /*slot*/ 0, buffer,
                                                 clientFence, clientDataspace,
                                                 std::vector<common::Rect>(1, damage), 1.f);
-                layer->setToClientComposition(
-                        mDisplayProperties.at(display->getDisplayId()).writer);
-                mDisplayProperties.at(display->getDisplayId())
-                        .writer.validateDisplay(display->getDisplayId(),
+                layer->setToClientComposition(mDisplayProperties.at(display.getDisplayId()).writer);
+                mDisplayProperties.at(display.getDisplayId())
+                        .writer.validateDisplay(display.getDisplayId(),
                                                 ComposerClientWriter::kNoTimestamp,
                                                 ComposerClientWrapper::kNoFrameIntervalNs);
-                execute(display->getDisplayId());
+                execute(display.getDisplayId());
                 changedCompositionTypes =
-                        mDisplayProperties.at(display->getDisplayId())
-                                .reader.takeChangedCompositionTypes(display->getDisplayId());
+                        mDisplayProperties.at(display.getDisplayId())
+                                .reader.takeChangedCompositionTypes(display.getDisplayId());
                 ASSERT_TRUE(changedCompositionTypes.empty());
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
 
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         }
@@ -634,12 +686,12 @@
         GTEST_SKIP();
     }
 
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+    for (const DisplayWrapper display : mAllDisplays) {
         ASSERT_TRUE(
                 mComposerClient
-                        ->setClientTargetSlotCount(display->getDisplayId(), kClientTargetSlotCount)
+                        ->setClientTargetSlotCount(display.getDisplayId(), kClientTargetSlotCount)
                         .isOk());
-        auto& testColorModes = mDisplayProperties.at(display->getDisplayId()).testColorModes;
+        auto& testColorModes = mDisplayProperties.at(display.getDisplayId()).testColorModes;
 
         for (const auto& lutProperties : *properties.lutProperties) {
             if (!lutProperties) {
@@ -650,25 +702,31 @@
             for (const auto& key : l.samplingKeys) {
                 for (ColorMode mode : testColorModes) {
                     EXPECT_TRUE(mComposerClient
-                                        ->setColorMode(display->getDisplayId(), mode,
+                                        ->setColorMode(display.getDisplayId(), mode,
                                                        RenderIntent::COLORIMETRIC)
                                         .isOk());
 
+                    auto [dataspace, readbackSupported] =
+                            GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+                    if (!readbackSupported) {
+                        continue;
+                    }
+
                     common::Rect coloredSquare(
-                            {0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+                            {0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
 
                     // expected color for each pixel
                     std::vector<Color> expectedColors(static_cast<size_t>(
-                            display->getDisplayWidth() * display->getDisplayHeight()));
-                    ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+                            display.getDisplayWidth() * display.getDisplayHeight()));
+                    ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
                                                    coloredSquare, WHITE);
 
                     auto layer = std::make_shared<TestBufferLayer>(
                             mComposerClient,
-                            *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                            display->getDisplayId(), display->getDisplayWidth(),
-                            display->getDisplayHeight(), PixelFormat::RGBA_8888,
-                            mDisplayProperties.at(display->getDisplayId()).writer);
+                            *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                            display.getDisplayId(), display.getDisplayWidth(),
+                            display.getDisplayHeight(), PixelFormat::RGBA_8888,
+                            mDisplayProperties.at(display.getDisplayId()).writer);
                     layer->setDisplayFrame(coloredSquare);
                     layer->setZOrder(10);
                     layer->setDataspace(Dataspace::SRGB);
@@ -682,46 +740,45 @@
                     std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
                     ReadbackBuffer readbackBuffer(
-                            display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                            display->getDisplayHeight(),
-                            mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                            mDisplayProperties.at(display->getDisplayId()).dataspace);
+                            display.getDisplayId(), mComposerClient, display.getDisplayWidth(),
+                            display.getDisplayHeight(),
+                            mDisplayProperties.at(display.getDisplayId()).pixelFormat, dataspace);
                     ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-                    writeLayers(layers, display->getDisplayId());
-                    ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId())
+                    writeLayers(layers, display.getDisplayId());
+                    ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId())
                                         .reader.takeErrors()
                                         .empty());
-                    mDisplayProperties.at(display->getDisplayId())
-                            .writer.validateDisplay(display->getDisplayId(),
+                    mDisplayProperties.at(display.getDisplayId())
+                            .writer.validateDisplay(display.getDisplayId(),
                                                     ComposerClientWriter::kNoTimestamp,
                                                     ComposerClientWrapper::kNoFrameIntervalNs);
-                    execute(display->getDisplayId());
-                    if (!mDisplayProperties.at(display->getDisplayId())
-                                 .reader.takeChangedCompositionTypes(display->getDisplayId())
+                    execute(display.getDisplayId());
+                    if (!mDisplayProperties.at(display.getDisplayId())
+                                 .reader.takeChangedCompositionTypes(display.getDisplayId())
                                  .empty()) {
                         continue;
                     }
 
                     auto changedCompositionTypes =
-                            mDisplayProperties.at(display->getDisplayId())
-                                    .reader.takeChangedCompositionTypes(display->getDisplayId());
+                            mDisplayProperties.at(display.getDisplayId())
+                                    .reader.takeChangedCompositionTypes(display.getDisplayId());
                     ASSERT_TRUE(changedCompositionTypes.empty());
 
-                    mDisplayProperties.at(display->getDisplayId())
-                            .writer.presentDisplay(display->getDisplayId());
-                    execute(display->getDisplayId());
-                    ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId())
+                    mDisplayProperties.at(display.getDisplayId())
+                            .writer.presentDisplay(display.getDisplayId());
+                    execute(display.getDisplayId());
+                    ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId())
                                         .reader.takeErrors()
                                         .empty());
 
                     ReadbackHelper::fillColorsArea(
-                            expectedColors, display->getDisplayWidth(), coloredSquare,
+                            expectedColors, display.getDisplayWidth(), coloredSquare,
                             {188.f / 255.f, 188.f / 255.f, 188.f / 255.f, 1.0f});
 
                     ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
                     auto& testRenderEngine =
-                            mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+                            mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
                     testRenderEngine->setRenderLayers(layers);
                     ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
                     ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -744,27 +801,33 @@
         GTEST_SKIP();
     }
 
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+    for (const DisplayWrapper display : mAllDisplays) {
         ASSERT_TRUE(
                 mComposerClient
-                        ->setClientTargetSlotCount(display->getDisplayId(), kClientTargetSlotCount)
+                        ->setClientTargetSlotCount(display.getDisplayId(), kClientTargetSlotCount)
                         .isOk());
 
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             // sRGB layer
             auto srgbLayer = std::make_shared<TestBufferLayer>(
                     mComposerClient,
-                    *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                    display->getDisplayId(), display->getDisplayWidth(),
-                    display->getDisplayHeight() / 2, PixelFormat::RGBA_8888,
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                    display.getDisplayId(), display.getDisplayWidth(),
+                    display.getDisplayHeight() / 2, PixelFormat::RGBA_8888,
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             std::vector<Color> sRgbDeviceColors(srgbLayer->getWidth() * srgbLayer->getHeight());
-            ReadbackHelper::fillColorsArea(sRgbDeviceColors, display->getDisplayWidth(),
+            ReadbackHelper::fillColorsArea(sRgbDeviceColors, display.getDisplayWidth(),
                                            {0, 0, static_cast<int32_t>(srgbLayer->getWidth()),
                                             static_cast<int32_t>(srgbLayer->getHeight())},
                                            GREEN);
@@ -777,86 +840,90 @@
             // display P3 layer
             auto displayP3Layer = std::make_shared<TestBufferLayer>(
                     mComposerClient,
-                    *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                    display->getDisplayId(), display->getDisplayWidth(),
-                    display->getDisplayHeight() / 2, PixelFormat::RGBA_8888,
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                    display.getDisplayId(), display.getDisplayWidth(),
+                    display.getDisplayHeight() / 2, PixelFormat::RGBA_8888,
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             std::vector<Color> displayP3DeviceColors(
                     static_cast<size_t>(displayP3Layer->getWidth() * displayP3Layer->getHeight()));
-            ReadbackHelper::fillColorsArea(displayP3DeviceColors, display->getDisplayWidth(),
+            ReadbackHelper::fillColorsArea(displayP3DeviceColors, display.getDisplayWidth(),
                                            {0, 0, static_cast<int32_t>(displayP3Layer->getWidth()),
                                             static_cast<int32_t>(displayP3Layer->getHeight())},
                                            RED);
-            displayP3Layer->setDisplayFrame({0, display->getDisplayHeight() / 2,
-                                             display->getDisplayWidth(),
-                                             display->getDisplayHeight()});
+            displayP3Layer->setDisplayFrame({0, display.getDisplayHeight() / 2,
+                                             display.getDisplayWidth(),
+                                             display.getDisplayHeight()});
             displayP3Layer->setZOrder(10);
             displayP3Layer->setDataspace(Dataspace::DISPLAY_P3);
             ASSERT_NO_FATAL_FAILURE(displayP3Layer->setBuffer(displayP3DeviceColors));
 
-            writeLayers({srgbLayer, displayP3Layer}, display->getDisplayId());
+            writeLayers({srgbLayer, displayP3Layer}, display.getDisplayId());
 
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
+            execute(display.getDisplayId());
 
             auto changedCompositionTypes =
-                    mDisplayProperties.at(display->getDisplayId())
-                            .reader.takeChangedCompositionTypes(display->getDisplayId());
+                    mDisplayProperties.at(display.getDisplayId())
+                            .reader.takeChangedCompositionTypes(display.getDisplayId());
             ASSERT_TRUE(changedCompositionTypes.empty());
 
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
             changedCompositionTypes =
-                    mDisplayProperties.at(display->getDisplayId())
-                            .reader.takeChangedCompositionTypes(display->getDisplayId());
+                    mDisplayProperties.at(display.getDisplayId())
+                            .reader.takeChangedCompositionTypes(display.getDisplayId());
             ASSERT_TRUE(changedCompositionTypes.empty());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
         }
     }
 }
 
 TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
+    for (const DisplayWrapper display : mAllDisplays) {
         ASSERT_TRUE(
                 mComposerClient
-                        ->setClientTargetSlotCount(display->getDisplayId(), kClientTargetSlotCount)
+                        ->setClientTargetSlotCount(display.getDisplayId(), kClientTargetSlotCount)
                         .isOk());
 
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
             ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, 0, display->getDisplayWidth(), display->getDisplayHeight() / 2}, GREEN);
-            ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, display->getDisplayHeight() / 2, display->getDisplayWidth(),
-                     display->getDisplayHeight()},
-                    RED);
+                    expectedColors, display.getDisplayWidth(),
+                    {0, 0, display.getDisplayWidth(), display.getDisplayHeight() / 2}, GREEN);
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
+                                           {0, display.getDisplayHeight() / 2,
+                                            display.getDisplayWidth(), display.getDisplayHeight()},
+                                           RED);
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
             auto deviceLayer = std::make_shared<TestBufferLayer>(
                     mComposerClient,
-                    *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                    display->getDisplayId(), display->getDisplayWidth(),
-                    display->getDisplayHeight() / 2, PixelFormat::RGBA_8888,
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                    display.getDisplayId(), display.getDisplayWidth(),
+                    display.getDisplayHeight() / 2, PixelFormat::RGBA_8888,
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
             ReadbackHelper::fillColorsArea(deviceColors,
                                            static_cast<int32_t>(deviceLayer->getWidth()),
@@ -868,7 +935,7 @@
             deviceLayer->setZOrder(10);
             deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
             ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
-            deviceLayer->write(mDisplayProperties.at(display->getDisplayId()).writer);
+            deviceLayer->write(mDisplayProperties.at(display.getDisplayId()).writer);
 
             PixelFormat clientFormat = PixelFormat::RGBA_8888;
             auto clientUsage = static_cast<uint32_t>(
@@ -876,35 +943,34 @@
                     static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
                     static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
             Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
-            int32_t clientWidth = display->getDisplayWidth();
-            int32_t clientHeight = display->getDisplayHeight() / 2;
+            int32_t clientWidth = display.getDisplayWidth();
+            int32_t clientHeight = display.getDisplayHeight() / 2;
 
             auto clientLayer = std::make_shared<TestBufferLayer>(
                     mComposerClient,
-                    *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                    display->getDisplayId(), clientWidth, clientHeight, PixelFormat::RGBA_FP16,
-                    mDisplayProperties.at(display->getDisplayId()).writer, Composition::DEVICE);
-            common::Rect clientFrame = {0, display->getDisplayHeight() / 2,
-                                        display->getDisplayWidth(), display->getDisplayHeight()};
+                    *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                    display.getDisplayId(), clientWidth, clientHeight, PixelFormat::RGBA_FP16,
+                    mDisplayProperties.at(display.getDisplayId()).writer, Composition::DEVICE);
+            common::Rect clientFrame = {0, display.getDisplayHeight() / 2,
+                                        display.getDisplayWidth(), display.getDisplayHeight()};
             clientLayer->setDisplayFrame(clientFrame);
             clientLayer->setZOrder(0);
-            clientLayer->write(mDisplayProperties.at(display->getDisplayId()).writer);
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            clientLayer->write(mDisplayProperties.at(display.getDisplayId()).writer);
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
+            execute(display.getDisplayId());
 
             auto changedCompositionTypes =
-                    mDisplayProperties.at(display->getDisplayId())
-                            .reader.takeChangedCompositionTypes(display->getDisplayId());
+                    mDisplayProperties.at(display.getDisplayId())
+                            .reader.takeChangedCompositionTypes(display.getDisplayId());
             if (changedCompositionTypes.size() != 1) {
                 continue;
             }
             // create client target buffer
             ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
-            const auto& [graphicBufferStatus, graphicBuffer] =
-                    allocateBuffer(*display, clientUsage);
+            const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(display, clientUsage);
             ASSERT_TRUE(graphicBufferStatus);
             const auto& buffer = graphicBuffer->handle;
 
@@ -912,131 +978,133 @@
             int bytesPerPixel = -1;
             int bytesPerStride = -1;
             graphicBuffer->lock(clientUsage,
-                                {0, 0, display->getDisplayWidth(), display->getDisplayHeight()},
+                                {0, 0, display.getDisplayWidth(), display.getDisplayHeight()},
                                 &clientBufData, &bytesPerPixel, &bytesPerStride);
 
             std::vector<Color> clientColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
-            ReadbackHelper::fillColorsArea(clientColors, display->getDisplayWidth(), clientFrame,
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+            ReadbackHelper::fillColorsArea(clientColors, display.getDisplayWidth(), clientFrame,
                                            RED);
             ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
-                    static_cast<uint32_t>(display->getDisplayWidth()),
-                    static_cast<uint32_t>(display->getDisplayHeight()), graphicBuffer->getStride(),
+                    static_cast<uint32_t>(display.getDisplayWidth()),
+                    static_cast<uint32_t>(display.getDisplayHeight()), graphicBuffer->getStride(),
                     bytesPerPixel, clientBufData, clientFormat, clientColors));
             int32_t clientFence;
             const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
             ASSERT_EQ(::android::OK, unlockStatus);
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.setClientTarget(display->getDisplayId(), /*slot*/ 0, buffer,
-                                            clientFence, clientDataspace,
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.setClientTarget(display.getDisplayId(), /*slot*/ 0, buffer, clientFence,
+                                            clientDataspace,
                                             std::vector<common::Rect>(1, clientFrame), 1.f);
             clientLayer->setToClientComposition(
-                    mDisplayProperties.at(display->getDisplayId()).writer);
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+                    mDisplayProperties.at(display.getDisplayId()).writer);
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
+            execute(display.getDisplayId());
             changedCompositionTypes =
-                    mDisplayProperties.at(display->getDisplayId())
-                            .reader.takeChangedCompositionTypes(display->getDisplayId());
+                    mDisplayProperties.at(display.getDisplayId())
+                            .reader.takeChangedCompositionTypes(display.getDisplayId());
             ASSERT_TRUE(changedCompositionTypes.empty());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         }
     }
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerDamage) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
 
-            common::Rect redRect = {0, 0, display->getDisplayWidth() / 4,
-                                    display->getDisplayHeight() / 4};
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
+
+            common::Rect redRect = {0, 0, display.getDisplayWidth() / 4,
+                                    display.getDisplayHeight() / 4};
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
-                                           RED);
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
 
             auto layer = std::make_shared<TestBufferLayer>(
                     mComposerClient,
-                    *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                    display->getDisplayId(), display->getDisplayWidth(),
-                    display->getDisplayHeight(), PixelFormat::RGBA_8888,
-                    mDisplayProperties.at(display->getDisplayId()).writer);
-            layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+                    *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                    display.getDisplayId(), display.getDisplayWidth(), display.getDisplayHeight(),
+                    PixelFormat::RGBA_8888, mDisplayProperties.at(display.getDisplayId()).writer);
+            layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
             layer->setZOrder(10);
             layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
             ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
 
             std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
 
             // update surface damage and recheck
-            redRect = {display->getDisplayWidth() / 4, display->getDisplayHeight() / 4,
-                       display->getDisplayWidth() / 2, display->getDisplayHeight() / 2};
-            ReadbackHelper::clearColors(expectedColors, display->getDisplayWidth(),
-                                        display->getDisplayHeight(), display->getDisplayWidth());
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
-                                           RED);
+            redRect = {display.getDisplayWidth() / 4, display.getDisplayHeight() / 4,
+                       display.getDisplayWidth() / 2, display.getDisplayHeight() / 2};
+            ReadbackHelper::clearColors(expectedColors, display.getDisplayWidth(),
+                                        display.getDisplayHeight(), display.getDisplayWidth());
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
 
             ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
             layer->setSurfaceDamage(std::vector<common::Rect>(
-                    1, {0, 0, display->getDisplayWidth() / 2, display->getDisplayWidth() / 2}));
+                    1, {0, 0, display.getDisplayWidth() / 2, display.getDisplayWidth() / 2}));
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId())
-                                .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId())
+                                .reader.takeChangedCompositionTypes(display.getDisplayId())
                                 .empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         }
@@ -1044,56 +1112,60 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             auto layer = std::make_shared<TestColorLayer>(
-                    mComposerClient, display->getDisplayId(),
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    mComposerClient, display.getDisplayId(),
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             layer->setColor(RED);
-            layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+            layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
             layer->setZOrder(10);
             layer->setAlpha(0);
             layer->setBlendMode(BlendMode::PREMULTIPLIED);
 
             std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1102,70 +1174,72 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
             ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, 0, display->getDisplayWidth(), display->getDisplayHeight() / 4}, RED);
-            ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, display->getDisplayHeight() / 2, display->getDisplayWidth(),
-                     display->getDisplayHeight()},
-                    BLUE);
+                    expectedColors, display.getDisplayWidth(),
+                    {0, 0, display.getDisplayWidth(), display.getDisplayHeight() / 4}, RED);
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
+                                           {0, display.getDisplayHeight() / 2,
+                                            display.getDisplayWidth(), display.getDisplayHeight()},
+                                           BLUE);
 
             auto layer = std::make_shared<TestBufferLayer>(
                     mComposerClient,
-                    *mDisplayProperties.at(display->getDisplayId()).testRenderEngine,
-                    display->getDisplayId(), display->getDisplayWidth(),
-                    display->getDisplayHeight(), PixelFormat::RGBA_8888,
-                    mDisplayProperties.at(display->getDisplayId()).writer);
-            layer->setDisplayFrame({0, 0, display->getDisplayWidth(), display->getDisplayHeight()});
+                    *mDisplayProperties.at(display.getDisplayId()).testRenderEngine,
+                    display.getDisplayId(), display.getDisplayWidth(), display.getDisplayHeight(),
+                    PixelFormat::RGBA_8888, mDisplayProperties.at(display.getDisplayId()).writer);
+            layer->setDisplayFrame({0, 0, display.getDisplayWidth(), display.getDisplayHeight()});
             layer->setZOrder(10);
             layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
-            layer->setSourceCrop({0, static_cast<float>(display->getDisplayHeight() / 2),
-                                  static_cast<float>(display->getDisplayWidth()),
-                                  static_cast<float>(display->getDisplayHeight())});
+            layer->setSourceCrop({0, static_cast<float>(display.getDisplayHeight() / 2),
+                                  static_cast<float>(display.getDisplayWidth()),
+                                  static_cast<float>(display.getDisplayHeight())});
             ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
 
             std::vector<std::shared_ptr<TestLayer>> layers = {layer};
 
             // update expected colors to match crop
             ReadbackHelper::fillColorsArea(
-                    expectedColors, display->getDisplayWidth(),
-                    {0, 0, display->getDisplayWidth(), display->getDisplayHeight()}, BLUE);
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+                    expectedColors, display.getDisplayWidth(),
+                    {0, 0, display.getDisplayWidth(), display.getDisplayHeight()}, BLUE);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1174,98 +1248,100 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
 
-            common::Rect redRect = {0, 0, display->getDisplayWidth(),
-                                    display->getDisplayHeight() / 2};
-            common::Rect blueRect = {0, display->getDisplayHeight() / 4, display->getDisplayWidth(),
-                                     display->getDisplayHeight()};
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
+
+            common::Rect redRect = {0, 0, display.getDisplayWidth(),
+                                    display.getDisplayHeight() / 2};
+            common::Rect blueRect = {0, display.getDisplayHeight() / 4, display.getDisplayWidth(),
+                                     display.getDisplayHeight()};
             auto redLayer = std::make_shared<TestColorLayer>(
-                    mComposerClient, display->getDisplayId(),
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    mComposerClient, display.getDisplayId(),
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             redLayer->setColor(RED);
             redLayer->setDisplayFrame(redRect);
 
             auto blueLayer = std::make_shared<TestColorLayer>(
-                    mComposerClient, display->getDisplayId(),
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    mComposerClient, display.getDisplayId(),
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             blueLayer->setColor(BLUE);
             blueLayer->setDisplayFrame(blueRect);
             blueLayer->setZOrder(5);
 
             std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
 
             // red in front of blue
             redLayer->setZOrder(10);
 
             // fill blue first so that red will overwrite on overlap
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), blueRect,
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), blueRect,
                                            BLUE);
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
-                                           RED);
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
 
             redLayer->setZOrder(1);
-            ReadbackHelper::clearColors(expectedColors, display->getDisplayWidth(),
-                                        display->getDisplayHeight(), display->getDisplayWidth());
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
-                                           RED);
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), blueRect,
+            ReadbackHelper::clearColors(expectedColors, display.getDisplayWidth(),
+                                        display.getDisplayHeight(), display.getDisplayWidth());
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), blueRect,
                                            BLUE);
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId())
-                                .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId())
+                                .reader.takeChangedCompositionTypes(display.getDisplayId())
                                 .empty());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1274,32 +1350,38 @@
 }
 
 TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
 
-            const common::Rect redRect = {0, 0, display->getDisplayWidth(),
-                                          display->getDisplayHeight() / 2};
-            const common::Rect dimmerRedRect = {0, display->getDisplayHeight() / 2,
-                                                display->getDisplayWidth(),
-                                                display->getDisplayHeight()};
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
+
+            const common::Rect redRect = {0, 0, display.getDisplayWidth(),
+                                          display.getDisplayHeight() / 2};
+            const common::Rect dimmerRedRect = {0, display.getDisplayHeight() / 2,
+                                                display.getDisplayWidth(),
+                                                display.getDisplayHeight()};
 
             static constexpr float kMaxBrightnessNits = 300.f;
 
             const auto redLayer = std::make_shared<TestColorLayer>(
-                    mComposerClient, display->getDisplayId(),
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    mComposerClient, display.getDisplayId(),
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             redLayer->setColor(RED);
             redLayer->setDisplayFrame(redRect);
             redLayer->setWhitePointNits(kMaxBrightnessNits);
             redLayer->setBrightness(1.f);
 
             const auto dimmerRedLayer = std::make_shared<TestColorLayer>(
-                    mComposerClient, display->getDisplayId(),
-                    mDisplayProperties.at(display->getDisplayId()).writer);
+                    mComposerClient, display.getDisplayId(),
+                    mDisplayProperties.at(display.getDisplayId()).writer);
             dimmerRedLayer->setColor(RED);
             dimmerRedLayer->setDisplayFrame(dimmerRedRect);
             // Intentionally use a small dimming ratio as some implementations may be more likely
@@ -1310,42 +1392,39 @@
 
             const std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, dimmerRedLayer};
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
 
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(), redRect,
-                                           RED);
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
-                                           dimmerRedRect, DIM_RED);
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), redRect, RED);
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(), dimmerRedRect,
+                                           DIM_RED);
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 ALOGI(" Readback verification not supported for GPU composition for color mode %d",
                       mode);
                 continue;
             }
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1462,49 +1541,53 @@
 };
 
 TEST_P(GraphicsBlendModeCompositionTest, None) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
 
-            setBackgroundColor(display->getDisplayId(), BLACK);
-            setTopLayerColor(display->getDisplayId(), TRANSLUCENT_RED);
-            setUpLayers(*display, BlendMode::NONE);
-            setExpectedColors(*display, expectedColors);
+            setBackgroundColor(display.getDisplayId(), BLACK);
+            setTopLayerColor(display.getDisplayId(), TRANSLUCENT_RED);
+            setUpLayers(display, BlendMode::NONE);
+            setExpectedColors(display, expectedColors);
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-            auto& layers = mDisplayGfx[display->getDisplayId()].layers;
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1513,94 +1596,103 @@
 }
 
 TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
 
-            setBackgroundColor(display->getDisplayId(), BLACK);
-            setTopLayerColor(display->getDisplayId(), TRANSLUCENT_RED);
+            setBackgroundColor(display.getDisplayId(), BLACK);
+            setTopLayerColor(display.getDisplayId(), TRANSLUCENT_RED);
 
-            setUpLayers(*display, BlendMode::COVERAGE);
-            setExpectedColors(*display, expectedColors);
+            setUpLayers(display, BlendMode::COVERAGE);
+            setExpectedColors(display, expectedColors);
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-            auto& layers = mDisplayGfx[display->getDisplayId()].layers;
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
         }
     }
 }
 
 TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
 
-            setBackgroundColor(display->getDisplayId(), BLACK);
-            setTopLayerColor(display->getDisplayId(), TRANSLUCENT_RED);
-            setUpLayers(*display, BlendMode::PREMULTIPLIED);
-            setExpectedColors(*display, expectedColors);
+            setBackgroundColor(display.getDisplayId(), BLACK);
+            setTopLayerColor(display.getDisplayId(), TRANSLUCENT_RED);
+            setUpLayers(display, BlendMode::PREMULTIPLIED);
+            setExpectedColors(display, expectedColors);
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-            auto& layers = mDisplayGfx[display->getDisplayId()].layers;
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1658,58 +1750,63 @@
 };
 
 TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            auto status = mComposerClient->setColorMode(display->getDisplayId(), mode,
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            auto status = mComposerClient->setColorMode(display.getDisplayId(), mode,
                                                         RenderIntent::COLORIMETRIC);
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
+
             if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
                 (status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED ||
                  status.getServiceSpecificError() == IComposerClient::EX_BAD_PARAMETER)) {
                 ALOGI("ColorMode not supported on Display %" PRId64 " for ColorMode %d",
-                      display->getDisplayId(), mode);
+                      display.getDisplayId(), mode);
                 continue;
             }
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-            auto& bufferLayer = mDisplayGfx[display->getDisplayId()].bufferLayer;
+            auto& bufferLayer = mDisplayGfx[display.getDisplayId()].bufferLayer;
             bufferLayer->setTransform(Transform::FLIP_H);
             bufferLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
-            int& sideLength = mDisplayGfx[display->getDisplayId()].sideLength;
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+            int& sideLength = mDisplayGfx[display.getDisplayId()].sideLength;
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
                                            {sideLength / 2, 0, sideLength, sideLength / 2}, RED);
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
                                            {0, sideLength / 2, sideLength / 2, sideLength}, BLUE);
 
-            auto& layers = mDisplayGfx[display->getDisplayId()].layers;
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1718,53 +1815,57 @@
 }
 
 TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
+
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            auto& bufferLayer = mDisplayGfx[display->getDisplayId()].bufferLayer;
+            auto& bufferLayer = mDisplayGfx[display.getDisplayId()].bufferLayer;
             bufferLayer->setTransform(Transform::FLIP_V);
             bufferLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
-            int& sideLength = mDisplayGfx[display->getDisplayId()].sideLength;
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+            int& sideLength = mDisplayGfx[display.getDisplayId()].sideLength;
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
                                            {0, sideLength / 2, sideLength / 2, sideLength}, RED);
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
                                            {sideLength / 2, 0, sideLength, sideLength / 2}, BLUE);
 
-            auto& layers = mDisplayGfx[display->getDisplayId()].layers;
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1773,55 +1874,59 @@
 }
 
 TEST_P(GraphicsTransformCompositionTest, ROT_180) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
 
-            ReadbackBuffer readbackBuffer(
-                    display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                    display->getDisplayHeight(),
-                    mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                    mDisplayProperties.at(display->getDisplayId()).dataspace);
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
+
+            ReadbackBuffer readbackBuffer(display.getDisplayId(), mComposerClient,
+                                          display.getDisplayWidth(), display.getDisplayHeight(),
+                                          mDisplayProperties.at(display.getDisplayId()).pixelFormat,
+                                          dataspace);
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
 
-            auto& bufferLayer = mDisplayGfx[display->getDisplayId()].bufferLayer;
+            auto& bufferLayer = mDisplayGfx[display.getDisplayId()].bufferLayer;
             bufferLayer->setTransform(Transform::ROT_180);
             bufferLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
 
             std::vector<Color> expectedColors(
-                    static_cast<size_t>(display->getDisplayWidth() * display->getDisplayHeight()));
-            int& sideLength = mDisplayGfx[display->getDisplayId()].sideLength;
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+                    static_cast<size_t>(display.getDisplayWidth() * display.getDisplayHeight()));
+            int& sideLength = mDisplayGfx[display.getDisplayId()].sideLength;
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
                                            {sideLength / 2, sideLength / 2, sideLength, sideLength},
                                            RED);
-            ReadbackHelper::fillColorsArea(expectedColors, display->getDisplayWidth(),
+            ReadbackHelper::fillColorsArea(expectedColors, display.getDisplayWidth(),
                                            {0, 0, sideLength / 2, sideLength / 2}, BLUE);
 
-            auto& layers = mDisplayGfx[display->getDisplayId()].layers;
-            writeLayers(layers, display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.validateDisplay(display->getDisplayId(),
+            auto& layers = mDisplayGfx[display.getDisplayId()].layers;
+            writeLayers(layers, display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.validateDisplay(display.getDisplayId(),
                                             ComposerClientWriter::kNoTimestamp,
                                             ComposerClientWrapper::kNoFrameIntervalNs);
-            execute(display->getDisplayId());
-            if (!mDisplayProperties.at(display->getDisplayId())
-                         .reader.takeChangedCompositionTypes(display->getDisplayId())
+            execute(display.getDisplayId());
+            if (!mDisplayProperties.at(display.getDisplayId())
+                         .reader.takeChangedCompositionTypes(display.getDisplayId())
                          .empty()) {
                 continue;
             }
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-            mDisplayProperties.at(display->getDisplayId())
-                    .writer.presentDisplay(display->getDisplayId());
-            execute(display->getDisplayId());
-            ASSERT_TRUE(mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+            mDisplayProperties.at(display.getDisplayId())
+                    .writer.presentDisplay(display.getDisplayId());
+            execute(display.getDisplayId());
+            ASSERT_TRUE(mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
             ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
-            auto& testRenderEngine =
-                    mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+            auto& testRenderEngine = mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
             testRenderEngine->setRenderLayers(layers);
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
             ASSERT_NO_FATAL_FAILURE(testRenderEngine->checkColorBuffer(expectedColors));
@@ -1888,59 +1993,63 @@
 
 // @VsrTest = 4.4-015
 TEST_P(GraphicsColorManagementCompositionTest, ColorConversion) {
-    for (const DisplayWrapper* display : mDisplaysWithReadbackBuffers) {
-        for (ColorMode mode : mDisplayProperties.at(display->getDisplayId()).testColorModes) {
-            EXPECT_TRUE(mComposerClient
-                                ->setColorMode(display->getDisplayId(), mode,
-                                               RenderIntent::COLORIMETRIC)
-                                .isOk());
+    for (const DisplayWrapper display : mAllDisplays) {
+        for (ColorMode mode : mDisplayProperties.at(display.getDisplayId()).testColorModes) {
+            EXPECT_TRUE(
+                    mComposerClient
+                            ->setColorMode(display.getDisplayId(), mode, RenderIntent::COLORIMETRIC)
+                            .isOk());
+
+            auto [dataspace, readbackSupported] =
+                    GetDataspaceAndIfReadBackSupported(display.getDisplayId());
+            if (!readbackSupported) {
+                continue;
+            }
 
             auto& clientCompositionDisplaySettings =
-                    mDisplayProperties.at(display->getDisplayId()).clientCompositionDisplaySettings;
+                    mDisplayProperties.at(display.getDisplayId()).clientCompositionDisplaySettings;
             clientCompositionDisplaySettings.outputDataspace =
-                    static_cast<::android::ui::Dataspace>(
-                            mDisplayProperties.at(display->getDisplayId()).dataspace);
-            mDisplayProperties.at(display->getDisplayId())
+                    static_cast<::android::ui::Dataspace>(dataspace);
+            mDisplayProperties.at(display.getDisplayId())
                     .testRenderEngine->setDisplaySettings(clientCompositionDisplaySettings);
 
-            makeLayer(*display);
+            makeLayer(display);
             for (auto color : {LIGHT_RED, LIGHT_GREEN, LIGHT_BLUE}) {
                 ALOGD("Testing color: %f, %f, %f, %f with color mode: %d", color.r, color.g,
                       color.b, color.a, mode);
                 ReadbackBuffer readbackBuffer(
-                        display->getDisplayId(), mComposerClient, display->getDisplayWidth(),
-                        display->getDisplayHeight(),
-                        mDisplayProperties.at(display->getDisplayId()).pixelFormat,
-                        mDisplayProperties.at(display->getDisplayId()).dataspace);
+                        display.getDisplayId(), mComposerClient, display.getDisplayWidth(),
+                        display.getDisplayHeight(),
+                        mDisplayProperties.at(display.getDisplayId()).pixelFormat, dataspace);
                 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
-                fillColor(*display, color);
-                auto& layer = mDisplayGfx[display->getDisplayId()].layer;
-                writeLayers({layer}, display->getDisplayId());
-                EXPECT_TRUE(mComposerClient->setPowerMode(display->getDisplayId(), PowerMode::ON)
+                fillColor(display, color);
+                auto& layer = mDisplayGfx[display.getDisplayId()].layer;
+                writeLayers({layer}, display.getDisplayId());
+                EXPECT_TRUE(mComposerClient->setPowerMode(display.getDisplayId(), PowerMode::ON)
                                     .isOk());
 
                 ASSERT_TRUE(
-                        mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-                mDisplayProperties.at(display->getDisplayId())
-                        .writer.validateDisplay(display->getDisplayId(),
+                        mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+                mDisplayProperties.at(display.getDisplayId())
+                        .writer.validateDisplay(display.getDisplayId(),
                                                 ComposerClientWriter::kNoTimestamp,
                                                 ComposerClientWrapper::kNoFrameIntervalNs);
-                execute(display->getDisplayId());
-                if (!mDisplayProperties.at(display->getDisplayId())
-                             .reader.takeChangedCompositionTypes(display->getDisplayId())
+                execute(display.getDisplayId());
+                if (!mDisplayProperties.at(display.getDisplayId())
+                             .reader.takeChangedCompositionTypes(display.getDisplayId())
                              .empty()) {
                     continue;
                 }
                 ASSERT_TRUE(
-                        mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
-                mDisplayProperties.at(display->getDisplayId())
-                        .writer.presentDisplay(display->getDisplayId());
-                execute(display->getDisplayId());
+                        mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
+                mDisplayProperties.at(display.getDisplayId())
+                        .writer.presentDisplay(display.getDisplayId());
+                execute(display.getDisplayId());
                 ASSERT_TRUE(
-                        mDisplayProperties.at(display->getDisplayId()).reader.takeErrors().empty());
+                        mDisplayProperties.at(display.getDisplayId()).reader.takeErrors().empty());
 
                 auto& testRenderEngine =
-                        mDisplayProperties.at(display->getDisplayId()).testRenderEngine;
+                        mDisplayProperties.at(display.getDisplayId()).testRenderEngine;
                 testRenderEngine->setRenderLayers({layer});
                 ASSERT_NO_FATAL_FAILURE(testRenderEngine->drawLayers());
                 ASSERT_NO_FATAL_FAILURE(
diff --git a/radio/aidl/Android.bp b/radio/aidl/Android.bp
index a79c807..9c7a5c1 100644
--- a/radio/aidl/Android.bp
+++ b/radio/aidl/Android.bp
@@ -42,7 +42,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 
 }
 
@@ -52,7 +52,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/config/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V4"],
+    imports: ["android.hardware.radio-V5"],
     flags: ["-Werror"],
     backend: {
         cpp: {
@@ -81,7 +81,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 
 }
 
@@ -91,7 +91,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/data/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V4"],
+    imports: ["android.hardware.radio-V5"],
     flags: ["-Werror"],
     backend: {
         cpp: {
@@ -120,7 +120,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -129,7 +129,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/messaging/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V4"],
+    imports: ["android.hardware.radio-V5"],
     flags: ["-Werror"],
     backend: {
         cpp: {
@@ -158,7 +158,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -167,7 +167,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/modem/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V4"],
+    imports: ["android.hardware.radio-V5"],
     flags: ["-Werror"],
     backend: {
         cpp: {
@@ -196,7 +196,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -205,7 +205,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/network/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V4"],
+    imports: ["android.hardware.radio-V5"],
     flags: ["-Werror"],
     backend: {
         cpp: {
@@ -234,7 +234,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -274,8 +274,8 @@
     stability: "vintf",
     flags: ["-Werror"],
     imports: [
-        "android.hardware.radio-V4",
-        "android.hardware.radio.config-V4",
+        "android.hardware.radio-V5",
+        "android.hardware.radio.config-V5",
     ],
     backend: {
         cpp: {
@@ -316,7 +316,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -325,7 +325,7 @@
     host_supported: true,
     srcs: ["android/hardware/radio/voice/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V4"],
+    imports: ["android.hardware.radio-V5"],
     flags: ["-Werror"],
     backend: {
         cpp: {
@@ -354,7 +354,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -363,8 +363,8 @@
     srcs: ["android/hardware/radio/ims/media/*.aidl"],
     stability: "vintf",
     imports: [
-        "android.hardware.radio-V4",
-        "android.hardware.radio.data-V4",
+        "android.hardware.radio-V5",
+        "android.hardware.radio.data-V5",
     ],
     flags: ["-Werror"],
     backend: {
@@ -399,7 +399,7 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
 
 aidl_interface {
@@ -407,7 +407,7 @@
     vendor_available: true,
     srcs: ["android/hardware/radio/ims/*.aidl"],
     stability: "vintf",
-    imports: ["android.hardware.radio-V4"],
+    imports: ["android.hardware.radio-V5"],
     flags: ["-Werror"],
     backend: {
         cpp: {
@@ -432,5 +432,5 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
index 2c66abd..5fc4ea9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/PhoneCapability.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.config;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable PhoneCapability {
   byte maxActiveData;
   byte maxActiveInternetData;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
index ede3189..734d9b2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimPortInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.config;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SimPortInfo {
   String iccId;
   int logicalSlotId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
index e84e7d4..a469e21 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimSlotStatus.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.config;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SimSlotStatus {
   int cardState;
   String atr;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl
index cba5dd9..7e7b25b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.config;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SimTypeInfo {
   android.hardware.radio.config.SimType currentSimType = android.hardware.radio.config.SimType.UNKNOWN;
   int supportedSimTypes;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SlotPortMapping.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SlotPortMapping.aidl
index 5278e79..413c3e0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SlotPortMapping.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SlotPortMapping.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.config;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SlotPortMapping {
   int physicalSlotId;
   int portId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
index d68a9d7..5f0b990 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable DataProfileInfo {
   int profileId;
   String apn;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl
index 3a3f41d..33de1e0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/EpsQos.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable EpsQos {
   int qci;
   android.hardware.radio.data.QosBandwidth downlink;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl
index 789ee86..a4ef5bd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveRequest.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable KeepaliveRequest {
   int type;
   byte[] sourceAddress;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl
index 404b44a..602b6eb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/KeepaliveStatus.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable KeepaliveStatus {
   int sessionHandle;
   int code;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
index 67d679f..c056450 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/LinkAddress.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable LinkAddress {
   String address;
   int addressProperties;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
index 22bbe42..0dcfc10 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/NrQos.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable NrQos {
   int fiveQi;
   android.hardware.radio.data.QosBandwidth downlink;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl
index e4bbf79..65b48a5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/OsAppId.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable OsAppId {
   byte[] osAppId;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl
index ea7529c..01bc46f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PcoDataInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable PcoDataInfo {
   int cid;
   String bearerProto;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl
index e428f1a..ee2e1c1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/PortRange.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable PortRange {
   int start;
   int end;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl
index 4dac56c..4180884 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/Qos.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union Qos {
   boolean noinit;
   android.hardware.radio.data.EpsQos eps;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl
index b59dee0..6456f09 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosBandwidth.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable QosBandwidth {
   int maxBitrateKbps;
   int guaranteedBitrateKbps;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
index a3208d9..8e9754b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilter.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable QosFilter {
   String[] localAddresses;
   String[] remoteAddresses;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl
index 50b52a4..114a581 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpsecSpi.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union QosFilterIpsecSpi {
   boolean noinit;
   int value;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
index 4913dcf..69cc337 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union QosFilterIpv6FlowLabel {
   boolean noinit;
   int value;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl
index 4f0d260..b67997c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosFilterTypeOfService.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union QosFilterTypeOfService {
   boolean noinit;
   byte value;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl
index 89010a9..7f6256c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/QosSession.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable QosSession {
   int qosSessionId;
   android.hardware.radio.data.Qos qos;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
index 80c055e..5e2613c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/RouteSelectionDescriptor.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RouteSelectionDescriptor {
   byte precedence;
   android.hardware.radio.data.PdpProtocolType sessionType = android.hardware.radio.data.PdpProtocolType.IP;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl
index 699cc4d..7620093 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SetupDataCallResult.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable SetupDataCallResult {
   android.hardware.radio.data.DataCallFailCause cause = android.hardware.radio.data.DataCallFailCause.NONE;
   long suggestedRetryTime;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
index 60df402..c704202 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SliceInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SliceInfo {
   byte sliceServiceType;
   int sliceDifferentiator;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl
index 4d28737..4cfbbb3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/SlicingConfig.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SlicingConfig {
   android.hardware.radio.data.UrspRule[] urspRules;
   android.hardware.radio.data.SliceInfo[] sliceInfo;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl
index dc474a2..d73c693 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/TrafficDescriptor.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable TrafficDescriptor {
   @nullable String dnn;
   @nullable android.hardware.radio.data.OsAppId osAppId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl
index 6850f6a..836f83d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/UrspRule.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.data;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable UrspRule {
   int precedence;
   android.hardware.radio.data.TrafficDescriptor[] trafficDescriptors;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl
index eb65eb1..5abe422 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AmrParams.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable AmrParams {
   android.hardware.radio.ims.media.AmrMode amrMode = android.hardware.radio.ims.media.AmrMode.INVALID;
   boolean octetAligned;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl
index eca7b93..c6477a8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/AnbrMode.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable AnbrMode {
   android.hardware.radio.ims.media.CodecMode anbrUplinkMode;
   android.hardware.radio.ims.media.CodecMode anbrDownlinkMode;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl
index 594a39f..649e6b4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CallQuality.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CallQuality {
   int downlinkCallQualityLevel;
   int uplinkCallQualityLevel;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl
index 644321c..9f3cbcb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecMode.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union CodecMode {
   boolean noinit;
   android.hardware.radio.ims.media.AmrMode amr;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl
index 1c80f7a..2ef76b3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecParams.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CodecParams {
   android.hardware.radio.ims.media.CodecType codecType = android.hardware.radio.ims.media.CodecType.INVALID;
   byte rxPayloadTypeNumber;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl
index 7e5722f..5846edd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/CodecSpecificParams.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union CodecSpecificParams {
   android.hardware.radio.ims.media.AmrParams amr;
   android.hardware.radio.ims.media.EvsParams evs;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
index f420fa7..5885685 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable DtmfParams {
   byte rxPayloadTypeNumber;
   byte txPayloadTypeNumber;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl
index 90d2204..536d965 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/EvsParams.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable EvsParams {
   android.hardware.radio.ims.media.EvsBandwidth bandwidth = android.hardware.radio.ims.media.EvsBandwidth.NONE;
   android.hardware.radio.ims.media.EvsMode evsMode = android.hardware.radio.ims.media.EvsMode.INVALID;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl
index da6e751..fd0f53b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityStatus.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable MediaQualityStatus {
   int rtpInactivityTimeMillis;
   int rtcpInactivityTimeMillis;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
index ecc379c..9206c71 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable MediaQualityThreshold {
   int[] rtpInactivityTimerMillis;
   int rtcpInactivityTimerMillis;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl
index 0bc4154..e8a492b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtcpConfig.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RtcpConfig {
   String canonicalName;
   int transmitPort;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl
index dd7f466..79a80e1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpAddress.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RtpAddress {
   String ipAddress;
   int portNumber;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl
index 6af5523..ce89830 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpConfig.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RtpConfig {
   int direction;
   android.hardware.radio.AccessNetwork accessNetwork = android.hardware.radio.AccessNetwork.UNKNOWN;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
index 06207ee..ac54034 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RtpHeaderExtension {
   int localId;
   byte[] data;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpReceptionStats.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpReceptionStats.aidl
index 216da4c..36f33c2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpReceptionStats.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpReceptionStats.aidl
@@ -32,7 +32,7 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.radio.ims.media;
-@VintfStability
+@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RtpReceptionStats {
   int rtpTimestamp;
   int rtcpSrTimestamp;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl
index 4107432..b269bca 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims.media/current/android/hardware/radio/ims/media/RtpSessionParams.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims.media;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RtpSessionParams {
   byte pTimeMillis;
   int maxPtimeMillis;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl
index ae3bbac..2af7647 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ConnectionFailureInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable ConnectionFailureInfo {
   android.hardware.radio.ims.ConnectionFailureInfo.ConnectionFailureReason failureReason = android.hardware.radio.ims.ConnectionFailureInfo.ConnectionFailureReason.INVALID;
   int causeCode;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl
index 73d987a..69d7349 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsCall.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable ImsCall {
   int index;
   android.hardware.radio.ims.ImsCall.CallType callType = android.hardware.radio.ims.ImsCall.CallType.NORMAL;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl
index 73cfd07..dc341d9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/ImsRegistration.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable ImsRegistration {
   android.hardware.radio.ims.ImsRegistrationState regState = android.hardware.radio.ims.ImsRegistrationState.NOT_REGISTERED;
   android.hardware.radio.AccessNetwork accessNetworkType = android.hardware.radio.AccessNetwork.UNKNOWN;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl
index a2e2ae5..9605dbb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.ims/current/android/hardware/radio/ims/SrvccCall.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.ims;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SrvccCall {
   int index;
   android.hardware.radio.ims.SrvccCall.CallType callType = android.hardware.radio.ims.SrvccCall.CallType.NORMAL;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
index 99ab0ea..412f33c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaBroadcastSmsConfigInfo {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl
index 00e584b..fbdc50b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAck.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaSmsAck {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl
index 6a64595..398ca8b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsAddress.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaSmsAddress {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl
index bbf8983..7668c29 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsMessage.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaSmsMessage {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
index 95bfd4c..874a76f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaSmsSubaddress {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
index 759407f..8e77342 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaSmsWriteArgs {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
index 1ccba86..fabb2e7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable GsmBroadcastSmsConfigInfo {
   int fromServiceId;
   int toServiceId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl
index bdd7d0c..ff40ff6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/GsmSmsMessage.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable GsmSmsMessage {
   String smscPdu;
   String pdu;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl
index 3af0f8d..257e2bc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/ImsSmsMessage.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable ImsSmsMessage {
   android.hardware.radio.RadioTechnologyFamily tech = android.hardware.radio.RadioTechnologyFamily.THREE_GPP;
   boolean retry;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl
index ae398a9..ab030c6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SendSmsResult.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SendSmsResult {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl
index a294b47..d9c9846 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/SmsWriteArgs.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.messaging;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SmsWriteArgs {
   int status;
   String pdu;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
index c834342..d5e8d92 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.modem;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable ActivityStatsInfo {
   int sleepModeTimeMs;
   int idleModeTimeMs;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
index 080a877..26770f8 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.modem;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable ActivityStatsTechSpecificInfo {
   android.hardware.radio.AccessNetwork rat = android.hardware.radio.AccessNetwork.UNKNOWN;
   int frequencyRange;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl
index 2d814ef..7d17a88 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfig.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.modem;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable HardwareConfig {
   int type;
   String uuid;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl
index 7d5537f..546832b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigModem.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.modem;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable HardwareConfigModem {
   int rilModel;
   android.hardware.radio.RadioTechnology rat = android.hardware.radio.RadioTechnology.UNKNOWN;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl
index 4c2e31b..7ec7e09 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/HardwareConfigSim.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.modem;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable HardwareConfigSim {
   String modemUuid;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl
index 96fb5a8..2b5302c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ImeiInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.modem;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable ImeiInfo {
   android.hardware.radio.modem.ImeiInfo.ImeiType type = android.hardware.radio.modem.ImeiInfo.ImeiType.INVALID;
   String imei;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
index c941246..0ba0ce0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/NvWriteItem.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.modem;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable NvWriteItem {
   /**
    * @deprecated NV APIs are deprecated starting from Android U.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
index bc3cfcc..b6f15ea 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/RadioCapability.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.modem;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RadioCapability {
   int session;
   int phase;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
index 36b9cdd..cac5d31 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union AccessTechnologySpecificInfo {
   boolean noinit;
   /**
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
index 3c812c0..fe59ee7 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable BarringInfo {
   int serviceType;
   int barringType;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
index 03369b9..1d06b71 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable BarringTypeSpecificInfo {
   int factor;
   int timeSeconds;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
index 5fbd6c4..871d4b5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable Cdma2000RegistrationInfo {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl
index 6e68665..2300c84 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaSignalStrength.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaSignalStrength {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl
index dbd1575..08f5975 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentity.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union CellIdentity {
   boolean noinit;
   android.hardware.radio.network.CellIdentityGsm gsm;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
index 548afd2..a58e193 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellIdentityCdma {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
index 5040f20..c2bc55a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellIdentityGsm {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
index be7821d..b2bfb2a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityLte.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellIdentityLte {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
index 6f4f9a0..4c82dcb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityNr.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellIdentityNr {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
index 864a886..35597b6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellIdentityTdscdma {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
index 4e76277..a42fafc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellIdentityWcdma {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl
index 53d485a..9b7b628 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellInfo {
   boolean registered;
   android.hardware.radio.network.CellConnectionStatus connectionStatus = android.hardware.radio.network.CellConnectionStatus.NONE;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl
index 18c9496..bb37c2d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoCdma.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellInfoCdma {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl
index 2074c2f..87f0341 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoGsm.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellInfoGsm {
   android.hardware.radio.network.CellIdentityGsm cellIdentityGsm;
   android.hardware.radio.network.GsmSignalStrength signalStrengthGsm;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl
index aa3b310..44eff0a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoLte.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellInfoLte {
   android.hardware.radio.network.CellIdentityLte cellIdentityLte;
   android.hardware.radio.network.LteSignalStrength signalStrengthLte;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl
index a8f49af..dbff1e0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoNr.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellInfoNr {
   android.hardware.radio.network.CellIdentityNr cellIdentityNr;
   android.hardware.radio.network.NrSignalStrength signalStrengthNr;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
index 732e70f..30558b5 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union CellInfoRatSpecificInfo {
   android.hardware.radio.network.CellInfoGsm gsm;
   android.hardware.radio.network.CellInfoWcdma wcdma;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl
index 1a03f34..b9ba5de 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoTdscdma.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellInfoTdscdma {
   android.hardware.radio.network.CellIdentityTdscdma cellIdentityTdscdma;
   android.hardware.radio.network.TdscdmaSignalStrength signalStrengthTdscdma;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl
index d02824d..fa0fdbb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellInfoWcdma.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellInfoWcdma {
   android.hardware.radio.network.CellIdentityWcdma cellIdentityWcdma;
   android.hardware.radio.network.WcdmaSignalStrength signalStrengthWcdma;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellularIdentifierDisclosure.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
index 540dc1e..109bacf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CellularIdentifierDisclosure {
   String plmn;
   android.hardware.radio.network.CellularIdentifier identifier = android.hardware.radio.network.CellularIdentifier.UNKNOWN;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
index b9e6f82..b96d64c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable ClosedSubscriberGroupInfo {
   boolean csgIndication;
   String homeNodebName;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
index 7273a94..3959fab 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable EmergencyNetworkScanTrigger {
   android.hardware.radio.AccessNetwork[] accessNetwork;
   android.hardware.radio.network.EmergencyScanType scanType = android.hardware.radio.network.EmergencyScanType.NO_PREFERENCE;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl
index 47940f3..adbb63d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EmergencyRegResult.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable EmergencyRegResult {
   android.hardware.radio.AccessNetwork accessNetwork = android.hardware.radio.AccessNetwork.UNKNOWN;
   android.hardware.radio.network.RegState regState = android.hardware.radio.network.RegState.NOT_REG_MT_NOT_SEARCHING_OP;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
index 2ff454c..e1aa796 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable EutranRegistrationInfo {
   android.hardware.radio.network.LteVopsInfo lteVopsInfo;
   android.hardware.radio.network.NrIndicators nrIndicators;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl
index 2a7eccb..28ca474 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/EvdoSignalStrength.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable EvdoSignalStrength {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl
index 65847ef..7e4bc4a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/GsmSignalStrength.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable GsmSignalStrength {
   int signalStrength;
   int bitErrorRate;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl
index 6dc6d3e..928d216 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LceDataInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable LceDataInfo {
   int lastHopCapacityKbps;
   byte confidenceLevel;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl
index 3fc4b5c..004df28 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LinkCapacityEstimate.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable LinkCapacityEstimate {
   int downlinkCapacityKbps;
   int uplinkCapacityKbps;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl
index eb2ca28..b392ca3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteSignalStrength.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable LteSignalStrength {
   int signalStrength;
   int rsrp;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl
index f8d3aa1..1336096 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/LteVopsInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable LteVopsInfo {
   boolean isVopsSupported;
   boolean isEmcBearerSupported;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
index cdac0be..5c5dcd2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable NetworkScanRequest {
   int type;
   int interval;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
index 518a378..c827fd4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NetworkScanResult.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable NetworkScanResult {
   int status;
   android.hardware.radio.RadioError error = android.hardware.radio.RadioError.NONE;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl
index efcd6d3..38cc957 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrIndicators.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable NrIndicators {
   boolean isEndcAvailable;
   boolean isDcNrRestricted;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
index 45e6ccf..8d89dfc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrSignalStrength.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable NrSignalStrength {
   int ssRsrp;
   int ssRsrq;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl
index 1b5b669..7148894 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/NrVopsInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable NrVopsInfo {
   byte vopsSupported;
   byte emcSupported;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl
index abe2bea..89711c2 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/OperatorInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable OperatorInfo {
   String alphaLong;
   String alphaShort;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl
index f58e5ed..5317842 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfig.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable PhysicalChannelConfig {
   android.hardware.radio.network.CellConnectionStatus status = android.hardware.radio.network.CellConnectionStatus.NONE;
   android.hardware.radio.RadioTechnology rat = android.hardware.radio.RadioTechnology.UNKNOWN;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
index 2e50e67..b18bde0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union PhysicalChannelConfigBand {
   boolean noinit;
   android.hardware.radio.network.GeranBands geranBand;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl
index 9a018f7..aeb1655 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifier.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RadioAccessSpecifier {
   android.hardware.radio.AccessNetwork accessNetwork = android.hardware.radio.AccessNetwork.UNKNOWN;
   android.hardware.radio.network.RadioAccessSpecifierBands bands;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
index 9ba420e..9736024 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 union RadioAccessSpecifierBands {
   boolean noinit;
   android.hardware.radio.network.GeranBands[] geranBands;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl
index 814cde8..4f2c71b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/RegStateResult.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RegStateResult {
   android.hardware.radio.network.RegState regState = android.hardware.radio.network.RegState.NOT_REG_MT_NOT_SEARCHING_OP;
   android.hardware.radio.RadioTechnology rat = android.hardware.radio.RadioTechnology.UNKNOWN;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
index 8613f19..4b55c45 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SecurityAlgorithmUpdate {
   android.hardware.radio.network.ConnectionEvent connectionEvent = android.hardware.radio.network.ConnectionEvent.CS_SIGNALLING_GSM;
   android.hardware.radio.network.SecurityAlgorithm encryption = android.hardware.radio.network.SecurityAlgorithm.A50;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl
index 196ff19..c0c00c6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalStrength.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SignalStrength {
   android.hardware.radio.network.GsmSignalStrength gsm;
   /**
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
index 2041bad..46769e9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable SignalThresholdInfo {
   int signalMeasurement;
   int hysteresisMs;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl
index 5192eae..1a02cc6 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SuppSvcNotification.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SuppSvcNotification {
   boolean isMT;
   int code;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl
index fe209e5..0ed1ddb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/TdscdmaSignalStrength.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable TdscdmaSignalStrength {
   int signalStrength;
   int bitErrorRate;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl
index b765ab6..a6ffa9a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/WcdmaSignalStrength.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.network;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable WcdmaSignalStrength {
   int signalStrength;
   int bitErrorRate;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl
index a3e6d3a..eecec76 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/AppStatus.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable AppStatus {
   int appType;
   int appState;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
index 788a2dc..a9f5050 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CardStatus.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CardStatus {
   int cardState;
   android.hardware.radio.sim.PinState universalPinState = android.hardware.radio.sim.PinState.UNKNOWN;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl
index 24fff2e..406b3aa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Carrier.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable Carrier {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
index 7d4a54b..4318f24 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CarrierInfo {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
index 8f5672f..b053b7f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CarrierRestrictions {
   /**
    * @deprecated use @List<CarrierInfo> allowedCarrierInfoList
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl
index 661518d..7575845 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable IccIo {
   int command;
   int fileId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl
index 1e418cd..8db38de 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IccIoResult.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable IccIoResult {
   int sw1;
   int sw2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
index 40722e5..1ccc262 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable ImsiEncryptionInfo {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl
index b020687..4abde4f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookCapacity.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable PhonebookCapacity {
   int maxAdnRecords;
   int usedAdnRecords;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl
index 1a6943b..9074169 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/PhonebookRecordInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable PhonebookRecordInfo {
   int recordId;
   String name;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl
index b29a4a7..02f4498 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/Plmn.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable Plmn {
   String mcc;
   String mnc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl
index 57ca2a5..8c256be 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SelectUiccSub.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SelectUiccSub {
   int slot;
   int appIndex;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl
index 5c81e3d..cf5ff90 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SessionInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SessionInfo {
   int sessionId;
   boolean isEs10 = false;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
index 45f6e48..b4c57a3 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimApdu.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable SimApdu {
   int sessionId;
   int cla;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
index c546565..25f8372 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/SimRefreshResult.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.sim;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable SimRefreshResult {
   int type;
   int efId;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl
index 33af1fd..194bf25 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Call.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable Call {
   int state;
   int index;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl
index 51c8758..e780fc4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CallForwardInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CallForwardInfo {
   int status;
   int reason;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl
index 7eb8c4e..b5b1471 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaCallWaiting.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaCallWaiting {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
index a673c93..88c04bf 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaDisplayInfoRecord {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
index 143409f..6424ebc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaInformationRecord {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
index 6968a8a..0bf8925 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaLineControlInfoRecord {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
index 684b171..630d1dd 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaNumberInfoRecord {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
index ce7c7c6..33d7362 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaRedirectingNumberInfoRecord {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
index 04e7bdc..899d384 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaSignalInfoRecord {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
index 733d822..ea44344 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaT53AudioControlInfoRecord {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
index 9cf931c..7c528d1 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CdmaT53ClirInfoRecord {
   /**
    * @deprecated Legacy CDMA is unsupported.
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
index fc811f2..050faa4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CfData.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable CfData {
   android.hardware.radio.voice.CallForwardInfo[] cfInfo;
   const int NUM_SERVICE_CLASSES = 7;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl
index 26041f0..d1d77ae 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/Dial.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable Dial {
   String address;
   int clir;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
index 2129f39..76b58f9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable EmergencyNumber {
   String number;
   String mcc;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
index c36a934..d4ea029 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable LastCallFailCauseInfo {
   android.hardware.radio.voice.LastCallFailCause causeCode = android.hardware.radio.voice.LastCallFailCause.INVALID;
   String vendorCause;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
index 2af38fe..4ad82ca 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/SsInfoData.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable SsInfoData {
   int[] ssInfo;
   const int SS_INFO_MAX = 4;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
index d265374..be3f933 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable StkCcUnsolSsResult {
   int serviceType;
   int requestType;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl
index 79c77ee..94be38f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/UusInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio.voice;
 /* @hide */
-@JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable UusInfo {
   int uusType;
   int uusDcs;
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
index e24a35d..2232279 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioConst.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RadioConst {
   const int VALUE_UNAVAILABLE = 0x7FFFFFFF;
   const long VALUE_UNAVAILABLE_LONG = 0x7FFFFFFFFFFFFFFF;
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl
index bfab0c5..a15a3ce 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfo.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RadioResponseInfo {
   android.hardware.radio.RadioResponseType type = android.hardware.radio.RadioResponseType.SOLICITED;
   int serial;
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl
index c445fec..bd8ece0 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioResponseInfoModem.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.radio;
 /* @hide */
-@JavaDerive(toString=true) @VintfStability
+@JavaDerive(toString=true) @RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability
 parcelable RadioResponseInfoModem {
   android.hardware.radio.RadioResponseType type = android.hardware.radio.RadioResponseType.SOLICITED;
   int serial;
diff --git a/radio/aidl/android/hardware/radio/RadioConst.aidl b/radio/aidl/android/hardware/radio/RadioConst.aidl
index df27526..525864d 100644
--- a/radio/aidl/android/hardware/radio/RadioConst.aidl
+++ b/radio/aidl/android/hardware/radio/RadioConst.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RadioConst {
     const int VALUE_UNAVAILABLE = 0x7FFFFFFF;
     const long VALUE_UNAVAILABLE_LONG = 0x7FFFFFFFFFFFFFFF;
diff --git a/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl b/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl
index 926ccf6..5d72ebb 100644
--- a/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl
+++ b/radio/aidl/android/hardware/radio/RadioResponseInfo.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RadioResponseInfo {
     /**
      * Response type
diff --git a/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl b/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl
index 3e76a93..f6b7ed4 100644
--- a/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl
+++ b/radio/aidl/android/hardware/radio/RadioResponseInfoModem.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RadioResponseInfoModem {
     /**
      * Response type
diff --git a/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl b/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
index 265ab96..f0fb1a6 100644
--- a/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
+++ b/radio/aidl/android/hardware/radio/config/PhoneCapability.aidl
@@ -24,6 +24,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable PhoneCapability {
     const byte UNKNOWN = -1;
     /**
diff --git a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
index 380932e..89e0af8 100644
--- a/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimPortInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SimPortInfo {
     /**
      * Integrated Circuit Card IDentifier (ICCID) is the unique identifier of the SIM card. The file
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index 171d97a..56698f0 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SimSlotStatus {
     /**
      * Card state in the physical slot. Values are CardStatus.[STATE_ABSENT, STATE_PRESENT,
diff --git a/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl b/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl
index 0534626..ff9d7bc 100644
--- a/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SimTypeInfo {
     /**
      * Current SimType on the physical slot id.
diff --git a/radio/aidl/android/hardware/radio/config/SlotPortMapping.aidl b/radio/aidl/android/hardware/radio/config/SlotPortMapping.aidl
index 30cca50..9d0f9f6 100644
--- a/radio/aidl/android/hardware/radio/config/SlotPortMapping.aidl
+++ b/radio/aidl/android/hardware/radio/config/SlotPortMapping.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SlotPortMapping {
     /**
      * Physical slot id is the index of the slots
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index 501cbce..260628c 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -23,6 +23,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable DataProfileInfo {
     const int ID_DEFAULT = 0;
     const int ID_TETHERED = 1;
diff --git a/radio/aidl/android/hardware/radio/data/EpsQos.aidl b/radio/aidl/android/hardware/radio/data/EpsQos.aidl
index 42eee32..ecae908 100644
--- a/radio/aidl/android/hardware/radio/data/EpsQos.aidl
+++ b/radio/aidl/android/hardware/radio/data/EpsQos.aidl
@@ -24,6 +24,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable EpsQos {
     /**
      * Quality of Service Class Identifier (QCI), see 3GPP TS 23.203 and 29.212.
diff --git a/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
index 115e47e..1d90b8f 100644
--- a/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
+++ b/radio/aidl/android/hardware/radio/data/KeepaliveRequest.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable KeepaliveRequest {
     /**
      * Keepalive specified by RFC 3948 Sec. 2.3 using IPv4
diff --git a/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl b/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl
index 162fc37..f4a4e9c 100644
--- a/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl
+++ b/radio/aidl/android/hardware/radio/data/KeepaliveStatus.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable KeepaliveStatus {
     /**
      * Keepalive is currently active.
diff --git a/radio/aidl/android/hardware/radio/data/LinkAddress.aidl b/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
index f5d6553..d4e8950 100644
--- a/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
+++ b/radio/aidl/android/hardware/radio/data/LinkAddress.aidl
@@ -23,6 +23,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable LinkAddress {
     const int ADDRESS_PROPERTY_NONE = 0;
     /**
diff --git a/radio/aidl/android/hardware/radio/data/NrQos.aidl b/radio/aidl/android/hardware/radio/data/NrQos.aidl
index f636e6b..75234ac 100644
--- a/radio/aidl/android/hardware/radio/data/NrQos.aidl
+++ b/radio/aidl/android/hardware/radio/data/NrQos.aidl
@@ -24,6 +24,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable NrQos {
     const byte FLOW_ID_RANGE_MIN = 1;
     const byte FLOW_ID_RANGE_MAX = 63;
diff --git a/radio/aidl/android/hardware/radio/data/OsAppId.aidl b/radio/aidl/android/hardware/radio/data/OsAppId.aidl
index ae38cf3..744065b 100644
--- a/radio/aidl/android/hardware/radio/data/OsAppId.aidl
+++ b/radio/aidl/android/hardware/radio/data/OsAppId.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable OsAppId {
     /**
      * Byte array representing OsId + OsAppId. The minimum length of the array is 18 and maximum
diff --git a/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl b/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl
index a487bb3..a4ea7ba 100644
--- a/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/PcoDataInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable PcoDataInfo {
     /**
      * Context ID, uniquely identifies this call
diff --git a/radio/aidl/android/hardware/radio/data/PortRange.aidl b/radio/aidl/android/hardware/radio/data/PortRange.aidl
index 1d436fa..27cf8aa 100644
--- a/radio/aidl/android/hardware/radio/data/PortRange.aidl
+++ b/radio/aidl/android/hardware/radio/data/PortRange.aidl
@@ -25,6 +25,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable PortRange {
     const int PORT_RANGE_MIN = 20;
     const int PORT_RANGE_MAX = 65535;
diff --git a/radio/aidl/android/hardware/radio/data/Qos.aidl b/radio/aidl/android/hardware/radio/data/Qos.aidl
index e98d030..94ae89c 100644
--- a/radio/aidl/android/hardware/radio/data/Qos.aidl
+++ b/radio/aidl/android/hardware/radio/data/Qos.aidl
@@ -25,6 +25,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union Qos {
     boolean noinit;
     EpsQos eps;
diff --git a/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl b/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl
index f2eca41..eafbcac 100644
--- a/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosBandwidth.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable QosBandwidth {
     /**
      * Maximum bit rate possible on the bearer
diff --git a/radio/aidl/android/hardware/radio/data/QosFilter.aidl b/radio/aidl/android/hardware/radio/data/QosFilter.aidl
index 4a2b61d..7918a7f 100644
--- a/radio/aidl/android/hardware/radio/data/QosFilter.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosFilter.aidl
@@ -27,6 +27,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable QosFilter {
     const byte DIRECTION_DOWNLINK = 0;
     const byte DIRECTION_UPLINK = 1;
diff --git a/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl b/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl
index 83c4fe1..3a6e07b 100644
--- a/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosFilterIpsecSpi.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union QosFilterIpsecSpi {
     boolean noinit;
     int value;
diff --git a/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl b/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
index 4591174..41f51c3 100644
--- a/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosFilterIpv6FlowLabel.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union QosFilterIpv6FlowLabel {
     boolean noinit;
     int value;
diff --git a/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl b/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl
index 8d27399..d8585d3 100644
--- a/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosFilterTypeOfService.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union QosFilterTypeOfService {
     boolean noinit;
     byte value;
diff --git a/radio/aidl/android/hardware/radio/data/QosSession.aidl b/radio/aidl/android/hardware/radio/data/QosSession.aidl
index 1a8eb2c..5dc9217 100644
--- a/radio/aidl/android/hardware/radio/data/QosSession.aidl
+++ b/radio/aidl/android/hardware/radio/data/QosSession.aidl
@@ -25,6 +25,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable QosSession {
     /**
      * Unique ID of the QoS session within the data call
diff --git a/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl b/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl
index 4d4b6d5..67e2919 100644
--- a/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl
+++ b/radio/aidl/android/hardware/radio/data/RouteSelectionDescriptor.aidl
@@ -25,6 +25,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RouteSelectionDescriptor {
     const byte SSC_MODE_UNKNOWN = -1;
     const byte SSC_MODE_1 = 1;
diff --git a/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl b/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
index 687982a..8f13050 100644
--- a/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
+++ b/radio/aidl/android/hardware/radio/data/SetupDataCallResult.aidl
@@ -28,6 +28,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SetupDataCallResult {
     /**
      * Indicates the data connection is inactive.
diff --git a/radio/aidl/android/hardware/radio/data/SliceInfo.aidl b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
index 809b8e0..61fee33 100644
--- a/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/SliceInfo.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SliceInfo {
     /*
      * Not specified
diff --git a/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl b/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl
index 47ac41e..d47e8d8 100644
--- a/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl
+++ b/radio/aidl/android/hardware/radio/data/SlicingConfig.aidl
@@ -25,6 +25,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SlicingConfig {
     /**
      * This vector contains the current URSP rules. Empty vector indicates no rules are configured.
diff --git a/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl b/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl
index 098c77a..c880632 100644
--- a/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl
+++ b/radio/aidl/android/hardware/radio/data/TrafficDescriptor.aidl
@@ -26,6 +26,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable TrafficDescriptor {
     /**
      * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003.
diff --git a/radio/aidl/android/hardware/radio/data/UrspRule.aidl b/radio/aidl/android/hardware/radio/data/UrspRule.aidl
index f2028b4..38cddd8 100644
--- a/radio/aidl/android/hardware/radio/data/UrspRule.aidl
+++ b/radio/aidl/android/hardware/radio/data/UrspRule.aidl
@@ -25,6 +25,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable UrspRule {
     /**
      * Precedence value in the range of 0 to 255. Higher value has lower precedence.
diff --git a/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl b/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl
index 92024ac..c079519 100644
--- a/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl
+++ b/radio/aidl/android/hardware/radio/ims/ConnectionFailureInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ConnectionFailureInfo {
     @VintfStability
     @Backing(type="int")
diff --git a/radio/aidl/android/hardware/radio/ims/ImsCall.aidl b/radio/aidl/android/hardware/radio/ims/ImsCall.aidl
index 49fd62c..5818e5e 100644
--- a/radio/aidl/android/hardware/radio/ims/ImsCall.aidl
+++ b/radio/aidl/android/hardware/radio/ims/ImsCall.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ImsCall {
     @Backing(type="int")
     enum CallType {
diff --git a/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl b/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl
index 9018273..929fd28 100644
--- a/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl
+++ b/radio/aidl/android/hardware/radio/ims/ImsRegistration.aidl
@@ -24,6 +24,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ImsRegistration {
     /** Default value */
     const int IMS_MMTEL_CAPABILITY_NONE = 0;
diff --git a/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl b/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl
index 4fdfed0..4f59c0f 100644
--- a/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl
+++ b/radio/aidl/android/hardware/radio/ims/SrvccCall.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SrvccCall {
     @VintfStability
     @Backing(type="int")
diff --git a/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl b/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl
index dbf38c2..b7b68db 100644
--- a/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/AmrParams.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable AmrParams {
     /** mode-set: AMR codec mode to represent the bit rate */
     AmrMode amrMode = AmrMode.INVALID;
diff --git a/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl b/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl
index af6f92f..43a9c83 100644
--- a/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/AnbrMode.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable AnbrMode {
     /**
      * Codec mode converted from bitrate received for uplink
diff --git a/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl b/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl
index dcf9623..71d4edf 100644
--- a/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/CallQuality.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CallQuality {
     /**
      * downlink CallQualityLevel for a given ongoing call
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl
index 6858ef4..0908920 100644
--- a/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecMode.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union CodecMode {
     /** Default value */
     boolean noinit;
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl
index 6da8087..4e7a246 100644
--- a/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecParams.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CodecParams {
     /** Negotiated codec type */
     CodecType codecType = CodecType.INVALID;
diff --git a/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl b/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl
index 86dcea0..2e04b54 100644
--- a/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/CodecSpecificParams.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union CodecSpecificParams {
     AmrParams amr;
     EvsParams evs;
diff --git a/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
index d2926f0..b45aa62 100644
--- a/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/DtmfParams.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable DtmfParams {
     /**
      * Dynamic payload type number to be used for DTMF RTP packets received.
diff --git a/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl b/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl
index 37c7d4b..231ab46 100644
--- a/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/EvsParams.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable EvsParams {
     /** EVS codec bandwidth */
     EvsBandwidth bandwidth = EvsBandwidth.NONE;
diff --git a/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl b/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl
index b617f91..2f571e8 100644
--- a/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/MediaQualityStatus.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable MediaQualityStatus {
     /**
      * Rtp inactivity observed as per threshold set by
diff --git a/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl b/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
index 25473d0..0c942ac 100644
--- a/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/MediaQualityThreshold.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable MediaQualityThreshold {
     /** Array including threshold values in milliseconds for monitoring RTP inactivity */
     int[] rtpInactivityTimerMillis;
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl b/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl
index 9cb3c0e..7819667 100644
--- a/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/RtcpConfig.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RtcpConfig {
     /** Canonical name that will be sent to all session participants */
     String canonicalName;
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl
index c17e4b2..0f98f4c 100644
--- a/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpAddress.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RtpAddress {
     /** Point to point IP address */
     String ipAddress;
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl
index 9aca292..e9467c7 100644
--- a/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpConfig.aidl
@@ -25,6 +25,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RtpConfig {
     /** Media flow direction. The bitfield of MediaDirection(s) */
     int direction;
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
index 19e855a..bd9e939 100644
--- a/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpHeaderExtension.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RtpHeaderExtension {
     /** Local identifier */
     int localId;
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpReceptionStats.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpReceptionStats.aidl
index 81c0bb2..568c7f9 100644
--- a/radio/aidl/android/hardware/radio/ims/media/RtpReceptionStats.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpReceptionStats.aidl
@@ -17,6 +17,7 @@
 package android.hardware.radio.ims.media;
 
 @VintfStability
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RtpReceptionStats {
     /** The timestamp of the latest RTP packet received */
     int rtpTimestamp;
diff --git a/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl b/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl
index ae5c7e6..2e0beb9 100644
--- a/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl
+++ b/radio/aidl/android/hardware/radio/ims/media/RtpSessionParams.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RtpSessionParams {
     /**
      * ptime: Recommended length of time in milliseconds represented by the media
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
index cef8f5d..2254d5b 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaBroadcastSmsConfigInfo {
     /**
      * Defines a broadcast message identifier whose value is 0x0000 - 0xFFFF as defined in
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
index ea5d8b2..94967ec 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaSmsAck {
     /** @deprecated Legacy CDMA is unsupported. */
     boolean errorClass;
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
index 11d953b..27f2708 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaSmsAddress {
     /**
      * DTMF digits
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
index 5332d82..bbb777f 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaSmsMessage {
     /** @deprecated Legacy CDMA is unsupported. */
     int teleserviceId;
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
index 132bbbb..bc4ef55 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
@@ -20,6 +20,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaSmsSubaddress {
     /**
      * CCITT X.213 or ISO 8348 AD2
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
index 3047859..6d8e8ed 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaSmsWriteArgs {
     /** @deprecated Legacy CDMA is unsupported. */
     const int STATUS_REC_UNREAD = 0;
diff --git a/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
index b4ab518..881102e 100644
--- a/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/GsmBroadcastSmsConfigInfo.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable GsmBroadcastSmsConfigInfo {
     /**
      * Beginning of the range of CBM message identifiers whose value is 0x0000 - 0xFFFF as defined
diff --git a/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
index 9a1a7b9..577bd62 100644
--- a/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/GsmSmsMessage.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable GsmSmsMessage {
     /**
      * SMSC address in GSM BCD format prefixed by a length byte (as expected by TS 27.005)
diff --git a/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
index c205323..6074d64 100644
--- a/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
@@ -23,6 +23,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ImsSmsMessage {
     RadioTechnologyFamily tech = RadioTechnologyFamily.THREE_GPP;
     /**
diff --git a/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl b/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
index da41d84..9f1da79 100644
--- a/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SendSmsResult {
     /**
      * TP-Message-Reference for GSM, and BearerData MessageId for CDMA.
diff --git a/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl
index 64ce606..4f5c6a8 100644
--- a/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/SmsWriteArgs.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SmsWriteArgs {
     const int STATUS_REC_UNREAD = 0;
     const int STATUS_REC_READ = 1;
diff --git a/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl b/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
index db77c51..49649ed 100644
--- a/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ActivityStatsInfo.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ActivityStatsInfo {
     /**
      * Total time (in ms) when modem is in a low power or sleep state
diff --git a/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl b/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
index 6ad47fc..bd431da 100644
--- a/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ActivityStatsTechSpecificInfo.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ActivityStatsTechSpecificInfo {
     /** Indicates the frequency range is unknown. */
     const int FREQUENCY_RANGE_UNKNOWN = 0;
diff --git a/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl
index 323e5c9..81fb903 100644
--- a/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl
+++ b/radio/aidl/android/hardware/radio/modem/HardwareConfig.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable HardwareConfig {
     const int STATE_ENABLED = 0;
     const int STATE_STANDBY = 1;
diff --git a/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl
index 0389170..abe268d 100644
--- a/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/HardwareConfigModem.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable HardwareConfigModem {
     /**
      * RIL attachment model. Values are:
diff --git a/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl b/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl
index a5747c1..7145c0f 100644
--- a/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl
+++ b/radio/aidl/android/hardware/radio/modem/HardwareConfigSim.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable HardwareConfigSim {
     /**
      * RadioConst:MAX_UUID_LENGTH is max length of the string
diff --git a/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl b/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl
index 82fade5..e61e4f6 100644
--- a/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ImeiInfo.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ImeiInfo {
     @VintfStability
     @Backing(type="int")
diff --git a/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
index 482126a..a1a932e 100644
--- a/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/NvWriteItem.aidl
@@ -23,6 +23,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable NvWriteItem {
     /**
      * @deprecated NV APIs are deprecated starting from Android U.
diff --git a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
index 9781595..732e9a3 100644
--- a/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
+++ b/radio/aidl/android/hardware/radio/modem/RadioCapability.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RadioCapability {
     /**
      * Logical Modem's (LM) initial value and value after PHASE_FINISH completes.
diff --git a/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
index 10421d6..bdf9a9b 100644
--- a/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
@@ -23,6 +23,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union AccessTechnologySpecificInfo {
     boolean noinit;
     /** @deprecated Legacy CDMA is unsupported. */
diff --git a/radio/aidl/android/hardware/radio/network/BarringInfo.aidl b/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
index 7be3987..cabe325 100644
--- a/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/BarringInfo.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 @SuppressWarnings(value={"redundant-name"})
 parcelable BarringInfo {
     /**
diff --git a/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
index b4a3bdf..9ff47b1 100644
--- a/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/BarringTypeSpecificInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable BarringTypeSpecificInfo {
     /**
      * The barring factor as a percentage 0-100
diff --git a/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
index 333a6c4..3aaa211 100644
--- a/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable Cdma2000RegistrationInfo {
     /** @deprecated Legacy CDMA is unsupported. */
     const int PRL_INDICATOR_NOT_REGISTERED = -1;
diff --git a/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
index 214a512..0b7a717 100644
--- a/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaSignalStrength {
     /**
      * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75,
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentity.aidl b/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
index 76a6675..74adb61 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
@@ -29,6 +29,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union CellIdentity {
     boolean noinit;
     CellIdentityGsm gsm;
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
index 7f33d2d..6093687 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellIdentityCdma {
     /**
      * Network Id 0..65535, RadioConst:VALUE_UNAVAILABLE if unknown
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
index fe39a0e..c4913ff 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityGsm.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellIdentityGsm {
     /**
      * 3-digit Mobile Country Code, 0..999, empty string if unknown
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
index 9c4fc3c..86bb0f8 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityLte.aidl
@@ -23,6 +23,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellIdentityLte {
     /**
      * 3-digit Mobile Country Code, 0..999, empty string if unknown
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
index 7ebc0cd..053cde3 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityNr.aidl
@@ -26,6 +26,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellIdentityNr {
     /**
      * 3-digit Mobile Country Code, in range[0, 999]; This value must be valid for registered or
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
index 8373493..b5e0d68 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityTdscdma.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellIdentityTdscdma {
     /**
      * 3-digit Mobile Country Code, 0..999, empty string if unknown.
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
index ab703f1..a3d44a1 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityWcdma.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellIdentityWcdma {
     /**
      * 3-digit Mobile Country Code, 0..999, empty string if unknown.
diff --git a/radio/aidl/android/hardware/radio/network/CellInfo.aidl b/radio/aidl/android/hardware/radio/network/CellInfo.aidl
index 808a407..9953600 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfo.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellInfo {
     /**
      * True if this cell is registered false if not registered.
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
index 0a0c0c0..0cb6bbc 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
@@ -23,6 +23,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellInfoCdma {
     /** @deprecated Legacy CDMA is unsupported. */
     CellIdentityCdma cellIdentityCdma;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl b/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl
index db84510..7d803e0 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoGsm.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellInfoGsm {
     CellIdentityGsm cellIdentityGsm;
     GsmSignalStrength signalStrengthGsm;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl b/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl
index 3d9b2f3..66ecc0d 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoLte.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellInfoLte {
     CellIdentityLte cellIdentityLte;
     LteSignalStrength signalStrengthLte;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl b/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl
index 61591a9..f462e42 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoNr.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellInfoNr {
     CellIdentityNr cellIdentityNr;
     NrSignalStrength signalStrengthNr;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
index eebed9e..5cf8700 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
@@ -26,6 +26,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union CellInfoRatSpecificInfo {
     /**
      * 3gpp CellInfo types.
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl
index ff0fff3..88249fb 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoTdscdma.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellInfoTdscdma {
     CellIdentityTdscdma cellIdentityTdscdma;
     TdscdmaSignalStrength signalStrengthTdscdma;
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl
index c38e306..1a57eab 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoWcdma.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CellInfoWcdma {
     CellIdentityWcdma cellIdentityWcdma;
     WcdmaSignalStrength signalStrengthWcdma;
diff --git a/radio/aidl/android/hardware/radio/network/CellularIdentifierDisclosure.aidl b/radio/aidl/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
index c851b43..3fd1d71 100644
--- a/radio/aidl/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellularIdentifierDisclosure.aidl
@@ -26,6 +26,7 @@
  * @hide
  */
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 @VintfStability
 parcelable CellularIdentifierDisclosure {
     // The PLMN-ID to which the UE transmitted the cellular identifier
diff --git a/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl b/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
index d61c1dc..8772bdc 100644
--- a/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/ClosedSubscriberGroupInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ClosedSubscriberGroupInfo {
     /**
      * Indicates whether the cell is restricted to only CSG members. A cell not broadcasting the
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl b/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
index 572d1e2..d936969 100644
--- a/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
+++ b/radio/aidl/android/hardware/radio/network/EmergencyNetworkScanTrigger.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable EmergencyNetworkScanTrigger {
     /**
      * Access network to be prioritized during emergency scan. The 1st entry has the highest
diff --git a/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl b/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl
index 7fc4d26..5a3483a 100644
--- a/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/EmergencyRegResult.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable EmergencyRegResult {
     /**
      * Indicates the cellular access network of the current emergency capable system.
diff --git a/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
index 15fabf3..8a74ead 100644
--- a/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/EutranRegistrationInfo.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable EutranRegistrationInfo {
     enum AttachResultType {
         /** Default value. */
diff --git a/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
index e89eb88..326a042 100644
--- a/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable EvdoSignalStrength {
     /**
      * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75,
diff --git a/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
index 4a99646..7446dc8 100644
--- a/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/GsmSignalStrength.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable GsmSignalStrength {
     /**
      * Valid values are (0-61, 99) as defined in TS 27.007 8.69; RadioConst:VALUE_UNAVAILABLE means
diff --git a/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl b/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl
index c855b18..359f3b5 100644
--- a/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/LceDataInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable LceDataInfo {
     /**
      * Last-hop cellular capacity: kilobits/second.
diff --git a/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl b/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
index 795237b..a4ae13a 100644
--- a/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
+++ b/radio/aidl/android/hardware/radio/network/LinkCapacityEstimate.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable LinkCapacityEstimate {
     /**
      * Estimated downlink capacity in kbps. In case of a dual connected network, this includes
diff --git a/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
index 785db0b..3e6a3df 100644
--- a/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/LteSignalStrength.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable LteSignalStrength {
     /**
      * Valid values are (0-31, 99) as defined in TS 27.007 8.5;
diff --git a/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl b/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
index c2aa3b5..73cf389 100644
--- a/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/LteVopsInfo.aidl
@@ -23,6 +23,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable LteVopsInfo {
     /**
      * This indicates if the camped network supports VoLTE services. This information is received from
diff --git a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
index 30977f8..9c7fed0 100644
--- a/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
+++ b/radio/aidl/android/hardware/radio/network/NetworkScanRequest.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 @SuppressWarnings(value={"redundant-name"})
 parcelable NetworkScanRequest {
     const int RADIO_ACCESS_SPECIFIER_MAX_SIZE = 8;
diff --git a/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl b/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
index 700c5e2..2010a9a 100644
--- a/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/NetworkScanResult.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 @SuppressWarnings(value={"redundant-name"})
 parcelable NetworkScanResult {
     /**
diff --git a/radio/aidl/android/hardware/radio/network/NrIndicators.aidl b/radio/aidl/android/hardware/radio/network/NrIndicators.aidl
index 214272c..888874f 100644
--- a/radio/aidl/android/hardware/radio/network/NrIndicators.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrIndicators.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable NrIndicators {
     /**
      * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving
diff --git a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
index a0db2d5..7c28380 100644
--- a/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrSignalStrength.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable NrSignalStrength {
     /**
      * SS reference signal received power, multiplied by -1.
diff --git a/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl b/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl
index 6fe1d27..4e6ace2 100644
--- a/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/NrVopsInfo.aidl
@@ -24,6 +24,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable NrVopsInfo {
     /**
      * Emergency services not supported
diff --git a/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl b/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl
index 36dbadf..9a1c43d 100644
--- a/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/OperatorInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable OperatorInfo {
     const int STATUS_UNKNOWN = 0;
     const int STATUS_AVAILABLE = 1;
diff --git a/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl
index b648ef8..84e6d41 100644
--- a/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl
+++ b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfig.aidl
@@ -23,6 +23,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable PhysicalChannelConfig {
     /**
      * Connection status for cell. Valid values are PRIMARY_SERVING and SECONDARY_SERVING
diff --git a/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
index aa0e9b2..cea2b11 100644
--- a/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
+++ b/radio/aidl/android/hardware/radio/network/PhysicalChannelConfigBand.aidl
@@ -24,6 +24,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union PhysicalChannelConfigBand {
     boolean noinit;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl
index 8bb4fe0..ee7178f 100644
--- a/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl
+++ b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifier.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RadioAccessSpecifier {
     /**
      * The type of network to scan.
diff --git a/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
index 4bf694a..9402985 100644
--- a/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
+++ b/radio/aidl/android/hardware/radio/network/RadioAccessSpecifierBands.aidl
@@ -24,6 +24,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 union RadioAccessSpecifierBands {
     boolean noinit;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
index a4cb647..18a2530 100644
--- a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
@@ -25,6 +25,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable RegStateResult {
     /**
      * Registration state. If the RAT is indicated as a GERAN or UTRAN technology, this
diff --git a/radio/aidl/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl b/radio/aidl/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
index ab48148..59b5f6e 100644
--- a/radio/aidl/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
+++ b/radio/aidl/android/hardware/radio/network/SecurityAlgorithmUpdate.aidl
@@ -26,6 +26,7 @@
  * @hide
  */
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 @VintfStability
 parcelable SecurityAlgorithmUpdate {
     /**
diff --git a/radio/aidl/android/hardware/radio/network/SignalStrength.aidl b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
index 4e3bcf0..9301ef3 100644
--- a/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
@@ -27,6 +27,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SignalStrength {
     /**
      * If GSM measurements are provided, this structure must contain valid measurements; otherwise
diff --git a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
index 1305a2c..f6b7021 100644
--- a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -24,6 +24,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 @SuppressWarnings(value={"redundant-name"})
 parcelable SignalThresholdInfo {
     /**
diff --git a/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl b/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl
index 3b8c8b2..f70c6f1 100644
--- a/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl
+++ b/radio/aidl/android/hardware/radio/network/SuppSvcNotification.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SuppSvcNotification {
     /**
      * Notification type
diff --git a/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
index 87c6baa..66780a8 100644
--- a/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/TdscdmaSignalStrength.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable TdscdmaSignalStrength {
     /**
      * UTRA carrier RSSI as defined in TS 25.225 5.1.4. Valid values are (0-31, 99) as defined in
diff --git a/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
index 8bc7fb8..7086cb5 100644
--- a/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/WcdmaSignalStrength.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable WcdmaSignalStrength {
     /**
      * Valid values are (0-31, 99) as defined in TS 27.007 8.5; RadioConst:VALUE_UNAVAILABLE means
diff --git a/radio/aidl/android/hardware/radio/sim/AppStatus.aidl b/radio/aidl/android/hardware/radio/sim/AppStatus.aidl
index 602c8c5..235737f 100644
--- a/radio/aidl/android/hardware/radio/sim/AppStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/AppStatus.aidl
@@ -23,6 +23,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable AppStatus {
     const int APP_STATE_UNKNOWN = 0;
     const int APP_STATE_DETECTED = 1;
diff --git a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
index 0deb70d..9158258 100644
--- a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
@@ -24,6 +24,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CardStatus {
     /*
      * Card is physically absent from the device. (Some old modems use STATE_ABSENT when the SIM
diff --git a/radio/aidl/android/hardware/radio/sim/Carrier.aidl b/radio/aidl/android/hardware/radio/sim/Carrier.aidl
index 8b27088..09b08ac 100644
--- a/radio/aidl/android/hardware/radio/sim/Carrier.aidl
+++ b/radio/aidl/android/hardware/radio/sim/Carrier.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable Carrier {
     /**
      * Apply to all carrier with the same mcc/mnc
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl b/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
index 74fe31b..90c900e 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierInfo.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CarrierInfo {
     /**
      * MCC (Mobile Country Code) of Carrier. Wild char is either '*' or '?'.
@@ -34,37 +35,30 @@
     /**
      * Service Provider Name(SPN) of the SIM card of the Carrier.
      */
-    @nullable
-    String spn;
+    @nullable String spn;
     /**
      * GID1 value of the SIM card of the Carrier.
      */
-    @nullable
-    String gid1;
+    @nullable String gid1;
     /**
      * GID2 value of the SIM card of the Carrier.
      */
-    @nullable
-    String gid2;
+    @nullable String gid2;
 
     /**
      * IMSI (International Mobile Subscriber Identity) prefix. Wild char is '*'.
      */
-    @nullable
-    String imsiPrefix;
+    @nullable String imsiPrefix;
     /**
      * Equivalent HPLMN of the SIM card of the Carrier.
      */
-    @nullable
-    List<Plmn> ehplmn;
+    @nullable List<Plmn> ehplmn;
     /**
      * ICCID (Integrated Circuit Card Identification) of the SIM card.
      */
-    @nullable
-    String iccid;
+    @nullable String iccid;
     /**
      * IMPI (IMS Private Identity) of the SIM card of the Carrier.
      */
-    @nullable
-    String impi;
-}
\ No newline at end of file
+    @nullable String impi;
+}
diff --git a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
index 69c618f..fd5c418 100644
--- a/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CarrierRestrictions.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CarrierRestrictions {
     @VintfStability
     @Backing(type="int")
diff --git a/radio/aidl/android/hardware/radio/sim/IccIo.aidl b/radio/aidl/android/hardware/radio/sim/IccIo.aidl
index 0877b7a..705d7bb 100644
--- a/radio/aidl/android/hardware/radio/sim/IccIo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IccIo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable IccIo {
     /**
      * One of the commands listed for TS 27.007 +CRSM
diff --git a/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl b/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl
index ac89698..8a676bd 100644
--- a/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IccIoResult.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable IccIoResult {
     int sw1;
     int sw2;
diff --git a/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl b/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
index b31b081..9a34985 100644
--- a/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/ImsiEncryptionInfo.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable ImsiEncryptionInfo {
     /**
      * Key type to be used for ePDG
diff --git a/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl b/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl
index 2212fda..aee9d8c 100644
--- a/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl
+++ b/radio/aidl/android/hardware/radio/sim/PhonebookCapacity.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable PhonebookCapacity {
     /**
      * Maximum number of ADN records possible in the SIM phonebook. Needs to be non-negative.
diff --git a/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl b/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl
index 1653c31..398076e 100644
--- a/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/PhonebookRecordInfo.aidl
@@ -23,6 +23,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable PhonebookRecordInfo {
     /**
      * Record index. 0 is used to insert a record
diff --git a/radio/aidl/android/hardware/radio/sim/Plmn.aidl b/radio/aidl/android/hardware/radio/sim/Plmn.aidl
index fd82692..4b236f9 100644
--- a/radio/aidl/android/hardware/radio/sim/Plmn.aidl
+++ b/radio/aidl/android/hardware/radio/sim/Plmn.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable Plmn {
     /**
      * MCC (Mobile Country Code) of the PLMN
@@ -28,4 +29,4 @@
      * MNC (Mobile Network Code) of the PLMN
      */
     String mnc;
-}
\ No newline at end of file
+}
diff --git a/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl b/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl
index 70a2191..3a1867b 100644
--- a/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SelectUiccSub.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SelectUiccSub {
     const int SUBSCRIPTION_TYPE_1 = 0;
     const int SUBSCRIPTION_TYPE_2 = 1;
diff --git a/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl b/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl
index 585118a..4cefeb4 100644
--- a/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SessionInfo.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SessionInfo {
     /**
      * Session id of the logical channel from TS 27.007 (+CCHC).
diff --git a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
index d0e3c39..05182db 100644
--- a/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimApdu.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SimApdu {
     /**
      * "sessionid" from TS 27.007 +CGLA command. Must be ignored for +CSIM command.
diff --git a/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
index 88c4552..805885f 100644
--- a/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
+++ b/radio/aidl/android/hardware/radio/sim/SimRefreshResult.aidl
@@ -19,6 +19,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 @SuppressWarnings(value={"redundant-name"})
 parcelable SimRefreshResult {
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/Call.aidl b/radio/aidl/android/hardware/radio/voice/Call.aidl
index 5f62faa..b200d07 100644
--- a/radio/aidl/android/hardware/radio/voice/Call.aidl
+++ b/radio/aidl/android/hardware/radio/voice/Call.aidl
@@ -22,6 +22,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable Call {
     const int PRESENTATION_ALLOWED = 0;
     const int PRESENTATION_RESTRICTED = 1;
diff --git a/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl b/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl
index 9b4ecd9..c7c8fa8 100644
--- a/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CallForwardInfo.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CallForwardInfo {
     const int STATUS_DISABLE = 0;
     const int STATUS_ENABLE = 1;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl b/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
index c77f3ec..bcf6159 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaCallWaiting {
     /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_UNKNOWN = 0;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
index bba6e4d..4a3536e 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -27,6 +27,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaDisplayInfoRecord {
     /** @deprecated Legacy CDMA is unsupported. */
     const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
index 7232eba..076438d 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -31,6 +31,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaInformationRecord {
     /** @deprecated Legacy CDMA is unsupported. */
     const int CDMA_MAX_NUMBER_OF_INFO_RECS = 10;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
index 9cf0103..0e7585c 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaLineControlInfoRecord {
     /** @deprecated Legacy CDMA is unsupported. */
     byte lineCtrlPolarityIncluded;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
index bc00acb..f59123d 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -25,6 +25,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaNumberInfoRecord {
     /** @deprecated Legacy CDMA is unsupported. */
     const int CDMA_NUMBER_INFO_BUFFER_LENGTH = 81;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
index 514b8e1..c12601e 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
@@ -22,6 +22,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaRedirectingNumberInfoRecord {
     /**
      * Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
index 2ada10b..5752620 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaSignalInfoRecord {
     /**
      * True if signal information record is present
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
index 68b19b8..a6860ee 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaT53AudioControlInfoRecord {
     /** @deprecated Legacy CDMA is unsupported. */
     byte upLink;
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
index 6a1b992..956a85c 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
@@ -22,6 +22,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CdmaT53ClirInfoRecord {
     /** @deprecated Legacy CDMA is unsupported. */
     byte cause;
diff --git a/radio/aidl/android/hardware/radio/voice/CfData.aidl b/radio/aidl/android/hardware/radio/voice/CfData.aidl
index 84304f4..aef3916 100644
--- a/radio/aidl/android/hardware/radio/voice/CfData.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CfData.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable CfData {
     const int NUM_SERVICE_CLASSES = 7;
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/Dial.aidl b/radio/aidl/android/hardware/radio/voice/Dial.aidl
index a874181..90a42a0 100644
--- a/radio/aidl/android/hardware/radio/voice/Dial.aidl
+++ b/radio/aidl/android/hardware/radio/voice/Dial.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable Dial {
     /**
      * Use subscription default value
diff --git a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
index 30f29a9..4bb0077 100644
--- a/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
+++ b/radio/aidl/android/hardware/radio/voice/EmergencyNumber.aidl
@@ -41,6 +41,7 @@
  */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable EmergencyNumber {
     /**
      * Indicates the number is from the network signal.
diff --git a/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl b/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
index 6af38bb..d8946cb 100644
--- a/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
+++ b/radio/aidl/android/hardware/radio/voice/LastCallFailCauseInfo.aidl
@@ -21,6 +21,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable LastCallFailCauseInfo {
     LastCallFailCause causeCode = LastCallFailCause.INVALID;
     String vendorCause;
diff --git a/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
index 9c9dcff..9370013 100644
--- a/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
+++ b/radio/aidl/android/hardware/radio/voice/SsInfoData.aidl
@@ -20,6 +20,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable SsInfoData {
     const int SS_INFO_MAX = 4;
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl b/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
index 641994e..ea15477 100644
--- a/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
+++ b/radio/aidl/android/hardware/radio/voice/StkCcUnsolSsResult.aidl
@@ -23,6 +23,7 @@
 /** @hide */
 @VintfStability
 @JavaDerive(toString=true)
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable StkCcUnsolSsResult {
     const int REQUEST_TYPE_ACTIVATION = 0;
     const int REQUEST_TYPE_DEACTIVATION = 1;
diff --git a/radio/aidl/android/hardware/radio/voice/UusInfo.aidl b/radio/aidl/android/hardware/radio/voice/UusInfo.aidl
index 3760ac6..ec7cd4e 100644
--- a/radio/aidl/android/hardware/radio/voice/UusInfo.aidl
+++ b/radio/aidl/android/hardware/radio/voice/UusInfo.aidl
@@ -23,6 +23,7 @@
 @VintfStability
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
+@RustDerive(Clone=true, Eq=true, PartialEq=true)
 parcelable UusInfo {
     /**
      * User specified protocol
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
index a3a8c20..04aed77 100644
--- a/radio/aidl/compat/libradiocompat/Android.bp
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -25,16 +25,16 @@
 cc_defaults {
     name: "android.hardware.radio-library.aidl_deps",
     shared_libs: [
-        "android.hardware.radio.config-V4-ndk",
-        "android.hardware.radio.data-V4-ndk",
-        "android.hardware.radio.ims-V3-ndk",
-        "android.hardware.radio.ims.media-V3-ndk",
-        "android.hardware.radio.messaging-V4-ndk",
-        "android.hardware.radio.modem-V4-ndk",
-        "android.hardware.radio.network-V4-ndk",
+        "android.hardware.radio.config-V5-ndk",
+        "android.hardware.radio.data-V5-ndk",
+        "android.hardware.radio.ims-V4-ndk",
+        "android.hardware.radio.ims.media-V4-ndk",
+        "android.hardware.radio.messaging-V5-ndk",
+        "android.hardware.radio.modem-V5-ndk",
+        "android.hardware.radio.network-V5-ndk",
         "android.hardware.radio.sap-V1-ndk",
-        "android.hardware.radio.sim-V4-ndk",
-        "android.hardware.radio.voice-V4-ndk",
+        "android.hardware.radio.sim-V5-ndk",
+        "android.hardware.radio.voice-V5-ndk",
     ],
 }
 
diff --git a/radio/aidl/vts/Android.bp b/radio/aidl/vts/Android.bp
index 6e8ce8b..bbe1333 100644
--- a/radio/aidl/vts/Android.bp
+++ b/radio/aidl/vts/Android.bp
@@ -77,17 +77,17 @@
         "server_configurable_flags",
     ],
     static_libs: [
-        "android.hardware.radio-V4-ndk",
-        "android.hardware.radio.config-V4-ndk",
-        "android.hardware.radio.data-V4-ndk",
-        "android.hardware.radio.ims-V3-ndk",
-        "android.hardware.radio.ims.media-V3-ndk",
-        "android.hardware.radio.messaging-V4-ndk",
-        "android.hardware.radio.modem-V4-ndk",
-        "android.hardware.radio.network-V4-ndk",
+        "android.hardware.radio-V5-ndk",
+        "android.hardware.radio.config-V5-ndk",
+        "android.hardware.radio.data-V5-ndk",
+        "android.hardware.radio.ims-V4-ndk",
+        "android.hardware.radio.ims.media-V4-ndk",
+        "android.hardware.radio.messaging-V5-ndk",
+        "android.hardware.radio.modem-V5-ndk",
+        "android.hardware.radio.network-V5-ndk",
         "android.hardware.radio.sap-V1-ndk",
-        "android.hardware.radio.sim-V4-ndk",
-        "android.hardware.radio.voice-V4-ndk",
+        "android.hardware.radio.sim-V5-ndk",
+        "android.hardware.radio.voice-V5-ndk",
         "telephony_flags_c_lib",
     ],
     test_suites: [
diff --git a/radio/aidl/vts/radio_aidl_hal_utils.h b/radio/aidl/vts/radio_aidl_hal_utils.h
index d9c7311..3e2e633 100644
--- a/radio/aidl/vts/radio_aidl_hal_utils.h
+++ b/radio/aidl/vts/radio_aidl_hal_utils.h
@@ -65,8 +65,6 @@
 
 static constexpr const char* FEATURE_TELEPHONY = "android.hardware.telephony";
 
-static constexpr const char* FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
-
 static constexpr const char* FEATURE_TELEPHONY_IMS = "android.hardware.telephony.ims";
 
 static constexpr const char* FEATURE_TELEPHONY_CALLING = "android.hardware.telephony.calling";
diff --git a/radio/aidl/vts/radio_messaging_test.cpp b/radio/aidl/vts/radio_messaging_test.cpp
index 089895f..7e4ef96 100644
--- a/radio/aidl/vts/radio_messaging_test.cpp
+++ b/radio/aidl/vts/radio_messaging_test.cpp
@@ -113,104 +113,6 @@
 }
 
 /*
- * Test IRadioMessaging.sendCdmaSms() for the response returned.
- */
-TEST_P(RadioMessagingTest, sendCdmaSms) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping sendCdmaSms "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    // Create a CdmaSmsAddress
-    CdmaSmsAddress cdmaSmsAddress;
-    cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
-    cdmaSmsAddress.isNumberModeDataNetwork = false;
-    cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
-    cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
-    cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
-
-    // Create a CdmaSmsSubAddress
-    CdmaSmsSubaddress cdmaSmsSubaddress;
-    cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
-    cdmaSmsSubaddress.odd = false;
-    cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
-
-    // Create a CdmaSmsMessage
-    CdmaSmsMessage cdmaSmsMessage;
-    cdmaSmsMessage.teleserviceId = 4098;
-    cdmaSmsMessage.isServicePresent = false;
-    cdmaSmsMessage.serviceCategory = 0;
-    cdmaSmsMessage.address = cdmaSmsAddress;
-    cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
-    cdmaSmsMessage.bearerData =
-            (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
-
-    radio_messaging->sendCdmaSms(serial, cdmaSmsMessage);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_messaging->rspInfo.error,
-                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
-                CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
- * Test IRadioMessaging.sendCdmaSmsExpectMore() for the response returned.
- */
-TEST_P(RadioMessagingTest, sendCdmaSmsExpectMore) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping sendCdmaSmsExpectMore "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    // Create a CdmaSmsAddress
-    CdmaSmsAddress cdmaSmsAddress;
-    cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
-    cdmaSmsAddress.isNumberModeDataNetwork = false;
-    cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
-    cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
-    cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
-
-    // Create a CdmaSmsSubAddress
-    CdmaSmsSubaddress cdmaSmsSubaddress;
-    cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
-    cdmaSmsSubaddress.odd = false;
-    cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
-
-    // Create a CdmaSmsMessage
-    CdmaSmsMessage cdmaSmsMessage;
-    cdmaSmsMessage.teleserviceId = 4098;
-    cdmaSmsMessage.isServicePresent = false;
-    cdmaSmsMessage.serviceCategory = 0;
-    cdmaSmsMessage.address = cdmaSmsAddress;
-    cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
-    cdmaSmsMessage.bearerData =
-            (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
-
-    radio_messaging->sendCdmaSmsExpectMore(serial, cdmaSmsMessage);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_messaging->rspInfo.error,
-                {RadioError::INVALID_ARGUMENTS, RadioError::INVALID_STATE, RadioError::SIM_ABSENT},
-                CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
  * Test IRadioMessaging.setGsmBroadcastConfig() for the response returned.
  */
 TEST_P(RadioMessagingTest, setGsmBroadcastConfig) {
@@ -304,85 +206,6 @@
 }
 
 /*
- * Test IRadioMessaging.setCdmaBroadcastConfig() for the response returned.
- */
-TEST_P(RadioMessagingTest, setCdmaBroadcastConfig) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping setCdmaBroadcastConfig "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    CdmaBroadcastSmsConfigInfo cbSmsConfig;
-    cbSmsConfig.serviceCategory = 4096;
-    cbSmsConfig.language = 1;
-    cbSmsConfig.selected = true;
-
-    std::vector<CdmaBroadcastSmsConfigInfo> cdmaBroadcastSmsConfigInfoList = {cbSmsConfig};
-
-    radio_messaging->setCdmaBroadcastConfig(serial, cdmaBroadcastSmsConfigInfoList);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
-                                     {RadioError::NONE, RadioError::INVALID_MODEM_STATE},
-                                     CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
- * Test IRadioMessaging.getCdmaBroadcastConfig() for the response returned.
- */
-TEST_P(RadioMessagingTest, getCdmaBroadcastConfig) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping getCdmaBroadcastConfig "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    radio_messaging->getCdmaBroadcastConfig(serial);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error, {RadioError::NONE},
-                                     CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
- * Test IRadioMessaging.setCdmaBroadcastActivation() for the response returned.
- */
-TEST_P(RadioMessagingTest, setCdmaBroadcastActivation) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping setCdmaBroadcastActivation "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-    bool activate = false;
-
-    radio_messaging->setCdmaBroadcastActivation(serial, activate);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
-                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS},
-                                     CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
  * Test IRadioMessaging.setGsmBroadcastActivation() for the response returned.
  */
 TEST_P(RadioMessagingTest, setGsmBroadcastActivation) {
@@ -462,35 +285,6 @@
 }
 
 /*
- * Test IRadioMessaging.acknowledgeLastIncomingCdmaSms() for the response returned.
- */
-TEST_P(RadioMessagingTest, acknowledgeLastIncomingCdmaSms) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping acknowledgeIncomingGsmSmsWithPdu "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    // Create a CdmaSmsAck
-    CdmaSmsAck cdmaSmsAck;
-    cdmaSmsAck.errorClass = false;
-    cdmaSmsAck.smsCauseCode = 1;
-
-    radio_messaging->acknowledgeLastIncomingCdmaSms(serial, cdmaSmsAck);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_messaging->rspInfo.error,
-                                     {RadioError::INVALID_ARGUMENTS, RadioError::NO_SMS_TO_ACK},
-                                     CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
  * Test IRadioMessaging.sendImsSms() for the response returned.
  */
 TEST_P(RadioMessagingTest, sendImsSms) {
@@ -656,118 +450,6 @@
 }
 
 /*
- * Test IRadioMessaging.writeSmsToRuim() for the response returned.
- */
-TEST_P(RadioMessagingTest, writeSmsToRuim) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping writeSmsToRuim "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    // Create a CdmaSmsAddress
-    CdmaSmsAddress cdmaSmsAddress;
-    cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
-    cdmaSmsAddress.isNumberModeDataNetwork = false;
-    cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
-    cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
-    cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
-
-    // Create a CdmaSmsSubAddress
-    CdmaSmsSubaddress cdmaSmsSubaddress;
-    cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
-    cdmaSmsSubaddress.odd = false;
-    cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
-
-    // Create a CdmaSmsMessage
-    CdmaSmsMessage cdmaSmsMessage;
-    cdmaSmsMessage.teleserviceId = 4098;
-    cdmaSmsMessage.isServicePresent = false;
-    cdmaSmsMessage.serviceCategory = 0;
-    cdmaSmsMessage.address = cdmaSmsAddress;
-    cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
-    cdmaSmsMessage.bearerData =
-            (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
-
-    // Create a CdmaSmsWriteArgs
-    CdmaSmsWriteArgs cdmaSmsWriteArgs;
-    cdmaSmsWriteArgs.status = CdmaSmsWriteArgs::STATUS_REC_UNREAD;
-    cdmaSmsWriteArgs.message = cdmaSmsMessage;
-
-    radio_messaging->writeSmsToRuim(serial, cdmaSmsWriteArgs);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_messaging->rspInfo.error,
-                {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_SMS_FORMAT,
-                 RadioError::INVALID_SMSC_ADDRESS, RadioError::INVALID_STATE, RadioError::MODEM_ERR,
-                 RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
-                CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
- * Test IRadioMessaging.deleteSmsOnRuim() for the response returned.
- */
-TEST_P(RadioMessagingTest, deleteSmsOnRuim) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping deleteSmsOnRuim "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-    int index = 1;
-
-    // Create a CdmaSmsAddress
-    CdmaSmsAddress cdmaSmsAddress;
-    cdmaSmsAddress.digitMode = CdmaSmsAddress::DIGIT_MODE_FOUR_BIT;
-    cdmaSmsAddress.isNumberModeDataNetwork = false;
-    cdmaSmsAddress.numberType = CdmaSmsAddress::NUMBER_TYPE_UNKNOWN;
-    cdmaSmsAddress.numberPlan = CdmaSmsAddress::NUMBER_PLAN_UNKNOWN;
-    cdmaSmsAddress.digits = (std::vector<uint8_t>){11, 1, 6, 5, 10, 7, 7, 2, 10, 3, 10, 3};
-
-    // Create a CdmaSmsSubAddress
-    CdmaSmsSubaddress cdmaSmsSubaddress;
-    cdmaSmsSubaddress.subaddressType = CdmaSmsSubaddress::SUBADDRESS_TYPE_NSAP;
-    cdmaSmsSubaddress.odd = false;
-    cdmaSmsSubaddress.digits = (std::vector<uint8_t>){};
-
-    // Create a CdmaSmsMessage
-    CdmaSmsMessage cdmaSmsMessage;
-    cdmaSmsMessage.teleserviceId = 4098;
-    cdmaSmsMessage.isServicePresent = false;
-    cdmaSmsMessage.serviceCategory = 0;
-    cdmaSmsMessage.address = cdmaSmsAddress;
-    cdmaSmsMessage.subAddress = cdmaSmsSubaddress;
-    cdmaSmsMessage.bearerData =
-            (std::vector<uint8_t>){15, 0, 3, 32, 3, 16, 1, 8, 16, 53, 76, 68, 6, 51, 106, 0};
-
-    // Create a CdmaSmsWriteArgs
-    CdmaSmsWriteArgs cdmaSmsWriteArgs;
-    cdmaSmsWriteArgs.status = CdmaSmsWriteArgs::STATUS_REC_UNREAD;
-    cdmaSmsWriteArgs.message = cdmaSmsMessage;
-
-    radio_messaging->deleteSmsOnRuim(serial, index);
-
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_messaging->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_messaging->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_messaging->rspInfo.error,
-                {RadioError::NONE, RadioError::INVALID_ARGUMENTS, RadioError::INVALID_MODEM_STATE,
-                 RadioError::MODEM_ERR, RadioError::NO_SUCH_ENTRY, RadioError::SIM_ABSENT},
-                CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
  * Test IRadioMessaging.reportSmsMemoryStatus() for the response returned.
  */
 TEST_P(RadioMessagingTest, reportSmsMemoryStatus) {
diff --git a/radio/aidl/vts/radio_modem_test.cpp b/radio/aidl/vts/radio_modem_test.cpp
index 9fb7db8..1c8a6f8 100644
--- a/radio/aidl/vts/radio_modem_test.cpp
+++ b/radio/aidl/vts/radio_modem_test.cpp
@@ -201,6 +201,13 @@
         GTEST_SKIP() << "Skipping getDeviceIdentity "
                         "due to undefined FEATURE_TELEPHONY";
     }
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_modem->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version >= 4) {
+        ALOGI("Skipped the test since getDeviceIdentity is deprecated");
+        GTEST_SKIP();
+    }
 
     serial = GetRandomSerialNumber();
 
@@ -285,29 +292,6 @@
 }
 
 /*
- * Test IRadioModem.nvWriteCdmaPrl() for the response returned.
- */
-TEST_P(RadioModemTest, nvWriteCdmaPrl) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping nvWriteCdmaPrl "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-    std::vector<uint8_t> prl = {1, 2, 3, 4, 5};
-
-    radio_modem->nvWriteCdmaPrl(serial, std::vector<uint8_t>(prl));
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_modem->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_modem->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_modem->rspInfo.error, {RadioError::NONE},
-                                     CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
  * Test IRadioModem.nvResetConfig() for the response returned.
  */
 TEST_P(RadioModemTest, nvResetConfig) {
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index ff231db..bdd4148 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -590,42 +590,6 @@
 }
 
 /*
- * Test IRadioNetwork.setSignalStrengthReportingCriteria() for CDMA2000
- */
-TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_Cdma2000) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_RADIO_ACCESS)) {
-        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Cdma2000 "
-                        "due to undefined FEATURE_TELEPHONY_RADIO_ACCESS";
-    }
-
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Cdma2000 "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    SignalThresholdInfo signalThresholdInfo;
-    signalThresholdInfo.signalMeasurement = SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
-    signalThresholdInfo.hysteresisMs = 5000;
-    signalThresholdInfo.hysteresisDb = 2;
-    signalThresholdInfo.thresholds = {-105, -90, -75, -65};
-    signalThresholdInfo.isEnabled = true;
-    signalThresholdInfo.ran = AccessNetwork::CDMA2000;
-
-    ndk::ScopedAStatus res =
-            radio_network->setSignalStrengthReportingCriteria(serial, {signalThresholdInfo});
-    ASSERT_OK(res);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
-
-    ALOGI("setSignalStrengthReportingCriteria_Cdma2000, rspInfo.error = %s\n",
-          toString(radioRsp_network->rspInfo.error).c_str());
-    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error, {RadioError::NONE}));
-}
-
-/*
  * Test IRadioNetwork.setSignalStrengthReportingCriteria() for NGRAN_SSRSRP
  */
 TEST_P(RadioNetworkTest, setSignalStrengthReportingCriteria_NGRAN_SSRSRP) {
@@ -790,15 +754,6 @@
     signalThresholdInfoEutran.isEnabled = true;
     signalThresholdInfoEutran.ran = AccessNetwork::EUTRAN;
 
-    SignalThresholdInfo signalThresholdInfoCdma2000;
-    signalThresholdInfoCdma2000.signalMeasurement =
-            SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_RSSI;
-    signalThresholdInfoCdma2000.hysteresisMs = 5000;
-    signalThresholdInfoCdma2000.hysteresisDb = 2;
-    signalThresholdInfoCdma2000.thresholds = {-105, -90, -75, -65};
-    signalThresholdInfoCdma2000.isEnabled = true;
-    signalThresholdInfoCdma2000.ran = AccessNetwork::CDMA2000;
-
     SignalThresholdInfo signalThresholdInfoNgran;
     signalThresholdInfoNgran.signalMeasurement =
             SignalThresholdInfo::SIGNAL_MEASUREMENT_TYPE_SSRSRP;
@@ -811,9 +766,6 @@
     std::vector<SignalThresholdInfo> candidateSignalThresholdInfos = {
             signalThresholdInfoGeran, signalThresholdInfoUtran, signalThresholdInfoEutran,
             signalThresholdInfoNgran};
-    if (deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        candidateSignalThresholdInfos.push_back(signalThresholdInfoCdma2000);
-    }
 
     std::vector<SignalThresholdInfo> supportedSignalThresholdInfos;
     for (size_t i = 0; i < candidateSignalThresholdInfos.size(); i++) {
@@ -2015,53 +1967,6 @@
 }
 
 /*
- * Test IRadioNetwork.setCdmaRoamingPreference() for the response returned.
- */
-TEST_P(RadioNetworkTest, setCdmaRoamingPreference) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping setCdmaRoamingPreference "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    radio_network->setCdmaRoamingPreference(serial, CdmaRoamingType::HOME_NETWORK);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_network->rspInfo.error,
-                {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::REQUEST_NOT_SUPPORTED}));
-    }
-}
-
-/*
- * Test IRadioNetwork.getCdmaRoamingPreference() for the response returned.
- */
-TEST_P(RadioNetworkTest, getCdmaRoamingPreference) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping getCdmaRoamingPreference "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    radio_network->getCdmaRoamingPreference(serial);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(
-                CheckAnyOfErrors(radioRsp_network->rspInfo.error,
-                                 {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::MODEM_ERR},
-                                 CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
  * Test IRadioNetwork.getVoiceRadioTechnology() for the response returned.
  */
 TEST_P(RadioNetworkTest, getVoiceRadioTechnology) {
diff --git a/radio/aidl/vts/radio_sim_test.cpp b/radio/aidl/vts/radio_sim_test.cpp
index e7c7c65..73beb57 100644
--- a/radio/aidl/vts/radio_sim_test.cpp
+++ b/radio/aidl/vts/radio_sim_test.cpp
@@ -1066,106 +1066,6 @@
 }
 
 /*
- * Test IRadioSim.getCdmaSubscription() for the response returned.
- */
-TEST_P(RadioSimTest, getCdmaSubscription) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping getCdmaSubscription "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    radio_sim->getCdmaSubscription(serial);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_sim->rspInfo.error,
-                {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
-    }
-}
-
-/*
- * Test IRadioSim.getCdmaSubscriptionSource() for the response returned.
- */
-TEST_P(RadioSimTest, getCdmaSubscriptionSource) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping getCdmaSubscriptionSource "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    radio_sim->getCdmaSubscriptionSource(serial);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_sim->rspInfo.error,
-                {RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED, RadioError::SIM_ABSENT}));
-    }
-}
-
-/*
- * Test IRadioSim.setCdmaSubscriptionSource() for the response returned.
- */
-TEST_P(RadioSimTest, setCdmaSubscriptionSource) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping setCdmaSubscriptionSource "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    radio_sim->setCdmaSubscriptionSource(serial, CdmaSubscriptionSource::RUIM_SIM);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(
-                radioRsp_sim->rspInfo.error,
-                {RadioError::NONE, RadioError::SIM_ABSENT, RadioError::SUBSCRIPTION_NOT_AVAILABLE},
-                CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
- * Test IRadioSim.setUiccSubscription() for the response returned.
- */
-TEST_P(RadioSimTest, setUiccSubscription) {
-    if (!shouldTestCdma()) {
-        GTEST_SKIP() << "Skipping CDMA testing (deprecated)";
-    }
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_SUBSCRIPTION)) {
-        GTEST_SKIP() << "Skipping setUiccSubscription "
-                        "due to undefined FEATURE_TELEPHONY_SUBSCRIPTION";
-    }
-
-    serial = GetRandomSerialNumber();
-    SelectUiccSub item;
-    memset(&item, 0, sizeof(item));
-
-    radio_sim->setUiccSubscription(serial, item);
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_sim->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_sim->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(
-                CheckAnyOfErrors(radioRsp_sim->rspInfo.error,
-                                 {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
-                                  RadioError::MODEM_ERR, RadioError::SUBSCRIPTION_NOT_SUPPORTED},
-                                 CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
  * Test IRadioSim.sendEnvelope() for the response returned.
  */
 TEST_P(RadioSimTest, sendEnvelope) {
diff --git a/radio/aidl/vts/radio_voice_test.cpp b/radio/aidl/vts/radio_voice_test.cpp
index 9eb5bac..3df6bfb 100644
--- a/radio/aidl/vts/radio_voice_test.cpp
+++ b/radio/aidl/vts/radio_voice_test.cpp
@@ -821,31 +821,6 @@
 }
 
 /*
- * Test IRadioVoice.sendCdmaFeatureCode() for the response returned.
- */
-TEST_P(RadioVoiceTest, sendCdmaFeatureCode) {
-    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
-        GTEST_SKIP() << "Skipping sendCdmaFeatureCode "
-                        "due to undefined FEATURE_TELEPHONY_CDMA";
-    }
-
-    serial = GetRandomSerialNumber();
-
-    radio_voice->sendCdmaFeatureCode(serial, std::string());
-    EXPECT_EQ(std::cv_status::no_timeout, wait());
-    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_voice->rspInfo.type);
-    EXPECT_EQ(serial, radioRsp_voice->rspInfo.serial);
-
-    if (cardStatus.cardState == CardStatus::STATE_ABSENT) {
-        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_voice->rspInfo.error,
-                                     {RadioError::NONE, RadioError::INVALID_ARGUMENTS,
-                                      RadioError::INVALID_CALL_ID, RadioError::INVALID_MODEM_STATE,
-                                      RadioError::MODEM_ERR, RadioError::OPERATION_NOT_ALLOWED},
-                                     CHECK_GENERAL_ERROR));
-    }
-}
-
-/*
  * Test IRadioVoice.sendDtmf() for the response returned.
  */
 TEST_P(RadioVoiceTest, sendDtmf) {
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
index 1908d05..0ae4b96 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IKeyMintDevice.aidl
@@ -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/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index da3427a..a8ccabf 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -100,6 +100,9 @@
     export_static_lib_headers: [
         "libkeymint_support",
     ],
+    shared_libs: [
+        "libkeystore2_flags_cc",
+    ],
     static_libs: [
         "libgmock_ndk",
     ],
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 0c86a27..0ec76a5 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -29,6 +29,7 @@
 #include <android-base/strings.h>
 #include <android/binder_manager.h>
 #include <android/content/pm/IPackageManagerNative.h>
+#include <android_security_keystore2.h>
 #include <cppbor_parse.h>
 #include <cutils/properties.h>
 #include <gmock/gmock.h>
@@ -387,11 +388,11 @@
     os_patch_level_ = getOsPatchlevel();
     vendor_patch_level_ = getVendorPatchlevel();
 
-    // TODO(b/369375199): temporary code, remove when apexd -> keystore2 -> KeyMint transmission
-    // of module info happens.
-    {
-        GTEST_LOG_(INFO) << "Setting MODULE_HASH to fake value as fallback";
-        // Ensure that a MODULE_HASH value is definitely present in KeyMint (if it's >= v4).
+    if (!::android::security::keystore2::attest_modules()) {
+        // Some tests (for v4+) require that the KeyMint instance has been
+        // provided with a module hash value.  If the keystore2 flag is off,
+        // this will not happen, so set a fake value here instead.
+        GTEST_LOG_(INFO) << "Setting MODULE_HASH to fake value as fallback when flag off";
         vector<uint8_t> fakeModuleHash = {
                 0xf3, 0xf1, 0x1f, 0xe5, 0x13, 0x05, 0xfe, 0xfa, 0xe9, 0xc3, 0x53,
                 0xef, 0x69, 0xdf, 0x9f, 0xd7, 0x0c, 0x1e, 0xcc, 0x2c, 0x2c, 0x62,
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 2f34b9d..5a6eea1 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -9134,5 +9134,12 @@
             }
         }
     }
+    // Some tests rely on information about the state of the system having been received by KeyMint,
+    // so ensure that has happened before running tests.
+    using namespace std::chrono_literals;
+    if (!android::base::WaitForProperty("keystore.module_hash.sent", "true", 30s)) {
+        std::cerr << "Warning: running test before keystore.module_hash.sent is true\n";
+    }
+
     return RUN_ALL_TESTS();
 }
diff --git a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 21c5315..00112b1 100644
--- a/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/rkp/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -54,8 +54,12 @@
  * use by the IRemotelyProvisionedComponent.
  *
  * The root keypair is generated by immutable code (e.g. ROM), from a Unique Device Secret (UDS).
- * The keypair that is generated from it can be referred to as the UDS_Pub/UDS_Priv keys. After the
- * device-unique secret is used, it must be made unavailable to any later boot stage.
+ * The UDS is a hardware-bound secret that forms the root of identify for the device and code
+ * running on the device. The keypair generated from the UDS is referred to as the UDS_Pub/UDS_Priv
+ * keypair. After the device-unique secret is used, it must be made unavailable to any later boot
+ * stage. Refer to the
+ * [Open Profile for DICE ](https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md#uds-details)
+ * specification for more details on the UDS.
  *
  * In this way, booting the device incrementally builds a certificate chain that (a) identifies and
  * validates the integrity of every stage and (b) contains a set of public keys that correspond to
@@ -95,8 +99,8 @@
  *
  * 2) The CDI_Leaf_Priv key cannot be used to sign arbitrary data.
  *
- * 3) Backend infrastructure does not correlate UDS_Pub with the certificates signed and sent back
- *    to the device.
+ * 3) Backend infrastructure very closely guards access to UDS_Pub, limiting it to the minimum
+ *    set of services that need to know it for security, privacy, and counter-abuse purposes.
  *
  * Versioning
  * ==========
diff --git a/security/see/hwcrypto/aidl/Android.bp b/security/see/hwcrypto/aidl/Android.bp
index c64b827..2115f19 100644
--- a/security/see/hwcrypto/aidl/Android.bp
+++ b/security/see/hwcrypto/aidl/Android.bp
@@ -31,6 +31,7 @@
     },
     frozen: true,
     system_ext_specific: true,
+    vendor_available: true,
     versions_with_info: [
         {
             version: "1",
diff --git a/security/see/hwcrypto/aidl/vts/functional/Android.bp b/security/see/hwcrypto/aidl/vts/functional/Android.bp
index beb8976..fc63878 100644
--- a/security/see/hwcrypto/aidl/vts/functional/Android.bp
+++ b/security/see/hwcrypto/aidl/vts/functional/Android.bp
@@ -19,6 +19,8 @@
 rust_defaults {
     name: "hw_crypto_hal_aidl_rust_defaults",
     enabled: false,
+    prefer_rlib: true,
+    vendor_available: true,
     rustlibs: [
         "libbinder_rs",
         "android.hardware.security.see.hwcrypto-V1-rust",
@@ -28,9 +30,10 @@
         "libvsock",
         "librpcbinder_rs",
         "librustutils",
+        "libhwcryptohal_common",
     ],
     arch: {
-        x86_64: {
+        arm64: {
             enabled: true,
         },
     },
@@ -47,37 +50,38 @@
     ],
 }
 
-rust_binary {
-    name: "wait_hw_crypto",
-    prefer_rlib: true,
+rust_test {
+    name: "VtsAidlHwCryptoTests",
+    srcs: ["hwcryptokey_tests.rs"],
+    test_config: "AndroidKeyOperations.xml",
+    require_root: true,
     defaults: [
         "hw_crypto_hal_aidl_rust_defaults",
+        "rdroidtest.defaults",
     ],
-    srcs: ["wait_service.rs"],
     rustlibs: [
         "libhwcryptohal_vts_test",
-        "liblogger",
-        "liblog_rust",
-        "libanyhow",
-        "libclap",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
     ],
 }
 
 rust_test {
-    name: "VtsAidlHwCryptoConnTest",
-    srcs: ["connection_test.rs"],
+    name: "VtsAidlHwCryptoOperationsTests",
+    srcs: ["hwcrypto_operations_tests.rs"],
+    test_config: "AndroidTestOperations.xml",
     require_root: true,
     defaults: [
         "hw_crypto_hal_aidl_rust_defaults",
+        "rdroidtest.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",
+    test_suites: [
+        "general-tests",
+        "vts",
     ],
 }
diff --git a/security/see/hwcrypto/aidl/vts/functional/AndroidKeyOperations.xml b/security/see/hwcrypto/aidl/vts/functional/AndroidKeyOperations.xml
new file mode 100644
index 0000000..57229d7
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/AndroidKeyOperations.xml
@@ -0,0 +1,30 @@
+<?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="Config for HwCrypto HAL operations VTS tests.">
+  <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+    <option name="push-file" key="VtsAidlHwCryptoTests" value="/data/local/tmp/VtsAidlHwCryptoTests" />
+  </target_preparer>
+
+  <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+    <option name="test-device-path" value="/data/local/tmp" />
+    <option name="module-name" value="VtsAidlHwCryptoTests" />
+    <!-- Rust tests are run in parallel by default. Run these ones
+         single-threaded. -->
+    <option name="native-test-flag" value="--test-threads=1" />
+  </test>
+</configuration>
\ No newline at end of file
diff --git a/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml b/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml
deleted file mode 100644
index 73290cf..0000000
--- a/security/see/hwcrypto/aidl/vts/functional/AndroidTest.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?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/AndroidTestOperations.xml b/security/see/hwcrypto/aidl/vts/functional/AndroidTestOperations.xml
new file mode 100644
index 0000000..f069b3b
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/AndroidTestOperations.xml
@@ -0,0 +1,30 @@
+<?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="Config for HwCrypto HAL device key VTS tests.">
+  <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+    <option name="push-file" key="VtsAidlHwCryptoOperationsTests" value="/data/local/tmp/VtsAidlHwCryptoOperationsTests" />
+  </target_preparer>
+
+  <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+    <option name="test-device-path" value="/data/local/tmp" />
+    <option name="module-name" value="VtsAidlHwCryptoOperationsTests" />
+    <!-- Rust tests are run in parallel by default. Run these ones
+         single-threaded. -->
+    <option name="native-test-flag" value="--test-threads=1" />
+  </test>
+</configuration>
\ No newline at end of file
diff --git a/security/see/hwcrypto/aidl/vts/functional/connection_test.rs b/security/see/hwcrypto/aidl/vts/functional/connection_test.rs
deleted file mode 100644
index 338923d..0000000
--- a/security/see/hwcrypto/aidl/vts/functional/connection_test.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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/hwcrypto_operations_tests.rs b/security/see/hwcrypto/aidl/vts/functional/hwcrypto_operations_tests.rs
new file mode 100644
index 0000000..69a34e3
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/hwcrypto_operations_tests.rs
@@ -0,0 +1,596 @@
+/*
+ * 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.
+ */
+
+//! HwCryptoOperations tests.
+
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
+    AesKey::AesKey, ExplicitKeyMaterial::ExplicitKeyMaterial, KeyType::KeyType, KeyLifetime::KeyLifetime,
+    KeyUse::KeyUse, OperationData::OperationData, HmacOperationParameters::HmacOperationParameters,
+    SymmetricOperationParameters::SymmetricOperationParameters, SymmetricOperation::SymmetricOperation,
+    HmacKey::HmacKey, CipherModeParameters::CipherModeParameters, AesCipherMode::AesCipherMode,
+    SymmetricCryptoParameters::SymmetricCryptoParameters,
+};
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::{
+    KeyPolicy::KeyPolicy,CryptoOperation::CryptoOperation,CryptoOperationSet::CryptoOperationSet,
+    OperationParameters::OperationParameters, PatternParameters::PatternParameters,
+};
+use rdroidtest::{ignore_if, rdroidtest};
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_key_operations_connection() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key.getHwCryptoOperations();
+    assert!(hw_crypto_operations.is_ok(), "Couldn't get back a hwcrypto operations binder object");
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_key_operations_simple_aes_test() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let policy = KeyPolicy {
+        usage: KeyUse::ENCRYPT_DECRYPT,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyManagementKey: false,
+        keyType: KeyType::AES_128_CBC_PKCS7_PADDING,
+    };
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    let input_data = OperationData::DataBuffer("string to be encrypted".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    let mut op_result = hw_crypto_operations
+        .processCommandList(&mut crypto_sets)
+        .expect("couldn't process commands");
+    // Extracting the vector from the command list because of ownership
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let context = op_result.remove(0).context;
+    // Separating the finish call on a different command set to test the returned context
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(encrypted_data);
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+
+    // Decrypting
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::DECRYPT;
+    let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    // Extracting the vector from the command list because of ownership
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let decrypted_msg =
+        String::from_utf8(decrypted_data).expect("couldn't decode received message");
+    assert_eq!(decrypted_msg, "string to be encrypted", "couldn't retrieve original message");
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_key_operations_simple_hmac_test() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+    let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
+    let policy = KeyPolicy {
+        usage: KeyUse::SIGN,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyManagementKey: false,
+        keyType: KeyType::HMAC_SHA256,
+    };
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let hmac_parameters = HmacOperationParameters { key: Some(key.clone()) };
+    let op_parameters = OperationParameters::Hmac(hmac_parameters);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_parameters));
+    let input_data = OperationData::DataBuffer("text to be mac'ed".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    // Extracting the vector from the command list because of ownership
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(mac)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+
+    //Getting a second mac to compare
+    let hmac_parameters = HmacOperationParameters { key: Some(key) };
+    let op_parameters = OperationParameters::Hmac(hmac_parameters);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_parameters));
+    let input_data = OperationData::DataBuffer("text to be mac'ed".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    // Extracting the vector from the command list because of ownership
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(mac2)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    assert_eq!(mac, mac2, "got a different mac");
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_key_operations_aes_simple_cbcs_test_non_block_multiple() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+
+    let usage = KeyUse::ENCRYPT_DECRYPT;
+    let key_type = KeyType::AES_128_CBC_NO_PADDING;
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: key_type,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 0,
+    }));
+    let input_data =
+        OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data = OperationData::DataBuffer("unencrypted".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+
+    let clear_encrypted_msg =
+        String::from_utf8(encrypted_data[encrypted_data.len() - "unencrypted".len()..].to_vec())
+            .expect("couldn't decode message");
+    assert_eq!(clear_encrypted_msg, "unencrypted");
+
+    // Decrypting
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::DECRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 0,
+    }));
+    cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let decrypted_msg =
+        String::from_utf8(decrypted_data).expect("couldn't decode received message");
+    assert_eq!(
+        decrypted_msg,
+        "encryption data.0123456789abcdeffedcba9876543210\
+        0123456789abcdefunencrypted",
+        "couldn't retrieve original message"
+    );
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_key_operations_aes_simple_all_encrypted_cbcs_test() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+
+    let usage = KeyUse::ENCRYPT_DECRYPT;
+    let key_type = KeyType::AES_128_CBC_NO_PADDING;
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: key_type,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 0,
+    }));
+    let input_data =
+        OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+
+    // Checking that encrypting with patter 0,0 is equivalent to pattern 1,0
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 0,
+        numberBlocksCopy: 0,
+    }));
+    let input_data =
+        OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data1)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    assert_eq!(encrypted_data, encrypted_data1, "encrypted data should match");
+
+    // Decrypting
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::DECRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let decrypted_msg =
+        String::from_utf8(decrypted_data).expect("couldn't decode received message");
+    assert_eq!(
+        decrypted_msg,
+        "encryption data.0123456789abcdeffedcba9876543210\
+        0123456789abcdef",
+        "couldn't retrieve original message"
+    );
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn check_cbcs_wrong_key_types() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+
+    let usage = KeyUse::ENCRYPT_DECRYPT;
+    let key_type = KeyType::AES_128_CBC_PKCS7_PADDING;
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: key_type,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 9,
+    }));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    let process_result = hw_crypto_operations.processCommandList(&mut crypto_sets);
+    assert!(process_result.is_err(), "Should not be able to use cbcs mode with this key type");
+
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: KeyType::AES_256_CBC_NO_PADDING,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes256([0; 32]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let sym_op_params = SymmetricOperationParameters { key: Some(key), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 9,
+    }));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    let process_result = hw_crypto_operations.processCommandList(&mut crypto_sets);
+
+    assert!(process_result.is_err(), "Should not be able to use cbcs mode with this key type");
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn aes_simple_cbcs_test() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let hw_crypto_operations = hw_crypto_key
+        .getHwCryptoOperations()
+        .expect("Couldn't get back a hwcryptokey operations binder object");
+
+    let usage = KeyUse::ENCRYPT_DECRYPT;
+    let key_type = KeyType::AES_128_CBC_NO_PADDING;
+    let policy = KeyPolicy {
+        usage,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyType: key_type,
+        keyManagementKey: false,
+    };
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+
+    let nonce = [0u8; 16];
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::ENCRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 9,
+    }));
+    let input_data =
+        OperationData::DataBuffer("encryption data.0123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data =
+        OperationData::DataBuffer("fedcba98765432100123456789abcdef".as_bytes().to_vec());
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    let input_data = OperationData::DataBuffer(
+        "fedcba98765432100123456789abcdefProtectedSection".as_bytes().to_vec(),
+    );
+    cmd_list.push(CryptoOperation::DataInput(input_data));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(encrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let clear_encrypted_msg =
+        String::from_utf8(encrypted_data[16..encrypted_data.len() - 16].to_vec())
+            .expect("couldn't decode received message");
+    assert_eq!(
+        clear_encrypted_msg,
+        "0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210\
+        0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdef",
+        "couldn't retrieve clear portion"
+    );
+
+    // Decrypting
+    let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters {
+        nonce: nonce.into(),
+    }));
+    let direction = SymmetricOperation::DECRYPT;
+    let sym_op_params =
+        SymmetricOperationParameters { key: Some(key.clone()), direction, parameters };
+    let op_params = OperationParameters::SymmetricCrypto(sym_op_params);
+    let mut cmd_list = Vec::<CryptoOperation>::new();
+    let data_output = OperationData::DataBuffer(Vec::new());
+    cmd_list.push(CryptoOperation::DataOutput(data_output));
+    cmd_list.push(CryptoOperation::SetOperationParameters(op_params));
+    cmd_list.push(CryptoOperation::SetPattern(PatternParameters {
+        numberBlocksProcess: 1,
+        numberBlocksCopy: 9,
+    }));
+    cmd_list.push(CryptoOperation::DataInput(OperationData::DataBuffer(encrypted_data)));
+    cmd_list.push(CryptoOperation::Finish(None));
+    let crypto_op_set = CryptoOperationSet { context: None, operations: cmd_list };
+    let mut crypto_sets = Vec::new();
+    crypto_sets.push(crypto_op_set);
+    hw_crypto_operations.processCommandList(&mut crypto_sets).expect("couldn't process commands");
+
+    let CryptoOperation::DataOutput(OperationData::DataBuffer(decrypted_data)) =
+        crypto_sets.remove(0).operations.remove(0)
+    else {
+        panic!("not reachable, we created this object above on the test");
+    };
+    let decrypted_msg =
+        String::from_utf8(decrypted_data).expect("couldn't decode received message");
+    assert_eq!(
+        decrypted_msg,
+        "encryption data.0123456789abcdeffedcba9876543210\
+        0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210\
+        0123456789abcdeffedcba98765432100123456789abcdefProtectedSection",
+        "couldn't retrieve original message"
+    );
+}
+
+rdroidtest::test_main!();
diff --git a/security/see/hwcrypto/aidl/vts/functional/hwcryptokey_tests.rs b/security/see/hwcrypto/aidl/vts/functional/hwcryptokey_tests.rs
new file mode 100644
index 0000000..8b4d924
--- /dev/null
+++ b/security/see/hwcrypto/aidl/vts/functional/hwcryptokey_tests.rs
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+//! HwCryptoKey tests.
+
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::{
+    DerivedKeyParameters::DerivedKeyParameters, DerivedKeyPolicy::DerivedKeyPolicy,
+    DiceBoundDerivationKey::DiceBoundDerivationKey, KeySlot::KeySlot,
+};
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{
+    HalErrorCode, AesKey::AesKey, ExplicitKeyMaterial::ExplicitKeyMaterial, KeyType::KeyType, KeyLifetime::KeyLifetime, KeyUse::KeyUse,
+    HmacKey::HmacKey, ProtectionId::ProtectionId,
+};
+use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::KeyPolicy::KeyPolicy;
+use hwcryptohal_common;
+use rdroidtest::{ignore_if, rdroidtest};
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_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");
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_key_get_current_dice_policy() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let dice_policy = hw_crypto_key.getCurrentDicePolicy().expect("Couldn't get dice policy back");
+    assert!(!dice_policy.is_empty(), "received empty dice policy");
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_get_keyslot_data() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let key = hw_crypto_key.getKeyslotData(KeySlot::KEYMINT_SHARED_HMAC_KEY);
+    assert_eq!(
+        key.err()
+            .expect("should not be able to access this keylost from the host")
+            .service_specific_error(),
+        HalErrorCode::UNAUTHORIZED,
+        "wrong error type received"
+    );
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_import_clear_key() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let clear_key = ExplicitKeyMaterial::Aes(AesKey::Aes128([0; 16]));
+    let mut policy = KeyPolicy {
+        usage: KeyUse::ENCRYPT_DECRYPT,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyManagementKey: false,
+        keyType: KeyType::AES_128_GCM,
+    };
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import key");
+    assert!(key.getPublicKey().is_err(), "symmetric keys don't have a public key");
+    let imported_policy = key.getKeyPolicy().expect("couldn't get key policy");
+    let serialized_policy =
+        hwcryptohal_common::key_policy_to_cbor(&policy).expect("couldn't serialize policy");
+    let serialized_impoorted_policy = hwcryptohal_common::key_policy_to_cbor(&imported_policy)
+        .expect("couldn't serialize policy");
+    assert_eq!(serialized_policy, serialized_impoorted_policy, "policies should match");
+    policy.keyLifetime = KeyLifetime::EPHEMERAL;
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy);
+    assert!(key.is_err(), "imported keys should be of type PORTABLE");
+    policy.keyLifetime = KeyLifetime::HARDWARE;
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy);
+    assert!(key.is_err(), "imported keys should be of type PORTABLE");
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_token_export_import() {
+    // This test is not representative of the complete flow because here the exporter and importer
+    // are the same client, which is not something we would usually do
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
+    let policy = KeyPolicy {
+        usage: KeyUse::DERIVE,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyManagementKey: false,
+        keyType: KeyType::HMAC_SHA256,
+    };
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+    let dice_policy = hw_crypto_key.getCurrentDicePolicy().expect("Couldn't get dice policy back");
+    let token =
+        key.getShareableToken(dice_policy.as_slice()).expect("Couldn't get shareable token");
+    let imported_key = hw_crypto_key
+        .keyTokenImport(&token, dice_policy.as_slice());
+    assert!(imported_key.is_ok(), "Couldn't import shareable token");
+    // TODO: Use operations to verify that the keys match
+}
+
+#[rdroidtest]
+#[ignore_if(hwcryptohal_vts_test::ignore_test())]
+fn test_hwcrypto_android_invalid_calls() {
+    let hw_crypto_key = hwcryptohal_vts_test::get_hwcryptokey()
+        .expect("Couldn't get back a hwcryptokey binder object");
+    let clear_key = ExplicitKeyMaterial::Hmac(HmacKey::Sha256([0; 32]));
+    let policy = KeyPolicy {
+        usage: KeyUse::DERIVE,
+        keyLifetime: KeyLifetime::PORTABLE,
+        keyPermissions: Vec::new(),
+        keyManagementKey: false,
+        keyType: KeyType::HMAC_SHA256,
+    };
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+    let protections = Vec::new();
+    let res = key.setProtectionId(ProtectionId::WIDEVINE_OUTPUT_BUFFER, &protections);
+    assert_eq!(
+        res.err()
+            .expect("should not be call this function from the host")
+            .service_specific_error(),
+        HalErrorCode::UNAUTHORIZED,
+        "wrong error type received"
+    );
+    let derivation_key = DiceBoundDerivationKey::OpaqueKey(Some(key));
+    let res = hw_crypto_key.deriveCurrentDicePolicyBoundKey(&derivation_key);
+    assert_eq!(
+        res.err()
+            .expect("should not be call this function from the host")
+            .service_specific_error(),
+        HalErrorCode::UNAUTHORIZED,
+        "wrong error type received"
+    );
+    let fake_policy = Vec::new();
+    let res = hw_crypto_key.deriveDicePolicyBoundKey(&derivation_key, &fake_policy);
+    assert_eq!(
+        res.err()
+            .expect("should not be call this function from the host")
+            .service_specific_error(),
+        HalErrorCode::UNAUTHORIZED,
+        "wrong error type received"
+    );
+    let key = hw_crypto_key.importClearKey(&clear_key, &policy).expect("couldn't import clear key");
+    let derived_policy = DerivedKeyPolicy::OpaqueKey(Vec::new());
+    let derived_parameters = DerivedKeyParameters {
+        derivationKey: Some(key),
+        keyPolicy: derived_policy,
+        context: Vec::new(),
+    };
+    let res = hw_crypto_key.deriveKey(&derived_parameters);
+    assert_eq!(
+        res.err()
+            .expect("should not be call this function from the host")
+            .service_specific_error(),
+        HalErrorCode::UNAUTHORIZED,
+        "wrong error type received"
+    );
+}
+
+rdroidtest::test_main!();
diff --git a/security/see/hwcrypto/aidl/vts/functional/lib.rs b/security/see/hwcrypto/aidl/vts/functional/lib.rs
index e14ac83..43676f6 100644
--- a/security/see/hwcrypto/aidl/vts/functional/lib.rs
+++ b/security/see/hwcrypto/aidl/vts/functional/lib.rs
@@ -17,41 +17,27 @@
 //! 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 anyhow::Result;
 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::IHwCryptoKey;
 
-const HWCRYPTO_SERVICE_PORT: u32 = 4;
+pub const HWCRYPTO_SERVICE: &str = "android.hardware.security.see.hwcrypto.IHwCryptoKey";
 
-/// 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 using the service manager
+pub fn get_hwcryptokey() -> Result<binder::Strong<dyn IHwCryptoKey>, binder::Status> {
+    let interface_name = HWCRYPTO_SERVICE.to_owned() + "/default";
+    Ok(binder::get_interface(&interface_name)?)
 }
 
-/// 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)?)
+pub fn get_supported_instances() -> Vec<(String, String)> {
+    // Determine which instances are available.
+    binder::get_declared_instances(HWCRYPTO_SERVICE)
+        .unwrap_or_default()
+        .into_iter()
+        .map(|v| (v.clone(), v))
+        .collect()
+}
+
+pub fn ignore_test() -> bool {
+    let instances = get_supported_instances();
+    instances.len() == 0
 }
diff --git a/security/see/hwcrypto/aidl/vts/functional/wait_service.rs b/security/see/hwcrypto/aidl/vts/functional/wait_service.rs
deleted file mode 100644
index 13cbcb1..0000000
--- a/security/see/hwcrypto/aidl/vts/functional/wait_service.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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/security/see/hwcrypto/default/Android.bp b/security/see/hwcrypto/default/Android.bp
new file mode 100644
index 0000000..7a4a7b6
--- /dev/null
+++ b/security/see/hwcrypto/default/Android.bp
@@ -0,0 +1,143 @@
+// 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.
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "hwcryptohallib",
+    enabled: false,
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libbinder",
+        "libbinder_ndk",
+        "libbinder_trusty",
+        "libtrusty",
+        "libutils",
+
+        // AIDL interface deps versions, please refer to below link
+        // https://source.android.com/docs/core/architecture/aidl/stable-aidl#module-naming-rules
+        "android.hardware.security.see.hwcrypto-V1-ndk",
+        "android.hardware.security.see.hwcrypto-V1-cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    srcs: ["hwcryptolib.cpp"],
+    proprietary: true,
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+}
+
+cc_binary {
+    name: "android.hardware.trusty.hwcryptohal-service",
+    enabled: false,
+    relative_install_path: "hw",
+    srcs: [
+        "hwcrypto_delegator.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libbinder",
+        "libbinder_ndk",
+        "libbinder_trusty",
+        "libtrusty",
+        "libutils",
+        "hwcryptohallib",
+
+        // AIDL interface deps versions, please refer to below link
+        // https://source.android.com/docs/core/architecture/aidl/stable-aidl#module-naming-rules
+        "android.hardware.security.see.hwcrypto-V1-ndk",
+        "android.hardware.security.see.hwcrypto-V1-cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    proprietary: true,
+    vintf_fragments: ["android.hardware.security.see.hwcrypto-service.trusty.xml"],
+    init_rc: ["android.hardware.security.see.hwcrypto-service.trusty.rc"],
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+}
+
+cc_fuzz {
+    name: "android.hardware.trusty.hwcryptohal-service_fuzzer",
+    enabled: false,
+    defaults: ["service_fuzzer_defaults"],
+    static_libs: [
+        "android.hardware.security.see.hwcrypto-V1-ndk",
+        "android.hardware.security.see.hwcrypto-V1-cpp",
+        "liblog",
+        "hwcryptohallib",
+    ],
+    shared_libs: [
+        "libbinder_trusty",
+        "libtrusty",
+    ],
+    srcs: ["fuzzer.cpp"],
+    fuzz_config: {
+        cc: [
+            "oarbildo@google.com",
+        ],
+    },
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+}
+
+cc_test {
+    name: "HwCryptoHalDelegatorTests",
+    enabled: false,
+    require_root: true,
+    srcs: [
+        "delegatorTest.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libutils",
+        "libbinder",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.security.see.hwcrypto-V1-ndk",
+        "android.hardware.security.see.hwcrypto-V1-cpp",
+        "hwcryptohallib",
+    ],
+
+    arch: {
+        arm64: {
+            enabled: true,
+        },
+    },
+}
diff --git a/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.rc b/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.rc
new file mode 100644
index 0000000..8665755
--- /dev/null
+++ b/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.rc
@@ -0,0 +1,5 @@
+service trusty-hwcryptohal /vendor/bin/hw/android.hardware.trusty.hwcryptohal-service \
+-d ${ro.hardware.trusty_ipc_dev:-/dev/trusty-ipc-dev0}
+    class hal
+    user system
+    group system
diff --git a/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.xml b/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.xml
new file mode 100644
index 0000000..8ac0942
--- /dev/null
+++ b/security/see/hwcrypto/default/android.hardware.security.see.hwcrypto-service.trusty.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.security.see.hwcrypto</name>
+        <version>1</version>
+        <interface>
+            <name>IHwCryptoKey</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
\ No newline at end of file
diff --git a/security/see/hwcrypto/default/delegatorTest.cpp b/security/see/hwcrypto/default/delegatorTest.cpp
new file mode 100644
index 0000000..28b177d
--- /dev/null
+++ b/security/see/hwcrypto/default/delegatorTest.cpp
@@ -0,0 +1,122 @@
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <linux/dma-heap.h>
+#include <sys/auxv.h>
+#include <sys/mman.h>
+#include "hwcryptokeyimpl.h"
+
+static inline bool align_overflow(size_t size, size_t alignment, size_t* aligned) {
+    if (size % alignment == 0) {
+        *aligned = size;
+        return false;
+    }
+    size_t temp = 0;
+    bool overflow = __builtin_add_overflow(size / alignment, 1, &temp);
+    overflow |= __builtin_mul_overflow(temp, alignment, aligned);
+    return overflow;
+}
+
+static int allocate_buffers(size_t size) {
+    const char* device_name = "/dev/dma_heap/system";
+    int dma_heap_fd = open(device_name, O_RDONLY | O_CLOEXEC);
+    if (dma_heap_fd < 0) {
+        LOG(ERROR) << "Cannot open " << device_name;
+        return -1;
+    }
+    size_t aligned = 0;
+    if (align_overflow(size, getauxval(AT_PAGESZ), &aligned)) {
+        LOG(ERROR) << "Rounding up buffer size oveflowed";
+        return -1;
+    }
+    struct dma_heap_allocation_data allocation_request = {
+            .len = aligned,
+            .fd_flags = O_RDWR | O_CLOEXEC,
+    };
+    int rc = ioctl(dma_heap_fd, DMA_HEAP_IOCTL_ALLOC, &allocation_request);
+    if (rc < 0) {
+        LOG(ERROR) << "Buffer allocation request failed  " << rc;
+        return -1;
+    }
+    int fd = allocation_request.fd;
+    if (fd < 0) {
+        LOG(ERROR) << "Allocation request returned bad fd" << fd;
+        return -1;
+    }
+    return fd;
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
+
+TEST(HwCryptoHalDelegator, FdTest) {
+    const std::string instance =
+            std::string() + ndk_hwcrypto::IHwCryptoKey::descriptor + "/default";
+    ndk::SpAIBinder binder(AServiceManager_waitForService(instance.c_str()));
+    ASSERT_NE(binder, nullptr);
+    auto hwCryptoKey = ndk_hwcrypto::IHwCryptoKey::fromBinder(binder);
+    ASSERT_NE(hwCryptoKey, nullptr);
+    auto fd = allocate_buffers(4096);
+    EXPECT_GE(fd, 0);
+    ndk::ScopedFileDescriptor ndkFd(fd);
+    ndk_hwcrypto::MemoryBufferParameter memBuffParam = ndk_hwcrypto::MemoryBufferParameter();
+    memBuffParam.bufferHandle.set<ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::input>(
+            std::move(ndkFd));
+    memBuffParam.sizeBytes = 4096;
+    auto operation = ndk_hwcrypto::CryptoOperation();
+    operation.set<ndk_hwcrypto::CryptoOperation::setMemoryBuffer>(std::move(memBuffParam));
+    ndk_hwcrypto::CryptoOperationSet operationSet = ndk_hwcrypto::CryptoOperationSet();
+    operationSet.context = nullptr;
+    operationSet.operations.push_back(std::move(operation));
+    std::vector<ndk_hwcrypto::CryptoOperationSet> operationSets;
+    operationSets.push_back(std::move(operationSet));
+    std::vector<ndk_hwcrypto::CryptoOperationResult> aidl_return;
+    std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations> hwCryptoOperations;
+    auto res = hwCryptoKey->getHwCryptoOperations(&hwCryptoOperations);
+    EXPECT_TRUE(res.isOk());
+    res = hwCryptoOperations->processCommandList(&operationSets, &aidl_return);
+    EXPECT_TRUE(res.isOk());
+}
+
+TEST(HwCryptoHalDelegator, keyPolicyCppToNdk) {
+    cpp_hwcrypto::KeyPolicy cppPolicy = cpp_hwcrypto::KeyPolicy();
+    cppPolicy.keyType = cpp_hwcrypto::types::KeyType::AES_128_CBC_PKCS7_PADDING;
+    cppPolicy.usage = cpp_hwcrypto::types::KeyUse::DECRYPT;
+    cppPolicy.keyLifetime = cpp_hwcrypto::types::KeyLifetime::PORTABLE;
+    cppPolicy.keyManagementKey = false;
+    cppPolicy.keyPermissions.push_back(
+            cpp_hwcrypto::types::KeyPermissions::ALLOW_PORTABLE_KEY_WRAPPING);
+    ndk_hwcrypto::KeyPolicy ndkPolicy = android::trusty::hwcryptohalservice::convertKeyPolicy<
+            ndk_hwcrypto::KeyPolicy, cpp_hwcrypto::KeyPolicy>(cppPolicy);
+    EXPECT_EQ(ndkPolicy.keyType, ndk_hwcrypto::types::KeyType::AES_128_CBC_PKCS7_PADDING);
+    EXPECT_EQ(ndkPolicy.usage, ndk_hwcrypto::types::KeyUse::DECRYPT);
+    EXPECT_EQ(ndkPolicy.keyLifetime, ndk_hwcrypto::types::KeyLifetime::PORTABLE);
+    EXPECT_EQ(ndkPolicy.keyManagementKey, false);
+    EXPECT_EQ(ndkPolicy.keyPermissions.size(), 1ul);
+    EXPECT_EQ(ndkPolicy.keyPermissions[0],
+              ndk_hwcrypto::types::KeyPermissions::ALLOW_PORTABLE_KEY_WRAPPING);
+}
+
+TEST(HwCryptoHalDelegator, keyPolicyNdkToCpp) {
+    ndk_hwcrypto::KeyPolicy ndkPolicy = ndk_hwcrypto::KeyPolicy();
+    ndkPolicy.keyType = ndk_hwcrypto::types::KeyType::AES_128_CTR;
+    ndkPolicy.usage = ndk_hwcrypto::types::KeyUse::ENCRYPT_DECRYPT;
+    ndkPolicy.keyLifetime = ndk_hwcrypto::types::KeyLifetime::HARDWARE;
+    ndkPolicy.keyManagementKey = true;
+    ndkPolicy.keyPermissions.push_back(
+            ndk_hwcrypto::types::KeyPermissions::ALLOW_EPHEMERAL_KEY_WRAPPING);
+    ndkPolicy.keyPermissions.push_back(
+            ndk_hwcrypto::types::KeyPermissions::ALLOW_HARDWARE_KEY_WRAPPING);
+    cpp_hwcrypto::KeyPolicy cppPolicy = android::trusty::hwcryptohalservice::convertKeyPolicy<
+            cpp_hwcrypto::KeyPolicy, ndk_hwcrypto::KeyPolicy>(ndkPolicy);
+    EXPECT_EQ(cppPolicy.keyType, cpp_hwcrypto::types::KeyType::AES_128_CTR);
+    EXPECT_EQ(cppPolicy.usage, cpp_hwcrypto::types::KeyUse::ENCRYPT_DECRYPT);
+    EXPECT_EQ(cppPolicy.keyLifetime, cpp_hwcrypto::types::KeyLifetime::HARDWARE);
+    EXPECT_EQ(cppPolicy.keyManagementKey, true);
+    EXPECT_EQ(cppPolicy.keyPermissions.size(), 2ul);
+    EXPECT_EQ(cppPolicy.keyPermissions[0],
+              cpp_hwcrypto::types::KeyPermissions::ALLOW_EPHEMERAL_KEY_WRAPPING);
+    EXPECT_EQ(cppPolicy.keyPermissions[1],
+              cpp_hwcrypto::types::KeyPermissions::ALLOW_HARDWARE_KEY_WRAPPING);
+}
diff --git a/security/see/hwcrypto/default/fuzzer.cpp b/security/see/hwcrypto/default/fuzzer.cpp
new file mode 100644
index 0000000..4673066
--- /dev/null
+++ b/security/see/hwcrypto/default/fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 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.
+ */
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include "hwcryptokeyimpl.h"
+
+using android::fuzzService;
+using ndk::SharedRefBase;
+
+static const char* TIPC_DEFAULT_DEVNAME = "/dev/trusty-ipc-dev0";
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    auto hwCryptoServer =
+            android::trusty::hwcryptohalservice::HwCryptoKey::Create(TIPC_DEFAULT_DEVNAME);
+
+    fuzzService(hwCryptoServer->asBinder().get(), FuzzedDataProvider(data, size));
+
+    return 0;
+}
diff --git a/security/see/hwcrypto/default/hwcrypto_delegator.cpp b/security/see/hwcrypto/default/hwcrypto_delegator.cpp
new file mode 100644
index 0000000..1c3528c
--- /dev/null
+++ b/security/see/hwcrypto/default/hwcrypto_delegator.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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 <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <getopt.h>
+#include <string>
+#include "hwcryptokeyimpl.h"
+
+static void showUsageAndExit(int code) {
+    LOG(ERROR) << "usage: android.hardware.trusty.hwcryptohal-service -d <trusty_dev>";
+    exit(code);
+}
+
+static void parseDeviceName(int argc, char* argv[], char*& device_name) {
+    static const char* _sopts = "h:d:";
+    static const struct option _lopts[] = {{"help", no_argument, nullptr, 'h'},
+                                           {"trusty_dev", required_argument, nullptr, 'd'},
+                                           {0, 0, 0, 0}};
+    int opt;
+    int oidx = 0;
+
+    while ((opt = getopt_long(argc, argv, _sopts, _lopts, &oidx)) != -1) {
+        switch (opt) {
+            case 'd':
+                device_name = strdup(optarg);
+                break;
+            case 'h':
+                showUsageAndExit(EXIT_SUCCESS);
+                break;
+            default:
+                LOG(ERROR) << "unrecognized option: " << opt;
+                showUsageAndExit(EXIT_FAILURE);
+        }
+    }
+
+    if (device_name == nullptr) {
+        LOG(ERROR) << "missing required argument(s)";
+        showUsageAndExit(EXIT_FAILURE);
+    }
+
+    LOG(INFO) << "starting android.hardware.trusty.hwcryptohal-service";
+    LOG(INFO) << "trusty dev: " << device_name;
+}
+
+int main(int argc, char* argv[]) {
+    char* device_name;
+    parseDeviceName(argc, argv, device_name);
+
+    auto hwCryptoServer = android::trusty::hwcryptohalservice::HwCryptoKey::Create(device_name);
+    if (hwCryptoServer == nullptr) {
+        LOG(ERROR) << "couldn't create hwcrypto service";
+        exit(EXIT_FAILURE);
+    }
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    const std::string instance =
+            std::string() + ndk_hwcrypto::IHwCryptoKey::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(hwCryptoServer->asBinder().get(), instance.c_str());
+    if (status != STATUS_OK) {
+        LOG(ERROR) << "couldn't register hwcrypto service";
+    }
+    CHECK_EQ(status, STATUS_OK);
+    ABinderProcess_joinThreadPool();
+
+    return 0;
+}
diff --git a/security/see/hwcrypto/default/hwcryptokeyimpl.h b/security/see/hwcrypto/default/hwcryptokeyimpl.h
new file mode 100644
index 0000000..7d3ade7
--- /dev/null
+++ b/security/see/hwcrypto/default/hwcryptokeyimpl.h
@@ -0,0 +1,119 @@
+/*
+ * 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 <aidl/android/hardware/security/see/hwcrypto/BnHwCryptoKey.h>
+#include <aidl/android/hardware/security/see/hwcrypto/IHwCryptoKey.h>
+#include <aidl/android/hardware/security/see/hwcrypto/types/HalErrorCode.h>
+#include <android-base/logging.h>
+#include <android-base/result.h>
+#include <android/hardware/security/see/hwcrypto/IHwCryptoKey.h>
+#include <binder/RpcSession.h>
+
+// We use cpp interfaces to talk to Trusty, and ndk interfaces for the platform
+namespace cpp_hwcrypto = android::hardware::security::see::hwcrypto;
+namespace ndk_hwcrypto = aidl::android::hardware::security::see::hwcrypto;
+
+namespace android {
+namespace trusty {
+namespace hwcryptohalservice {
+
+class HwCryptoKey : public ndk_hwcrypto::BnHwCryptoKey {
+  private:
+    sp<cpp_hwcrypto::IHwCryptoKey> mHwCryptoServer;
+    sp<IBinder> mRoot;
+    sp<RpcSession> mSession;
+    android::base::Result<void> connectToTrusty(const char* tipcDev);
+
+  public:
+    HwCryptoKey();
+
+    static std::shared_ptr<HwCryptoKey> Create(const char* tipcDev);
+
+    ndk::ScopedAStatus deriveCurrentDicePolicyBoundKey(
+            const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& derivationKey,
+            ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* aidl_return) override;
+
+    ndk::ScopedAStatus deriveDicePolicyBoundKey(
+            const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& derivationKey,
+            const ::std::vector<uint8_t>& dicePolicyForKeyVersion,
+            ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* aidl_return) override;
+    ndk::ScopedAStatus deriveKey(const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& parameters,
+                                 ndk_hwcrypto::IHwCryptoKey::DerivedKey* aidl_return) override;
+
+    ndk::ScopedAStatus getHwCryptoOperations(
+            std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return) override;
+
+    ndk::ScopedAStatus importClearKey(
+            const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial,
+            const ndk_hwcrypto::KeyPolicy& newKeyPolicy,
+            std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
+
+    ndk::ScopedAStatus getCurrentDicePolicy(std::vector<uint8_t>* aidl_return) override;
+
+    ndk::ScopedAStatus keyTokenImport(
+            const ndk_hwcrypto::types::OpaqueKeyToken& requestedKey,
+            const ::std::vector<uint8_t>& sealingDicePolicy,
+            std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
+
+    ndk::ScopedAStatus getKeyslotData(
+            ndk_hwcrypto::IHwCryptoKey::KeySlot slotId,
+            std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) override;
+};
+
+template <typename LHP, typename RHP>
+LHP convertKeyPolicy(const RHP& policyToConvert) {
+    LHP policy = LHP();
+    policy.usage = static_cast<decltype(policy.usage)>(policyToConvert.usage);
+    policy.keyLifetime = static_cast<decltype(policy.keyLifetime)>(policyToConvert.keyLifetime);
+    policy.keyType = static_cast<decltype(policy.keyType)>(policyToConvert.keyType);
+    policy.keyManagementKey = policyToConvert.keyManagementKey;
+    policy.keyPermissions.reserve(policyToConvert.keyPermissions.size());
+    for (auto permission : policyToConvert.keyPermissions) {
+        policy.keyPermissions.push_back(
+                std::move(static_cast<decltype(policy.keyPermissions)::value_type>(permission)));
+    }
+    return policy;
+}
+
+template <typename CPP, typename NDK,
+          std::map<std::weak_ptr<NDK>, wp<CPP>, std::owner_less<>>& mapping>
+sp<CPP> retrieveCppBinder(const std::shared_ptr<NDK>& ndkBinder) {
+    if (ndkBinder == nullptr) {
+        return nullptr;
+    }
+    if (mapping.find(ndkBinder) == mapping.end()) {
+        LOG(ERROR) << "couldn't find wrapped key";
+        return nullptr;
+    }
+    auto cppBbinder = mapping[ndkBinder];
+    return cppBbinder.promote();
+}
+
+template <typename CPP_BINDER, typename NDK_BINDER, typename NDK_BASE,
+          std::map<std::weak_ptr<NDK_BINDER>, wp<CPP_BINDER>, std::owner_less<>>& mapping>
+void insertBinderMapping(const sp<CPP_BINDER>& cppBinder, std::shared_ptr<NDK_BINDER>* ndkBinder) {
+    std::shared_ptr<NDK_BINDER> spNdkBinder = NDK_BASE::Create(cppBinder);
+    std::weak_ptr<NDK_BINDER> wptrNdkBinder = spNdkBinder;
+    wp<CPP_BINDER> wpCppBinder = cppBinder;
+    mapping.insert({wptrNdkBinder, wpCppBinder});
+    *ndkBinder = spNdkBinder;
+}
+
+}  // namespace hwcryptohalservice
+}  // namespace trusty
+}  // namespace android
diff --git a/security/see/hwcrypto/default/hwcryptolib.cpp b/security/see/hwcrypto/default/hwcryptolib.cpp
new file mode 100644
index 0000000..a7ecca1
--- /dev/null
+++ b/security/see/hwcrypto/default/hwcryptolib.cpp
@@ -0,0 +1,859 @@
+/*
+ * 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/android/hardware/security/see/hwcrypto/BnCryptoOperationContext.h>
+#include <aidl/android/hardware/security/see/hwcrypto/BnHwCryptoOperations.h>
+#include <aidl/android/hardware/security/see/hwcrypto/BnOpaqueKey.h>
+#include <aidl/android/hardware/security/see/hwcrypto/IOpaqueKey.h>
+#include <android-base/logging.h>
+#include <android/hardware/security/see/hwcrypto/BnHwCryptoKey.h>
+#include <binder/RpcTrusty.h>
+#include <trusty/tipc.h>
+#include <optional>
+#include <string>
+#include "hwcryptokeyimpl.h"
+
+using android::IBinder;
+using android::IInterface;
+using android::RpcSession;
+using android::RpcTrustyConnectWithSessionInitializer;
+using android::sp;
+using android::wp;
+using android::base::ErrnoError;
+using android::base::Error;
+using android::base::Result;
+using android::binder::Status;
+
+namespace android {
+namespace trusty {
+namespace hwcryptohalservice {
+
+#define HWCRYPTO_KEY_PORT "com.android.trusty.rust.hwcryptohal.V1"
+
+// Even though we get the cpp_hwcrypto::IOpaqueKey and cpp_hwcrypto::ICryptoOperationContext and
+// create the ndk_hwcrypto wrappers on this library we cannot cast them back when we need them
+// because they are received on the function calls as binder objects and there is no reliable
+// we to do this cast yet. Because of that we are creating maps to hold the wrapped objects
+// and translate them on function calls.
+// TODO: Add cleanup of both keyMapping and contextMapping once we have more test infrastructure in
+//       place.
+std::map<std::weak_ptr<ndk_hwcrypto::IOpaqueKey>, wp<cpp_hwcrypto::IOpaqueKey>, std::owner_less<>>
+        keyMapping;
+std::map<std::weak_ptr<ndk_hwcrypto::ICryptoOperationContext>,
+         wp<cpp_hwcrypto::ICryptoOperationContext>, std::owner_less<>>
+        contextMapping;
+
+static ndk::ScopedAStatus convertStatus(Status status) {
+    if (status.isOk()) {
+        return ndk::ScopedAStatus::ok();
+    } else {
+        auto exCode = status.exceptionCode();
+        if (exCode == Status::Exception::EX_SERVICE_SPECIFIC) {
+            return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                    status.serviceSpecificErrorCode(), status.exceptionMessage());
+        } else {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(exCode,
+                                                                    status.exceptionMessage());
+        }
+    }
+}
+
+static std::optional<cpp_hwcrypto::types::ExplicitKeyMaterial> convertExplicitKeyMaterial(
+        const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial) {
+    auto explicitKeyCpp = cpp_hwcrypto::types::ExplicitKeyMaterial();
+
+    if (keyMaterial.getTag() == ndk_hwcrypto::types::ExplicitKeyMaterial::aes) {
+        auto aesKey = keyMaterial.get<ndk_hwcrypto::types::ExplicitKeyMaterial::aes>();
+        auto aesKeyCpp = cpp_hwcrypto::types::AesKey();
+        if (aesKey.getTag() == ndk_hwcrypto::types::AesKey::aes128) {
+            aesKeyCpp.set<cpp_hwcrypto::types::AesKey::aes128>(
+                    aesKey.get<ndk_hwcrypto::types::AesKey::aes128>());
+            explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::aes>(aesKeyCpp);
+        } else if (aesKey.getTag() == ndk_hwcrypto::types::AesKey::aes256) {
+            aesKeyCpp.set<cpp_hwcrypto::types::AesKey::aes256>(
+                    aesKey.get<ndk_hwcrypto::types::AesKey::aes256>());
+            explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::aes>(aesKeyCpp);
+        } else {
+            LOG(ERROR) << "unknown AesKey type";
+            return std::nullopt;
+        }
+    } else if (keyMaterial.getTag() == ndk_hwcrypto::types::ExplicitKeyMaterial::hmac) {
+        auto hmacKey = keyMaterial.get<ndk_hwcrypto::types::ExplicitKeyMaterial::hmac>();
+        auto hmacKeyCpp = cpp_hwcrypto::types::HmacKey();
+        if (hmacKey.getTag() == ndk_hwcrypto::types::HmacKey::sha256) {
+            hmacKeyCpp.set<cpp_hwcrypto::types::HmacKey::sha256>(
+                    hmacKey.get<ndk_hwcrypto::types::HmacKey::sha256>());
+            explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::hmac>(hmacKeyCpp);
+        } else if (hmacKey.getTag() == ndk_hwcrypto::types::HmacKey::sha512) {
+            hmacKeyCpp.set<cpp_hwcrypto::types::HmacKey::sha512>(
+                    hmacKey.get<ndk_hwcrypto::types::HmacKey::sha512>());
+            explicitKeyCpp.set<cpp_hwcrypto::types::ExplicitKeyMaterial::hmac>(hmacKeyCpp);
+        } else {
+            LOG(ERROR) << "unknown HmacKey type";
+            return std::nullopt;
+        }
+    } else {
+        LOG(ERROR) << "unknown Key type";
+        return std::nullopt;
+    }
+    return explicitKeyCpp;
+}
+
+class HwCryptoOperationContextNdk : public ndk_hwcrypto::BnCryptoOperationContext {
+  private:
+    sp<cpp_hwcrypto::ICryptoOperationContext> mContext;
+    std::weak_ptr<ndk_hwcrypto::ICryptoOperationContext> self;
+
+  public:
+    HwCryptoOperationContextNdk(sp<cpp_hwcrypto::ICryptoOperationContext> operations)
+        : mContext(std::move(operations)) {}
+
+    ~HwCryptoOperationContextNdk() { contextMapping.erase(self); }
+
+    static std::shared_ptr<HwCryptoOperationContextNdk> Create(
+            sp<cpp_hwcrypto::ICryptoOperationContext> operations) {
+        if (operations == nullptr) {
+            return nullptr;
+        }
+        std::shared_ptr<HwCryptoOperationContextNdk> contextNdk =
+                ndk::SharedRefBase::make<HwCryptoOperationContextNdk>(std::move(operations));
+
+        if (!contextNdk) {
+            LOG(ERROR) << "failed to allocate HwCryptoOperationContext";
+            return nullptr;
+        }
+        contextNdk->self = contextNdk;
+        return contextNdk;
+    }
+};
+
+std::optional<cpp_hwcrypto::types::OperationData> convertOperationData(
+        const ndk_hwcrypto::types::OperationData& ndkOperationData) {
+    cpp_hwcrypto::types::OperationData cppOperationData = cpp_hwcrypto::types::OperationData();
+    cpp_hwcrypto::types::MemoryBufferReference cppMemBuffRef;
+    switch (ndkOperationData.getTag()) {
+        case ndk_hwcrypto::types::OperationData::dataBuffer:
+            cppOperationData.set<cpp_hwcrypto::types::OperationData::dataBuffer>(
+                    ndkOperationData.get<ndk_hwcrypto::types::OperationData::dataBuffer>());
+            break;
+        case ndk_hwcrypto::types::OperationData::memoryBufferReference:
+            cppMemBuffRef.startOffset =
+                    ndkOperationData
+                            .get<ndk_hwcrypto::types::OperationData::memoryBufferReference>()
+                            .startOffset;
+            cppMemBuffRef.sizeBytes =
+                    ndkOperationData
+                            .get<ndk_hwcrypto::types::OperationData::memoryBufferReference>()
+                            .sizeBytes;
+            cppOperationData.set<cpp_hwcrypto::types::OperationData::memoryBufferReference>(
+                    std::move(cppMemBuffRef));
+            break;
+        default:
+            LOG(ERROR) << "received unknown operation data type";
+            return std::nullopt;
+    }
+    return cppOperationData;
+}
+
+std::optional<cpp_hwcrypto::PatternParameters> convertPatternParameters(
+        const ndk_hwcrypto::PatternParameters& ndkpatternParameters) {
+    int64_t numberBlocksProcess = ndkpatternParameters.numberBlocksProcess;
+    int64_t numberBlocksCopy = ndkpatternParameters.numberBlocksCopy;
+    if ((numberBlocksProcess < 0) || (numberBlocksCopy < 0)) {
+        LOG(ERROR) << "received invalid pattern parameters";
+        return std::nullopt;
+    }
+    cpp_hwcrypto::PatternParameters patternParameters = cpp_hwcrypto::PatternParameters();
+    patternParameters.numberBlocksProcess = numberBlocksProcess;
+    patternParameters.numberBlocksCopy = numberBlocksCopy;
+    return patternParameters;
+}
+
+std::optional<cpp_hwcrypto::types::SymmetricOperation> convertSymmetricOperation(
+        const ndk_hwcrypto::types::SymmetricOperation& ndkSymmetricOperation) {
+    cpp_hwcrypto::types::SymmetricOperation symmetricOperation =
+            cpp_hwcrypto::types::SymmetricOperation();
+    switch (ndkSymmetricOperation) {
+        case ndk_hwcrypto::types::SymmetricOperation::ENCRYPT:
+            symmetricOperation = cpp_hwcrypto::types::SymmetricOperation::ENCRYPT;
+            break;
+        case ndk_hwcrypto::types::SymmetricOperation::DECRYPT:
+            symmetricOperation = cpp_hwcrypto::types::SymmetricOperation::DECRYPT;
+            break;
+        default:
+            LOG(ERROR) << "invalid symmetric operation type";
+            return std::nullopt;
+    }
+    return symmetricOperation;
+}
+
+cpp_hwcrypto::types::CipherModeParameters convertSymmetricModeParameters(
+        const ndk_hwcrypto::types::CipherModeParameters& ndkcipherModeParameters) {
+    cpp_hwcrypto::types::CipherModeParameters cipherModeParameters =
+            cpp_hwcrypto::types::CipherModeParameters();
+    cipherModeParameters.nonce = ndkcipherModeParameters.nonce;
+    return cipherModeParameters;
+}
+
+cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters convertSymmetricModeParameters(
+        const ndk_hwcrypto::types::AesGcmMode::AesGcmModeParameters& ndkgcmModeParameters) {
+    cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters gcmModeParameters =
+            cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters();
+    gcmModeParameters.nonce = ndkgcmModeParameters.nonce;
+    return gcmModeParameters;
+}
+
+std::optional<cpp_hwcrypto::MemoryBufferParameter> convertMemoryBufferParameters(
+        const ndk_hwcrypto::MemoryBufferParameter& ndkMemBuffParams) {
+    cpp_hwcrypto::MemoryBufferParameter memBuffParams = cpp_hwcrypto::MemoryBufferParameter();
+    memBuffParams.sizeBytes = ndkMemBuffParams.sizeBytes;
+    android::os::ParcelFileDescriptor pfd;
+    ndk::ScopedFileDescriptor ndkFd;
+    switch (ndkMemBuffParams.bufferHandle.getTag()) {
+        case ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::input:
+            ndkFd = ndkMemBuffParams.bufferHandle
+                            .get<ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::input>()
+                            .dup();
+            pfd.reset(binder::unique_fd(ndkFd.release()));
+            memBuffParams.bufferHandle
+                    .set<cpp_hwcrypto::MemoryBufferParameter::MemoryBuffer::input>(std::move(pfd));
+            break;
+        case ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::output:
+            ndkFd = ndkMemBuffParams.bufferHandle
+                            .get<ndk_hwcrypto::MemoryBufferParameter::MemoryBuffer::output>()
+                            .dup();
+            pfd.reset(binder::unique_fd(ndkFd.release()));
+            memBuffParams.bufferHandle
+                    .set<cpp_hwcrypto::MemoryBufferParameter::MemoryBuffer::output>(std::move(pfd));
+            break;
+        default:
+            LOG(ERROR) << "unknown bufferHandle type";
+            return std::nullopt;
+    }
+    return memBuffParams;
+}
+
+std::optional<cpp_hwcrypto::OperationParameters> convertOperationParameters(
+        const ndk_hwcrypto::OperationParameters& ndkOperationParameters) {
+    cpp_hwcrypto::OperationParameters operationParameters = cpp_hwcrypto::OperationParameters();
+    sp<cpp_hwcrypto::IOpaqueKey> opaqueKey;
+    cpp_hwcrypto::types::HmacOperationParameters hmacParameters =
+            cpp_hwcrypto::types::HmacOperationParameters();
+    std::optional<cpp_hwcrypto::types::SymmetricOperation> cppSymmetricOperation;
+    cpp_hwcrypto::types::CipherModeParameters cipherModeParameters;
+    cpp_hwcrypto::types::AesCipherMode cppAesCipherMode = cpp_hwcrypto::types::AesCipherMode();
+    cpp_hwcrypto::types::SymmetricOperationParameters cppSymmetricOperationParameters =
+            cpp_hwcrypto::types::SymmetricOperationParameters();
+    cpp_hwcrypto::types::SymmetricAuthOperationParameters cppSymmetricAuthOperationParameters =
+            cpp_hwcrypto::types::SymmetricAuthOperationParameters();
+    cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters cppAesGcmModeParameters =
+            cpp_hwcrypto::types::AesGcmMode::AesGcmModeParameters();
+    cpp_hwcrypto::types::AesGcmMode cppAesGcmMode = cpp_hwcrypto::types::AesGcmMode();
+    switch (ndkOperationParameters.getTag()) {
+        case ndk_hwcrypto::OperationParameters::symmetricAuthCrypto:
+            opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+                                          keyMapping>(
+                    ndkOperationParameters
+                            .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+                            .key);
+            if (!opaqueKey) {
+                LOG(ERROR) << "couldn't get aes key";
+                return std::nullopt;
+            }
+            cppSymmetricAuthOperationParameters.key = std::move(opaqueKey);
+            cppSymmetricOperation = convertSymmetricOperation(
+                    ndkOperationParameters
+                            .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+                            .direction);
+            if (!cppSymmetricOperation.has_value()) {
+                LOG(ERROR) << "couldn't get aes direction";
+                return std::nullopt;
+            }
+            cppSymmetricAuthOperationParameters.direction =
+                    std::move(cppSymmetricOperation.value());
+            switch (ndkOperationParameters
+                            .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+                            .parameters.getTag()) {
+                case ndk_hwcrypto::types::SymmetricAuthCryptoParameters::aes:
+                    switch (ndkOperationParameters
+                                    .get<ndk_hwcrypto::OperationParameters::symmetricAuthCrypto>()
+                                    .parameters
+                                    .get<ndk_hwcrypto::types::SymmetricAuthCryptoParameters::aes>()
+                                    .getTag()) {
+                        case ndk_hwcrypto::types::AesGcmMode::gcmTag16:
+                            cppAesGcmModeParameters = convertSymmetricModeParameters(
+                                    ndkOperationParameters
+                                            .get<ndk_hwcrypto::OperationParameters::
+                                                         symmetricAuthCrypto>()
+                                            .parameters
+                                            .get<ndk_hwcrypto::types::
+                                                         SymmetricAuthCryptoParameters::aes>()
+                                            .get<ndk_hwcrypto::types::AesGcmMode::gcmTag16>());
+                            cppAesGcmMode.set<cpp_hwcrypto::types::AesGcmMode::gcmTag16>(
+                                    std::move(cppAesGcmModeParameters));
+                            cppSymmetricAuthOperationParameters.parameters
+                                    .set<cpp_hwcrypto::types::SymmetricAuthCryptoParameters::aes>(
+                                            std::move(cppAesGcmMode));
+                            break;
+                        default:
+                            LOG(ERROR) << "received invalid aes gcm parameters";
+                            return std::nullopt;
+                    }
+                    break;
+                default:
+                    LOG(ERROR) << "received invalid symmetric auth crypto parameters";
+                    return std::nullopt;
+            }
+            operationParameters.set<cpp_hwcrypto::OperationParameters::symmetricAuthCrypto>(
+                    std::move(cppSymmetricAuthOperationParameters));
+            break;
+        case ndk_hwcrypto::OperationParameters::symmetricCrypto:
+            opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+                                          keyMapping>(
+                    ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+                            .key);
+            if (!opaqueKey) {
+                LOG(ERROR) << "couldn't get aes key";
+                return std::nullopt;
+            }
+            cppSymmetricOperationParameters.key = std::move(opaqueKey);
+            cppSymmetricOperation = convertSymmetricOperation(
+                    ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+                            .direction);
+            if (!cppSymmetricOperation.has_value()) {
+                LOG(ERROR) << "couldn't get aes direction";
+                return std::nullopt;
+            }
+            cppSymmetricOperationParameters.direction = std::move(cppSymmetricOperation.value());
+            switch (ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+                            .parameters.getTag()) {
+                case ndk_hwcrypto::types::SymmetricCryptoParameters::aes:
+                    switch (ndkOperationParameters
+                                    .get<ndk_hwcrypto::OperationParameters::symmetricCrypto>()
+                                    .parameters
+                                    .get<ndk_hwcrypto::types::SymmetricCryptoParameters::aes>()
+                                    .getTag()) {
+                        case ndk_hwcrypto::types::AesCipherMode::cbc:
+                            cipherModeParameters = convertSymmetricModeParameters(
+                                    ndkOperationParameters
+                                            .get<ndk_hwcrypto::OperationParameters::
+                                                         symmetricCrypto>()
+                                            .parameters
+                                            .get<ndk_hwcrypto::types::SymmetricCryptoParameters::
+                                                         aes>()
+                                            .get<ndk_hwcrypto::types::AesCipherMode::cbc>());
+                            cppAesCipherMode.set<cpp_hwcrypto::types::AesCipherMode::cbc>(
+                                    std::move(cipherModeParameters));
+                            cppSymmetricOperationParameters.parameters
+                                    .set<cpp_hwcrypto::types::SymmetricCryptoParameters::aes>(
+                                            std::move(cppAesCipherMode));
+                            break;
+                        case ndk_hwcrypto::types::AesCipherMode::ctr:
+                            cipherModeParameters = convertSymmetricModeParameters(
+                                    ndkOperationParameters
+                                            .get<ndk_hwcrypto::OperationParameters::
+                                                         symmetricCrypto>()
+                                            .parameters
+                                            .get<ndk_hwcrypto::types::SymmetricCryptoParameters::
+                                                         aes>()
+                                            .get<ndk_hwcrypto::types::AesCipherMode::ctr>());
+                            cppAesCipherMode.set<cpp_hwcrypto::types::AesCipherMode::ctr>(
+                                    std::move(cipherModeParameters));
+                            cppSymmetricOperationParameters.parameters
+                                    .set<cpp_hwcrypto::types::SymmetricCryptoParameters::aes>(
+                                            std::move(cppAesCipherMode));
+                            break;
+                        default:
+                            LOG(ERROR) << "received invalid aes parameters";
+                            return std::nullopt;
+                    }
+                    break;
+                default:
+                    LOG(ERROR) << "received invalid symmetric crypto parameters";
+                    return std::nullopt;
+            }
+            operationParameters.set<cpp_hwcrypto::OperationParameters::symmetricCrypto>(
+                    std::move(cppSymmetricOperationParameters));
+            break;
+        case ndk_hwcrypto::OperationParameters::hmac:
+            opaqueKey = retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey,
+                                          keyMapping>(
+                    ndkOperationParameters.get<ndk_hwcrypto::OperationParameters::hmac>().key);
+            if (!opaqueKey) {
+                LOG(ERROR) << "couldn't get hmac key";
+                return std::nullopt;
+            }
+            hmacParameters.key = opaqueKey;
+            operationParameters.set<cpp_hwcrypto::OperationParameters::hmac>(
+                    std::move(hmacParameters));
+            break;
+        default:
+            LOG(ERROR) << "received invalid operation parameters";
+            return std::nullopt;
+    }
+    return operationParameters;
+}
+
+class HwCryptoOperationsNdk : public ndk_hwcrypto::BnHwCryptoOperations {
+  private:
+    sp<cpp_hwcrypto::IHwCryptoOperations> mHwCryptoOperations;
+
+  public:
+    HwCryptoOperationsNdk(sp<cpp_hwcrypto::IHwCryptoOperations> operations)
+        : mHwCryptoOperations(std::move(operations)) {}
+
+    static std::shared_ptr<HwCryptoOperationsNdk> Create(
+            sp<cpp_hwcrypto::IHwCryptoOperations> operations) {
+        if (operations == nullptr) {
+            return nullptr;
+        }
+        std::shared_ptr<HwCryptoOperationsNdk> operationsNdk =
+                ndk::SharedRefBase::make<HwCryptoOperationsNdk>(std::move(operations));
+
+        if (!operationsNdk) {
+            LOG(ERROR) << "failed to allocate HwCryptoOperations";
+            return nullptr;
+        }
+        return operationsNdk;
+    }
+
+    ndk::ScopedAStatus processCommandList(
+            std::vector<ndk_hwcrypto::CryptoOperationSet>* operationSets,
+            std::vector<ndk_hwcrypto::CryptoOperationResult>* aidl_return) {
+        Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+        if (operationSets == nullptr) {
+            LOG(ERROR) << "received a null operation set";
+            return convertStatus(status);
+        }
+        if (aidl_return == nullptr) {
+            LOG(ERROR) << "received a null CryptoOperationResult set";
+            return convertStatus(status);
+        }
+        std::vector<cpp_hwcrypto::CryptoOperationResult> binderResult;
+        std::vector<cpp_hwcrypto::CryptoOperationSet> cppOperationSets;
+        for (ndk_hwcrypto::CryptoOperationSet& operationSet : *operationSets) {
+            cpp_hwcrypto::CryptoOperationSet cppSingleOperation =
+                    cpp_hwcrypto::CryptoOperationSet();
+            cppSingleOperation.context =
+                    retrieveCppBinder<cpp_hwcrypto::ICryptoOperationContext,
+                                      ndk_hwcrypto::ICryptoOperationContext, contextMapping>(
+                            operationSet.context);
+            for (ndk_hwcrypto::CryptoOperation& operation : operationSet.operations) {
+                cpp_hwcrypto::CryptoOperation cppOperation;
+                cpp_hwcrypto::types::Void voidObj;
+                std::optional<cpp_hwcrypto::types::OperationData> cppOperationData;
+                std::optional<cpp_hwcrypto::PatternParameters> cppPatternParameters;
+                std::optional<cpp_hwcrypto::OperationParameters> cppOperationParameters;
+                std::optional<cpp_hwcrypto::MemoryBufferParameter> cppMemBuffParams;
+                switch (operation.getTag()) {
+                    case ndk_hwcrypto::CryptoOperation::setMemoryBuffer:
+                        cppMemBuffParams = convertMemoryBufferParameters(
+                                operation.get<ndk_hwcrypto::CryptoOperation::setMemoryBuffer>());
+                        if (cppMemBuffParams.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::setMemoryBuffer>(
+                                    std::move(cppMemBuffParams.value()));
+                        } else {
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::setOperationParameters:
+                        cppOperationParameters = convertOperationParameters(
+                                operation.get<
+                                        ndk_hwcrypto::CryptoOperation::setOperationParameters>());
+                        if (cppOperationParameters.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::setOperationParameters>(
+                                    std::move(cppOperationParameters.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert operation parameters";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::setPattern:
+                        cppPatternParameters = convertPatternParameters(
+                                operation.get<ndk_hwcrypto::CryptoOperation::setPattern>());
+                        if (cppPatternParameters.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::setPattern>(
+                                    std::move(cppPatternParameters.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert pattern parameters";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::copyData:
+                        cppOperationData = convertOperationData(
+                                operation.get<ndk_hwcrypto::CryptoOperation::copyData>());
+                        if (cppOperationData.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::copyData>(
+                                    std::move(cppOperationData.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert CryptoOperation::copyData";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::aadInput:
+                        cppOperationData = convertOperationData(
+                                operation.get<ndk_hwcrypto::CryptoOperation::aadInput>());
+                        if (cppOperationData.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::aadInput>(
+                                    std::move(cppOperationData.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert CryptoOperation::aadInput";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::dataInput:
+                        cppOperationData = convertOperationData(
+                                operation.get<ndk_hwcrypto::CryptoOperation::dataInput>());
+                        if (cppOperationData.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::dataInput>(
+                                    std::move(cppOperationData.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert CryptoOperation::dataInput";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::dataOutput:
+                        cppOperationData = convertOperationData(
+                                operation.get<ndk_hwcrypto::CryptoOperation::dataOutput>());
+                        if (cppOperationData.has_value()) {
+                            cppOperation.set<cpp_hwcrypto::CryptoOperation::dataOutput>(
+                                    std::move(cppOperationData.value()));
+                        } else {
+                            LOG(ERROR) << "couldn't convert CryptoOperation::dataOutput";
+                            return convertStatus(status);
+                        }
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::destroyContext:
+                        cppOperation.set<cpp_hwcrypto::CryptoOperation::destroyContext>(
+                                std::move(voidObj));
+                        break;
+                    case ndk_hwcrypto::CryptoOperation::finish:
+                        cppOperation.set<cpp_hwcrypto::CryptoOperation::finish>(std::move(voidObj));
+                        break;
+                    default:
+                        // This shouldn't happen
+                        LOG(ERROR) << "received unknown crypto operation";
+                        return convertStatus(status);
+                }
+                cppSingleOperation.operations.push_back(std::move(cppOperation));
+            }
+            cppOperationSets.push_back(std::move(cppSingleOperation));
+        }
+        status = mHwCryptoOperations->processCommandList(&cppOperationSets, &binderResult);
+        if (status.isOk()) {
+            *aidl_return = std::vector<ndk_hwcrypto::CryptoOperationResult>();
+            for (cpp_hwcrypto::CryptoOperationResult& result : binderResult) {
+                ndk_hwcrypto::CryptoOperationResult ndkResult =
+                        ndk_hwcrypto::CryptoOperationResult();
+                if (result.context != nullptr) {
+                    insertBinderMapping<cpp_hwcrypto::ICryptoOperationContext,
+                                        ndk_hwcrypto::ICryptoOperationContext,
+                                        HwCryptoOperationContextNdk, contextMapping>(
+                            result.context, &ndkResult.context);
+                } else {
+                    ndkResult.context = nullptr;
+                }
+                aidl_return->push_back(std::move(ndkResult));
+            }
+        } else {
+            // No reason to copy back the data output vectors if this failed
+            LOG(ERROR) << "couldn't process command list";
+            return convertStatus(status);
+        }
+        // We need to copy the vectors from the cpp operations back to the ndk one
+        if (cppOperationSets.size() != operationSets->size()) {
+            LOG(ERROR) << "ndk and cpp operation sets had a different number of elements";
+            return convertStatus(Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+        }
+        for (unsigned setIdx = 0; setIdx < cppOperationSets.size(); ++setIdx) {
+            if (cppOperationSets[setIdx].operations.size() !=
+                (*operationSets)[setIdx].operations.size()) {
+                LOG(ERROR) << "ndk and cpp operations on set " << setIdx
+                           << " had a different number of elements";
+                return convertStatus(Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+            }
+            for (unsigned operationIdx = 0;
+                 operationIdx < cppOperationSets[setIdx].operations.size(); ++operationIdx) {
+                if (cppOperationSets[setIdx].operations[operationIdx].getTag() ==
+                    cpp_hwcrypto::CryptoOperation::dataOutput) {
+                    if ((*operationSets)[setIdx].operations[operationIdx].getTag() !=
+                        ndk_hwcrypto::CryptoOperation::dataOutput) {
+                        LOG(ERROR)
+                                << "ndk and cpp operations on set " << setIdx << " and operation "
+                                << operationIdx << " had a different operation type";
+                        return convertStatus(
+                                Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+                    }
+                    if (cppOperationSets[setIdx]
+                                .operations[operationIdx]
+                                .get<cpp_hwcrypto::CryptoOperation::dataOutput>()
+                                .getTag() == cpp_hwcrypto::types::OperationData::dataBuffer) {
+                        // This is the only case on which we need to move the data backto the
+                        // original array
+                        if ((*operationSets)[setIdx]
+                                    .operations[operationIdx]
+                                    .get<ndk_hwcrypto::CryptoOperation::dataOutput>()
+                                    .getTag() != ndk_hwcrypto::types::OperationData::dataBuffer) {
+                            LOG(ERROR) << "ndk and cpp operations on set " << setIdx
+                                       << " and operation " << operationIdx
+                                       << " had a different operation data output type";
+                            return convertStatus(
+                                    Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT));
+                        }
+                        (*operationSets)[setIdx]
+                                .operations[operationIdx]
+                                .get<ndk_hwcrypto::CryptoOperation::dataOutput>()
+                                .set<ndk_hwcrypto::types::OperationData::dataBuffer>(
+                                        cppOperationSets[setIdx]
+                                                .operations[operationIdx]
+                                                .get<cpp_hwcrypto::CryptoOperation::dataOutput>()
+                                                .get<cpp_hwcrypto::types::OperationData::
+                                                             dataBuffer>());
+                    }
+                }
+            }
+        }
+        return convertStatus(status);
+    }
+};
+
+class OpaqueKeyNdk : public ndk_hwcrypto::BnOpaqueKey {
+  private:
+    sp<cpp_hwcrypto::IOpaqueKey> mOpaqueKey;
+    std::weak_ptr<ndk_hwcrypto::IOpaqueKey> self;
+
+  public:
+    OpaqueKeyNdk(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) : mOpaqueKey(std::move(opaqueKey)) {}
+
+    ~OpaqueKeyNdk() { keyMapping.erase(self); }
+
+    static std::shared_ptr<OpaqueKeyNdk> Create(sp<cpp_hwcrypto::IOpaqueKey> opaqueKey) {
+        if (opaqueKey == nullptr) {
+            return nullptr;
+        }
+        std::shared_ptr<OpaqueKeyNdk> opaqueKeyNdk =
+                ndk::SharedRefBase::make<OpaqueKeyNdk>(std::move(opaqueKey));
+
+        if (!opaqueKeyNdk) {
+            LOG(ERROR) << "failed to allocate HwCryptoKey";
+            return nullptr;
+        }
+        opaqueKeyNdk->self = opaqueKeyNdk;
+        return opaqueKeyNdk;
+    }
+
+    ndk::ScopedAStatus exportWrappedKey(
+            const std::shared_ptr<ndk_hwcrypto::IOpaqueKey>& wrappingKey,
+            ::std::vector<uint8_t>* aidl_return) {
+        Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+        auto wrappingKeyNdk =
+                retrieveCppBinder<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey, keyMapping>(
+                        wrappingKey);
+        if (wrappingKeyNdk == nullptr) {
+            LOG(ERROR) << "couldn't get wrapped key";
+            return convertStatus(status);
+        }
+        status = mOpaqueKey->exportWrappedKey(wrappingKeyNdk, aidl_return);
+        return convertStatus(status);
+    }
+
+    ndk::ScopedAStatus getKeyPolicy(ndk_hwcrypto::KeyPolicy* aidl_return) {
+        Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+        if (aidl_return == nullptr) {
+            LOG(ERROR) << "return value passed to getKeyPolicy is nullptr";
+            return convertStatus(status);
+        }
+        cpp_hwcrypto::KeyPolicy cppPolicy = cpp_hwcrypto::KeyPolicy();
+
+        status = mOpaqueKey->getKeyPolicy(&cppPolicy);
+        if (status.isOk()) {
+            auto ndkPolicy =
+                    convertKeyPolicy<ndk_hwcrypto::KeyPolicy, cpp_hwcrypto::KeyPolicy>(cppPolicy);
+            *aidl_return = std::move(ndkPolicy);
+        }
+        return convertStatus(status);
+    }
+
+    ndk::ScopedAStatus getPublicKey(::std::vector<uint8_t>* aidl_return) {
+        auto status = mOpaqueKey->getPublicKey(aidl_return);
+        return convertStatus(status);
+    }
+
+    ndk::ScopedAStatus getShareableToken(const ::std::vector<uint8_t>& sealingDicePolicy,
+                                         ndk_hwcrypto::types::OpaqueKeyToken* aidl_return) {
+        Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+        if (aidl_return == nullptr) {
+            LOG(ERROR) << "return value passed to getShareableToken is nullptr";
+            return convertStatus(status);
+        }
+        cpp_hwcrypto::types::OpaqueKeyToken binder_return;
+        status = mOpaqueKey->getShareableToken(sealingDicePolicy, &binder_return);
+        if (status.isOk()) {
+            aidl_return->keyToken = std::move(binder_return.keyToken);
+        }
+        return convertStatus(status);
+    }
+
+    ndk::ScopedAStatus setProtectionId(
+            const ndk_hwcrypto::types::ProtectionId /*protectionId*/,
+            const ::std::vector<ndk_hwcrypto::types::OperationType>& /*allowedOperations*/) {
+        return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+                "android is not authorized to call setProtectionId");
+    }
+};
+
+Result<void> HwCryptoKey::connectToTrusty(const char* tipcDev) {
+    assert(!mSession);
+    auto session_initializer = [](sp<RpcSession>& session) {
+        session->setFileDescriptorTransportMode(RpcSession::FileDescriptorTransportMode::TRUSTY);
+    };
+    mSession =
+            RpcTrustyConnectWithSessionInitializer(tipcDev, HWCRYPTO_KEY_PORT, session_initializer);
+    if (!mSession) {
+        return ErrnoError() << "failed to connect to hwcrypto";
+    }
+    mRoot = mSession->getRootObject();
+    mHwCryptoServer = cpp_hwcrypto::IHwCryptoKey::asInterface(mRoot);
+    return {};
+}
+
+HwCryptoKey::HwCryptoKey() {}
+
+std::shared_ptr<HwCryptoKey> HwCryptoKey::Create(const char* tipcDev) {
+    std::shared_ptr<HwCryptoKey> hwCrypto = ndk::SharedRefBase::make<HwCryptoKey>();
+
+    if (!hwCrypto) {
+        LOG(ERROR) << "failed to allocate HwCryptoKey";
+        return nullptr;
+    }
+
+    auto ret = hwCrypto->connectToTrusty(tipcDev);
+    if (!ret.ok()) {
+        LOG(ERROR) << "failed to connect HwCryptoKey to Trusty: " << ret.error();
+        return nullptr;
+    }
+
+    return hwCrypto;
+}
+
+ndk::ScopedAStatus HwCryptoKey::deriveCurrentDicePolicyBoundKey(
+        const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& /*derivationKey*/,
+        ndk_hwcrypto::IHwCryptoKey::DiceCurrentBoundKeyResult* /*aidl_return*/) {
+    return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+            "android is not authorized to call deriveCurrentDicePolicyBoundKey");
+}
+
+ndk::ScopedAStatus HwCryptoKey::deriveDicePolicyBoundKey(
+        const ndk_hwcrypto::IHwCryptoKey::DiceBoundDerivationKey& /*derivationKey*/,
+        const ::std::vector<uint8_t>& /*dicePolicyForKeyVersion*/,
+        ndk_hwcrypto::IHwCryptoKey::DiceBoundKeyResult* /*aidl_return*/) {
+    return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+            "android is not authorized to call deriveDicePolicyBoundKey");
+}
+
+ndk::ScopedAStatus HwCryptoKey::deriveKey(
+        const ndk_hwcrypto::IHwCryptoKey::DerivedKeyParameters& /*parameters*/,
+        ndk_hwcrypto::IHwCryptoKey::DerivedKey* /*aidl_return*/) {
+    return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED,
+            "android is not authorized to call deriveKey");
+}
+
+ndk::ScopedAStatus HwCryptoKey::getHwCryptoOperations(
+        std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations>* aidl_return) {
+    Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+    if (aidl_return == nullptr) {
+        LOG(ERROR) << "return value passed to getHwCryptoOperations is nullptr";
+        return convertStatus(status);
+    }
+    sp<cpp_hwcrypto::IHwCryptoOperations> binder_return;
+    status = mHwCryptoServer->getHwCryptoOperations(&binder_return);
+    if (status.isOk()) {
+        std::shared_ptr<ndk_hwcrypto::IHwCryptoOperations> operations =
+                HwCryptoOperationsNdk::Create(binder_return);
+        *aidl_return = operations;
+    }
+    return convertStatus(status);
+}
+
+ndk::ScopedAStatus HwCryptoKey::importClearKey(
+        const ndk_hwcrypto::types::ExplicitKeyMaterial& keyMaterial,
+        const ndk_hwcrypto::KeyPolicy& newKeyPolicy,
+        std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) {
+    sp<cpp_hwcrypto::IOpaqueKey> binder_return = nullptr;
+    Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+    if (aidl_return == nullptr) {
+        LOG(ERROR) << "return value passed to importClearKey is nullptr";
+        return convertStatus(status);
+    }
+    auto cppKeyPolicy =
+            convertKeyPolicy<cpp_hwcrypto::KeyPolicy, ndk_hwcrypto::KeyPolicy>(newKeyPolicy);
+    auto explicitKeyCpp = convertExplicitKeyMaterial(keyMaterial);
+    if (!explicitKeyCpp.has_value()) {
+        LOG(ERROR) << "couldn't convert key material";
+        return convertStatus(status);
+    }
+    status = mHwCryptoServer->importClearKey(explicitKeyCpp.value(), cppKeyPolicy, &binder_return);
+    if (status.isOk()) {
+        if ((binder_return != nullptr)) {
+            insertBinderMapping<cpp_hwcrypto::IOpaqueKey, ndk_hwcrypto::IOpaqueKey, OpaqueKeyNdk,
+                                keyMapping>(binder_return, aidl_return);
+        } else {
+            *aidl_return = nullptr;
+        }
+    }
+    return convertStatus(status);
+}
+
+ndk::ScopedAStatus HwCryptoKey::getCurrentDicePolicy(std::vector<uint8_t>* aidl_return) {
+    auto status = mHwCryptoServer->getCurrentDicePolicy(aidl_return);
+    return convertStatus(status);
+}
+
+ndk::ScopedAStatus HwCryptoKey::keyTokenImport(
+        const ndk_hwcrypto::types::OpaqueKeyToken& requestedKey,
+        const ::std::vector<uint8_t>& sealingDicePolicy,
+        std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* aidl_return) {
+    Status status = Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
+    if (aidl_return == nullptr) {
+        LOG(ERROR) << "return value passed to keyTokenImport is nullptr";
+        return convertStatus(status);
+    }
+    sp<cpp_hwcrypto::IOpaqueKey> binder_return;
+    cpp_hwcrypto::types::OpaqueKeyToken requestedKeyCpp;
+    // trying first a shallow copy of the vector
+    requestedKeyCpp.keyToken = requestedKey.keyToken;
+    status = mHwCryptoServer->keyTokenImport(requestedKeyCpp, sealingDicePolicy, &binder_return);
+    if (status.isOk()) {
+        std::shared_ptr<ndk_hwcrypto::IOpaqueKey> opaqueKey = OpaqueKeyNdk::Create(binder_return);
+        *aidl_return = opaqueKey;
+    }
+    return convertStatus(status);
+}
+
+ndk::ScopedAStatus HwCryptoKey::getKeyslotData(
+        ndk_hwcrypto::IHwCryptoKey::KeySlot /*slotId*/,
+        std::shared_ptr<ndk_hwcrypto::IOpaqueKey>* /*aidl_return*/) {
+    return ndk::ScopedAStatus::fromServiceSpecificError(
+            ndk_hwcrypto::types::HalErrorCode::UNAUTHORIZED);
+}
+
+}  // namespace hwcryptohalservice
+}  // namespace trusty
+}  // namespace android
diff --git a/security/see/storage/default/Android.bp b/security/see/storage/default/Android.bp
new file mode 100644
index 0000000..7ea7739
--- /dev/null
+++ b/security/see/storage/default/Android.bp
@@ -0,0 +1,21 @@
+//
+// 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.
+
+prebuilt_etc {
+    name: "android.hardware.security.see.storage-service.trusty.xml",
+    sub_dir: "vintf",
+    vendor: true,
+    src: "android.hardware.security.see.storage-service.trusty.xml",
+}
diff --git a/security/see/storage/default/android.hardware.security.see.storage-service.trusty.xml b/security/see/storage/default/android.hardware.security.see.storage-service.trusty.xml
new file mode 100644
index 0000000..89f3839
--- /dev/null
+++ b/security/see/storage/default/android.hardware.security.see.storage-service.trusty.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl" exclusive-to="virtual-machine">
+        <name>android.hardware.security.see.storage</name>
+        <version>1</version>
+        <interface>
+            <name>ISecureStorage</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
index 5aecc54..d1acd6f 100644
--- a/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
+++ b/sensors/aidl/multihal/android.hardware.sensors-service-multihal.rc
@@ -1,3 +1,6 @@
+on boot
+    setprop vendor.sensors.dynamic_sensor_op_timeout_ms 1600
+
 service vendor.sensors-hal-multihal /vendor/bin/hw/android.hardware.sensors-service.multihal
     class hal
     user system
diff --git a/sensors/common/default/2.X/multihal/HalProxy.cpp b/sensors/common/default/2.X/multihal/HalProxy.cpp
index 305383e..c058122 100644
--- a/sensors/common/default/2.X/multihal/HalProxy.cpp
+++ b/sensors/common/default/2.X/multihal/HalProxy.cpp
@@ -587,7 +587,8 @@
                         static_cast<uint32_t>(EventQueueFlagBits::EVENTS_READ),
                         static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS),
                         kPendingWriteTimeoutNs, mEventQueueFlag)) {
-                ALOGE("Dropping %zu events after blockingWrite failed.", numToWrite);
+                ALOGE("Dropping %zu events after blockingWrite failed (is system_server running?).",
+                      numToWrite);
                 if (numWakeupEvents > 0) {
                     if (pendingWriteEvents.size() > eventQueueSize) {
                         decrementRefCountAndMaybeReleaseWakelock(
diff --git a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
index 29c47f5..b2a1304 100644
--- a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -21,6 +21,7 @@
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/wifi/BnWifi.h>
+#include <aidl/android/hardware/wifi/BnWifiStaIfaceEventCallback.h>
 #include <android/binder_manager.h>
 #include <android/binder_status.h>
 #include <binder/IServiceManager.h>
@@ -29,6 +30,7 @@
 
 #include "wifi_aidl_test_utils.h"
 
+using aidl::android::hardware::wifi::BnWifiStaIfaceEventCallback;
 using aidl::android::hardware::wifi::CachedScanData;
 using aidl::android::hardware::wifi::IWifi;
 using aidl::android::hardware::wifi::IWifiStaIface;
@@ -392,6 +394,66 @@
     }
 }
 
+class WifiStaIfaceEventCallback : public BnWifiStaIfaceEventCallback {
+  public:
+    WifiStaIfaceEventCallback() = default;
+
+    ::ndk::ScopedAStatus onBackgroundFullScanResult(
+            int32_t /* in_cmdId */, int32_t /* in_bucketsScanned */,
+            const ::aidl::android::hardware::wifi::StaScanResult& /* in_result */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onBackgroundScanFailure(int32_t /* in_cmdId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onBackgroundScanResults(
+            int32_t /* in_cmdId */,
+            const std::vector<::aidl::android::hardware::wifi::StaScanData>& /* in_scanDatas */)
+            override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onRssiThresholdBreached(int32_t /* in_cmdId */,
+                                                 const std::array<uint8_t, 6>& /* in_currBssid */,
+                                                 int32_t /* in_currRssi */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onTwtFailure(int32_t /*in_cmdId*/,
+                                      ::aidl::android::hardware::wifi::IWifiStaIfaceEventCallback::
+                                              TwtErrorCode /* in_error */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onTwtSessionCreate(
+            int32_t /* in_cmdId */,
+            const ::aidl::android::hardware::wifi::TwtSession& /* in_twtSession */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onTwtSessionUpdate(
+            int32_t /* in_cmdId */,
+            const ::aidl::android::hardware::wifi::TwtSession& /* in_twtSession */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onTwtSessionTeardown(
+            int32_t /* in_cmdId */, int32_t /* in_twtSessionId */,
+            ::aidl::android::hardware::wifi::IWifiStaIfaceEventCallback::
+                    TwtTeardownReasonCode /* in_reasonCode */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onTwtSessionStats(
+            int32_t /* in_cmdId */, int32_t /* in_twtSessionId */,
+            const ::aidl::android::hardware::wifi::TwtSessionStats& /* in_twtSessionStats */)
+            override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onTwtSessionSuspend(int32_t /* in_cmdId */,
+                                             int32_t /* in_twtSessionId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onTwtSessionResume(int32_t /* in_cmdId */,
+                                            int32_t /* in_twtSessionId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+};
+
 /**
  * TwtGetCapabilities
  */
@@ -433,6 +495,10 @@
     if (!twt_capabilities.isTwtRequesterSupported) {
         GTEST_SKIP() << "TWT is not supported";
     }
+    const std::shared_ptr<WifiStaIfaceEventCallback> callback =
+            ndk::SharedRefBase::make<WifiStaIfaceEventCallback>();
+    ASSERT_NE(callback, nullptr);
+    EXPECT_TRUE(wifi_sta_iface_->registerEventCallback(callback).isOk());
 
     TwtRequest twtRequest;
     twtRequest.mloLinkId = 0;
@@ -493,9 +559,13 @@
     twtRequest.minWakeIntervalUs = 10000;
     twtRequest.maxWakeIntervalUs = 100000;
 
+    auto status = wifi_sta_iface_->twtSessionUpdate(1, 10, twtRequest);
+    if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        GTEST_SKIP() << "TwtSessionUpdate is not supported";
+    }
     // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
     // as the error code.
-    EXPECT_TRUE(wifi_sta_iface_->twtSessionUpdate(1, 10, twtRequest).isOk());
+    EXPECT_TRUE(status.isOk());
 }
 
 /**
@@ -509,9 +579,13 @@
         GTEST_SKIP() << "TWT is not supported";
     }
 
+    auto status = wifi_sta_iface_->twtSessionSuspend(1, 10);
+    if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        GTEST_SKIP() << "TwtSessionSuspend is not supported";
+    }
     // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
     // as the error code.
-    EXPECT_TRUE(wifi_sta_iface_->twtSessionSuspend(1, 10).isOk());
+    EXPECT_TRUE(status.isOk());
 }
 
 /**
@@ -525,9 +599,13 @@
         GTEST_SKIP() << "TWT is not supported";
     }
 
+    auto status = wifi_sta_iface_->twtSessionResume(1, 10);
+    if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
+        GTEST_SKIP() << "TwtSessionResume is not supported";
+    }
     // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
     // as the error code.
-    EXPECT_TRUE(wifi_sta_iface_->twtSessionResume(1, 10).isOk());
+    EXPECT_TRUE(status.isOk());
 }
 
 /*