Merge "Add support and test for P210 format" into main am: aed2cbe113 am: 196504d359

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/3298491

Change-Id: I38286228ed10926336a6ed5782d47280970c144f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl
index 98ecee0..efc1ab2 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/Spatializer.aidl
@@ -42,6 +42,7 @@
   android.media.audio.common.HeadTracking.Mode headTrackingMode;
   android.media.audio.common.HeadTracking.ConnectionMode headTrackingConnectionMode;
   android.media.audio.common.HeadTracking.SensorData headTrackingSensorData;
+  android.media.audio.common.AudioChannelLayout[] spatializedChannelLayout;
   @VintfStability
   union Id {
     android.hardware.audio.effect.VendorExtension vendorExtensionTag;
diff --git a/audio/aidl/android/hardware/audio/effect/IFactory.aidl b/audio/aidl/android/hardware/audio/effect/IFactory.aidl
index b80e6ac..75d4d9e 100644
--- a/audio/aidl/android/hardware/audio/effect/IFactory.aidl
+++ b/audio/aidl/android/hardware/audio/effect/IFactory.aidl
@@ -74,13 +74,18 @@
 
     /**
      * Called by the framework to destroy the effect and free up all currently allocated resources.
-     * It is recommended to destroy the effect from the client side as soon as it is becomes unused.
+     * This method can be called at any time to destroy an effect instance. It is recommended to
+     * destroy the effect from the client side as soon as it becomes unused to free up resources.
      *
-     * The client must ensure effect instance is closed before destroy.
+     * The effect instance must handle any necessary cleanup and resource deallocation.
+     * If the effect is in the **PROCESSING** or **DRAINING** state, it must gracefully stop
+     * processing before destruction.
+     * The effect must ensure that all internal states are properly cleaned up to prevent resource
+     * leaks.
      *
      * @param handle The handle of effect instance to be destroyed.
      * @throws EX_ILLEGAL_ARGUMENT if the effect handle is not valid.
-     * @throws EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
+     * @throws EX_ILLEGAL_STATE if the effect instance can not be destroyed.
      */
     void destroyEffect(in IEffect handle);
 }
diff --git a/audio/aidl/android/hardware/audio/effect/Spatializer.aidl b/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
index 71e3ffe..e86452d 100644
--- a/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
@@ -86,4 +86,20 @@
      * Headtracking sensor data.
      */
     HeadTracking.SensorData headTrackingSensorData;
+
+    /**
+     * Spatialized channel layouts.
+     * A spatialized channel layout is one where each virtual speaker position is rendered
+     * at its corresponding virtual position, and is not downmixed with any other.
+     * For instance if a spatializer is only capable of distinct positions for 5.1, it would only
+     * return 5.1:
+     *  - the list wouldn't include 4.0, because that mask is "contained" within 5.1
+     *  - the list wouldn't include 7.1 (and so on) because the side and rear channels would be
+     *     downmixed together.
+     * Another example is a spatializer that can only spatialize up to 9 channels (not counting .1)
+     * and that supports 5.1.4, and 7.1.2, the list should include both.
+     * The values must also be part of the values reported by supportedChannelLayout.
+     * The array containing the values cannot be empty.
+     */
+    AudioChannelLayout[] spatializedChannelLayout;
 }
diff --git a/audio/aidl/android/hardware/audio/effect/State.aidl b/audio/aidl/android/hardware/audio/effect/State.aidl
index 1b698d7..ecd1bbe 100644
--- a/audio/aidl/android/hardware/audio/effect/State.aidl
+++ b/audio/aidl/android/hardware/audio/effect/State.aidl
@@ -24,6 +24,8 @@
  * it should transfer to IDLE state after handle the command successfully. Effect instance should
  * consume minimal resource and transfer to INIT state after it was close().
  *
+ * An effect instance can be destroyed from any state using `IFactory.destroyEffect()`.
+ *
  * Refer to the state machine diagram `state.gv` for a detailed state diagram.
  */
 @VintfStability
@@ -66,6 +68,7 @@
      * - Transitions to **INIT** on `IEffect.close()`.
      * - Remains in **IDLE** on `IEffect.getParameter()`, `IEffect.setParameter()`,
      *   `IEffect.getDescriptor()`, `IEffect.command(CommandId.RESET)`, and `IEffect.reopen()`.
+     * - Transitions to the final state on `IFactory.destroyEffect()`.
      */
     IDLE,
 
@@ -98,6 +101,7 @@
      *   stop processing with `CommandId.STOP` before closing.
      * - If `IEffect.close()` is called in this state, the effect instance should stop processing,
      *   transition to **IDLE**, and then close.
+     * - Transitions to the final state on `IFactory.destroyEffect()`.
      */
     PROCESSING,
 
@@ -123,6 +127,7 @@
      * - If not implemented, the effect instance may transition directly from **PROCESSING** to
      *   **IDLE** without this intermediate state.
      * - Any `CommandId.STOP` commands received during **DRAINING** should be ignored.
+     * - Transitions to the final state on `IFactory.destroyEffect()`.
      */
     DRAINING,
 }
diff --git a/audio/aidl/android/hardware/audio/effect/state.gv b/audio/aidl/android/hardware/audio/effect/state.gv
index 2a8194e..8590296 100644
--- a/audio/aidl/android/hardware/audio/effect/state.gv
+++ b/audio/aidl/android/hardware/audio/effect/state.gv
@@ -13,8 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// To render: "dot -Tpng state.gv -o state.png"
 
+// To render: "dot -Tpng state.gv -o state.png"
 digraph effect_state_machine {
 
     rankdir=LR; // Left to Right layout
@@ -29,40 +29,30 @@
     I [shape=point, fillcolor=black, width=0.2];
 
     // Final state node
-    F [shape=doublecircle, fillcolor=white, width=0.2];
+    F [shape=doublecircle, label="Destroyed"];
 
     // Define other nodes with colors
-    INIT [shape=ellipse, fillcolor=lightgreen];
-    IDLE [shape=ellipse, fillcolor=lightblue];
-    PROCESSING [shape=ellipse, fillcolor=lightyellow];
-    DRAINING [shape=ellipse, fillcolor=lightgrey];
+    INIT [shape=ellipse, fillcolor=lightgreen, label="INIT"];
+    IDLE [shape=ellipse, fillcolor=lightblue, label="IDLE"];
+    PROCESSING [shape=ellipse, fillcolor=lightyellow, label="PROCESSING"];
+    DRAINING [shape=ellipse, fillcolor=lightgrey, label="DRAINING"];
+    ANY_STATE [shape=ellipse, style=dashed, label="Any State", fillcolor=white];
 
-    // Transitions
+    // Main transitions
     I -> INIT [label="IFactory.createEffect", fontcolor="navy"];
-
-    INIT -> F [label="IFactory.destroyEffect"];
-
     INIT -> IDLE [label="IEffect.open()", fontcolor="lime"];
-
     IDLE -> PROCESSING [label="IEffect.command(START)"];
-
-    PROCESSING -> IDLE [label="IEffect.command(STOP)\nIEffect.command(RESET)"];
-
-    PROCESSING -> DRAINING [label="IEffect.command(STOP)", fontcolor="orange"];
-
-    DRAINING -> IDLE [label="Draining complete\n(IEffect.command(RESET)\nautomatic)"];
-
-    DRAINING -> PROCESSING [label="IEffect.command(START)\n(Interrupt draining)"];
-
+    PROCESSING -> IDLE [label="IEffect.command(STOP) (if draining not required)\nIEffect.command(RESET)"];
+    PROCESSING -> DRAINING [label="IEffect.command(STOP) (if draining required)", fontcolor="orange"];
+    DRAINING -> IDLE [label="IEffect.command(RESET)\nDraining complete (automatic transition)"];
+    DRAINING -> PROCESSING [label="IEffect.command(START) (Interrupt draining)"];
     IDLE -> INIT [label="IEffect.close()"];
 
-    // Self-loops
-    INIT -> INIT [label="IEffect.getState\nIEffect.getDescriptor"];
-
-    IDLE -> IDLE [label="IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.command(RESET)\nIEffect.reopen"];
-
-    PROCESSING -> PROCESSING [label="IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.reopen"];
-
-    DRAINING -> DRAINING [label="IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.reopen\nFading"];
-
+    // Global transitions
+    subgraph cluster_global_transitions {
+        label="Global Transitions (Any State)";
+        style=dashed;
+        ANY_STATE -> F [label="IFactory.destroyEffect", style="bold"];
+        ANY_STATE -> ANY_STATE [label="IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.getState\nIEffect.reopen", fontsize=10];
+    }
 }
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 73d7626..967d0b9 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -200,6 +200,47 @@
     test_suites: ["general-tests"],
 }
 
+cc_test {
+    name: "audio_alsa_utils_tests",
+    vendor_available: true,
+    defaults: [
+        "latest_android_media_audio_common_types_ndk_static",
+        "latest_android_hardware_audio_core_ndk_static",
+    ],
+    static_libs: [
+        "libalsautilsv2",
+        "libtinyalsav2",
+    ],
+    shared_libs: [
+        "libaudio_aidl_conversion_common_ndk",
+        "libaudioaidlcommon",
+        "libaudioutils",
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libfmq",
+        "libmedia_helper",
+        "libstagefright_foundation",
+        "libutils",
+    ],
+    header_libs: [
+        "libaudio_system_headers",
+        "libaudioaidl_headers",
+    ],
+    srcs: [
+        "alsa/Utils.cpp",
+        "tests/AlsaUtilsTest.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+        "-DBACKEND_NDK",
+    ],
+    test_suites: ["general-tests"],
+}
+
 cc_defaults {
     name: "aidlaudioeffectservice_defaults",
     defaults: [
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 7857f53..97f7286 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -22,7 +22,10 @@
 #include "effect-impl/EffectTypes.h"
 #include "include/effect-impl/EffectTypes.h"
 
+using aidl::android::hardware::audio::effect::CommandId;
+using aidl::android::hardware::audio::effect::Descriptor;
 using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::kDestroyAnyStateSupportedVersion;
 using aidl::android::hardware::audio::effect::kEventFlagDataMqNotEmpty;
 using aidl::android::hardware::audio::effect::kEventFlagNotEmpty;
 using aidl::android::hardware::audio::effect::kReopenSupportedVersion;
@@ -31,13 +34,45 @@
 using ::android::hardware::EventFlag;
 
 extern "C" binder_exception_t destroyEffect(const std::shared_ptr<IEffect>& instanceSp) {
-    State state;
-    ndk::ScopedAStatus status = instanceSp->getState(&state);
-    if (!status.isOk() || State::INIT != state) {
+    if (!instanceSp) {
+        LOG(ERROR) << __func__ << " nullptr";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+
+    Descriptor desc;
+    ndk::ScopedAStatus status = instanceSp->getDescriptor(&desc);
+    if (!status.isOk()) {
         LOG(ERROR) << __func__ << " instance " << instanceSp.get()
+                   << " failed to get descriptor, status: " << status.getDescription();
+        return EX_ILLEGAL_STATE;
+    }
+
+    State state;
+    status = instanceSp->getState(&state);
+    if (!status.isOk()) {
+        LOG(ERROR) << __func__ << " " << desc.common.name << " instance " << instanceSp.get()
                    << " in state: " << toString(state) << ", status: " << status.getDescription();
         return EX_ILLEGAL_STATE;
     }
+
+    int effectVersion = 0;
+    if (!instanceSp->getInterfaceVersion(&effectVersion).isOk()) {
+        LOG(WARNING) << __func__ << " " << desc.common.name << " failed to get interface version";
+    }
+
+    if (effectVersion < kDestroyAnyStateSupportedVersion) {
+        if (State::INIT != state) {
+            LOG(ERROR) << __func__ << " " << desc.common.name << " can not destroy instance "
+                       << instanceSp.get() << " in state: " << toString(state);
+            return EX_ILLEGAL_STATE;
+        }
+    } else {
+        instanceSp->command(CommandId::RESET);
+        instanceSp->close();
+    }
+
+    LOG(DEBUG) << __func__ << " " << desc.common.name << " instance " << instanceSp.get()
+               << " destroyed";
     return EX_NONE;
 }
 
diff --git a/audio/aidl/default/alsa/Utils.cpp b/audio/aidl/default/alsa/Utils.cpp
index 10374f2..77e4f65 100644
--- a/audio/aidl/default/alsa/Utils.cpp
+++ b/audio/aidl/default/alsa/Utils.cpp
@@ -39,6 +39,8 @@
 
 namespace aidl::android::hardware::audio::core::alsa {
 
+const float kUnityGainFloat = 1.0f;
+
 DeviceProxy::DeviceProxy() : mProfile(nullptr), mProxy(nullptr, alsaProxyDeleter) {}
 
 DeviceProxy::DeviceProxy(const DeviceProfile& deviceProfile)
@@ -140,7 +142,6 @@
 
 const AudioFormatDescToPcmFormatMap& getAudioFormatDescriptorToPcmFormatMap() {
     static const AudioFormatDescToPcmFormatMap formatDescToPcmFormatMap = {
-            {make_AudioFormatDescription(PcmType::UINT_8_BIT), PCM_FORMAT_S8},
             {make_AudioFormatDescription(PcmType::INT_16_BIT), PCM_FORMAT_S16_LE},
             {make_AudioFormatDescription(PcmType::FIXED_Q_8_24), PCM_FORMAT_S24_LE},
             {make_AudioFormatDescription(PcmType::INT_24_BIT), PCM_FORMAT_S24_3LE},
@@ -165,6 +166,92 @@
     return pcmFormatToFormatDescMap;
 }
 
+void applyGainToInt16Buffer(void* buffer, const size_t bufferSizeBytes, const float gain,
+                            int channelCount) {
+    const uint16_t unityGainQ4_12 = u4_12_from_float(kUnityGainFloat);
+    const uint16_t vl = u4_12_from_float(gain);
+    const uint32_t vrl = (vl << 16) | vl;
+    int numFrames = 0;
+    if (channelCount == 2) {
+        numFrames = bufferSizeBytes / sizeof(uint32_t);
+        if (numFrames == 0) {
+            return;
+        }
+        uint32_t* intBuffer = (uint32_t*)buffer;
+        if (CC_UNLIKELY(vl > unityGainQ4_12)) {
+            do {
+                int32_t l = mulRL(1, *intBuffer, vrl) >> 12;
+                int32_t r = mulRL(0, *intBuffer, vrl) >> 12;
+                l = clamp16(l);
+                r = clamp16(r);
+                *intBuffer++ = (r << 16) | (l & 0xFFFF);
+            } while (--numFrames);
+        } else {
+            do {
+                int32_t l = mulRL(1, *intBuffer, vrl) >> 12;
+                int32_t r = mulRL(0, *intBuffer, vrl) >> 12;
+                *intBuffer++ = (r << 16) | (l & 0xFFFF);
+            } while (--numFrames);
+        }
+    } else {
+        numFrames = bufferSizeBytes / sizeof(uint16_t);
+        if (numFrames == 0) {
+            return;
+        }
+        int16_t* intBuffer = (int16_t*)buffer;
+        if (CC_UNLIKELY(vl > unityGainQ4_12)) {
+            do {
+                int32_t mono = mul(*intBuffer, static_cast<int16_t>(vl)) >> 12;
+                *intBuffer++ = clamp16(mono);
+            } while (--numFrames);
+        } else {
+            do {
+                int32_t mono = mul(*intBuffer, static_cast<int16_t>(vl)) >> 12;
+                *intBuffer++ = static_cast<int16_t>(mono & 0xFFFF);
+            } while (--numFrames);
+        }
+    }
+}
+
+void applyGainToInt32Buffer(int32_t* typedBuffer, const size_t bufferSizeBytes, const float gain) {
+    int numSamples = bufferSizeBytes / sizeof(int32_t);
+    if (numSamples == 0) {
+        return;
+    }
+    if (CC_UNLIKELY(gain > kUnityGainFloat)) {
+        do {
+            float multiplied = (*typedBuffer) * gain;
+            if (multiplied > INT32_MAX) {
+                *typedBuffer++ = INT32_MAX;
+            } else if (multiplied < INT32_MIN) {
+                *typedBuffer++ = INT32_MIN;
+            } else {
+                *typedBuffer++ = multiplied;
+            }
+        } while (--numSamples);
+    } else {
+        do {
+            *typedBuffer++ = (*typedBuffer) * gain;
+        } while (--numSamples);
+    }
+}
+
+void applyGainToFloatBuffer(float* floatBuffer, const size_t bufferSizeBytes, const float gain) {
+    int numSamples = bufferSizeBytes / sizeof(float);
+    if (numSamples == 0) {
+        return;
+    }
+    if (CC_UNLIKELY(gain > kUnityGainFloat)) {
+        do {
+            *floatBuffer++ = std::clamp((*floatBuffer) * gain, -kUnityGainFloat, kUnityGainFloat);
+        } while (--numSamples);
+    } else {
+        do {
+            *floatBuffer++ = (*floatBuffer) * gain;
+        } while (--numSamples);
+    }
+}
+
 }  // namespace
 
 std::ostream& operator<<(std::ostream& os, const DeviceProfile& device) {
@@ -345,7 +432,7 @@
     return findValueOrDefault(getAudioFormatDescriptorToPcmFormatMap(), aidl, PCM_FORMAT_INVALID);
 }
 
-void applyGain(void* buffer, float gain, size_t bytesToTransfer, enum pcm_format pcmFormat,
+void applyGain(void* buffer, float gain, size_t bufferSizeBytes, enum pcm_format pcmFormat,
                int channelCount) {
     if (channelCount != 1 && channelCount != 2) {
         LOG(WARNING) << __func__ << ": unsupported channel count " << channelCount;
@@ -355,56 +442,37 @@
         LOG(WARNING) << __func__ << ": unsupported pcm format " << pcmFormat;
         return;
     }
-    const float unityGainFloat = 1.0f;
-    if (std::abs(gain - unityGainFloat) < 1e-6) {
+    if (std::abs(gain - kUnityGainFloat) < 1e-6) {
         return;
     }
-    int numFrames;
     switch (pcmFormat) {
-        case PCM_FORMAT_S16_LE: {
-            const uint16_t unityGainQ4_12 = u4_12_from_float(unityGainFloat);
-            const uint16_t vl = u4_12_from_float(gain);
-            const uint32_t vrl = (vl << 16) | vl;
-            if (channelCount == 2) {
-                numFrames = bytesToTransfer / sizeof(uint32_t);
-                uint32_t* intBuffer = (uint32_t*)buffer;
-                if (CC_UNLIKELY(vl > unityGainQ4_12)) {
-                    // volume is boosted, so we might need to clamp even though
-                    // we process only one track.
-                    do {
-                        int32_t l = mulRL(1, *intBuffer, vrl) >> 12;
-                        int32_t r = mulRL(0, *intBuffer, vrl) >> 12;
-                        l = clamp16(l);
-                        r = clamp16(r);
-                        *intBuffer++ = (r << 16) | (l & 0xFFFF);
-                    } while (--numFrames);
-                } else {
-                    do {
-                        int32_t l = mulRL(1, *intBuffer, vrl) >> 12;
-                        int32_t r = mulRL(0, *intBuffer, vrl) >> 12;
-                        *intBuffer++ = (r << 16) | (l & 0xFFFF);
-                    } while (--numFrames);
-                }
-            } else {
-                numFrames = bytesToTransfer / sizeof(uint16_t);
-                int16_t* intBuffer = (int16_t*)buffer;
-                if (CC_UNLIKELY(vl > unityGainQ4_12)) {
-                    // volume is boosted, so we might need to clamp even though
-                    // we process only one track.
-                    do {
-                        int32_t mono = mulRL(1, *intBuffer, vrl) >> 12;
-                        *intBuffer++ = clamp16(mono);
-                    } while (--numFrames);
-                } else {
-                    do {
-                        int32_t mono = mulRL(1, *intBuffer, vrl) >> 12;
-                        *intBuffer++ = static_cast<int16_t>(mono & 0xFFFF);
-                    } while (--numFrames);
-                }
+        case PCM_FORMAT_S16_LE:
+            applyGainToInt16Buffer(buffer, bufferSizeBytes, gain, channelCount);
+            break;
+        case PCM_FORMAT_FLOAT_LE: {
+            float* floatBuffer = (float*)buffer;
+            applyGainToFloatBuffer(floatBuffer, bufferSizeBytes, gain);
+        } break;
+        case PCM_FORMAT_S24_LE:
+            // PCM_FORMAT_S24_LE buffer is composed of signed fixed-point 32-bit Q8.23 data with
+            // min and max limits of the same bit representation as min and max limits of
+            // PCM_FORMAT_S32_LE buffer.
+        case PCM_FORMAT_S32_LE: {
+            int32_t* typedBuffer = (int32_t*)buffer;
+            applyGainToInt32Buffer(typedBuffer, bufferSizeBytes, gain);
+        } break;
+        case PCM_FORMAT_S24_3LE: {
+            int numSamples = bufferSizeBytes / (sizeof(uint8_t) * 3);
+            if (numSamples == 0) {
+                return;
             }
+            std::unique_ptr<int32_t[]> typedBuffer(new int32_t[numSamples]);
+            memcpy_to_i32_from_p24(typedBuffer.get(), (uint8_t*)buffer, numSamples);
+            applyGainToInt32Buffer(typedBuffer.get(), numSamples * sizeof(int32_t), gain);
+            memcpy_to_p24_from_i32((uint8_t*)buffer, typedBuffer.get(), numSamples);
         } break;
         default:
-            // TODO(336370745): Implement gain for other supported formats
+            LOG(FATAL) << __func__ << ": unsupported pcm format " << pcmFormat;
             break;
     }
 }
diff --git a/audio/aidl/default/config/audioPolicy/api/current.txt b/audio/aidl/default/config/audioPolicy/api/current.txt
index e57c108..1249a09 100644
--- a/audio/aidl/default/config/audioPolicy/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/api/current.txt
@@ -144,6 +144,7 @@
     enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_HEARING_AID;
     enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_IP;
     enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_LINE;
+    enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_MULTICHANNEL_GROUP;
     enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_PROXY;
     enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
     enum_constant public static final android.audio.policy.configuration.AudioDevice AUDIO_DEVICE_OUT_SPDIF;
@@ -222,6 +223,18 @@
     enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_FLAC;
     enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_HE_AAC_V1;
     enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_HE_AAC_V2;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_BASE_AAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_BASE_ENHANCED_AAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_BASE_ENHANCED_FLAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_BASE_ENHANCED_OPUS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_BASE_ENHANCED_PCM;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_BASE_FLAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_BASE_OPUS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_BASE_PCM;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_SIMPLE_AAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_SIMPLE_FLAC;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_SIMPLE_OPUS;
+    enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IAMF_SIMPLE_PCM;
     enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IEC60958;
     enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_IEC61937;
     enum_constant public static final android.audio.policy.configuration.AudioFormat AUDIO_FORMAT_LC3;
diff --git a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
index 108a6a3..8adac8c 100644
--- a/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/audio_policy_configuration.xsd
@@ -262,6 +262,7 @@
             <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_LINE"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER_SAFE"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_IP"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_MULTICHANNEL_GROUP"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_BUS"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_PROXY"/>
             <xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
@@ -416,6 +417,18 @@
             <xs:enumeration value="AUDIO_FORMAT_APTX_ADAPTIVE_R4"/>
             <xs:enumeration value="AUDIO_FORMAT_DTS_HD_MA"/>
             <xs:enumeration value="AUDIO_FORMAT_DTS_UHD_P2"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_SIMPLE_OPUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_SIMPLE_AAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_SIMPLE_PCM"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_SIMPLE_FLAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_BASE_OPUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_BASE_AAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_BASE_PCM"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_BASE_FLAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_BASE_ENHANCED_OPUS"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_BASE_ENHANCED_AAC"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_BASE_ENHANCED_PCM"/>
+            <xs:enumeration value="AUDIO_FORMAT_IAMF_BASE_ENHANCED_FLAC"/>
         </xs:restriction>
     </xs:simpleType>
     <xs:simpleType name="extendableAudioFormat">
diff --git a/audio/aidl/default/config/audioPolicy/engine/api/current.txt b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
index 017362f..41cfb44 100644
--- a/audio/aidl/default/config/audioPolicy/engine/api/current.txt
+++ b/audio/aidl/default/config/audioPolicy/engine/api/current.txt
@@ -266,6 +266,7 @@
     enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_EVENT;
     enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
     enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_SAFETY;
+    enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_SPEAKER_CLEANUP;
     enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_UNKNOWN;
     enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VEHICLE_STATUS;
     enum_constant public static final android.audio.policy.engine.configuration.UsageEnumType AUDIO_USAGE_VIRTUAL_SOURCE;
diff --git a/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
index c16e366..7d9b06e 100644
--- a/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
+++ b/audio/aidl/default/config/audioPolicy/engine/audio_policy_engine_configuration.xsd
@@ -375,6 +375,7 @@
             <xs:enumeration value="AUDIO_USAGE_SAFETY" />
             <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
             <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+            <xs:enumeration value="AUDIO_USAGE_SPEAKER_CLEANUP" />
         </xs:restriction>
     </xs:simpleType>
 
diff --git a/audio/aidl/default/tests/AlsaUtilsTest.cpp b/audio/aidl/default/tests/AlsaUtilsTest.cpp
new file mode 100644
index 0000000..226eea0
--- /dev/null
+++ b/audio/aidl/default/tests/AlsaUtilsTest.cpp
@@ -0,0 +1,253 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AlsaUtilsTest"
+
+#include <alsa/Utils.h>
+#include <android-base/macros.h>
+#include <audio_utils/primitives.h>
+#include <gtest/gtest.h>
+#include <log/log.h>
+
+extern "C" {
+#include <tinyalsa/pcm.h>
+}
+
+namespace alsa = ::aidl::android::hardware::audio::core::alsa;
+
+namespace {
+
+const static constexpr float kInt16tTolerance = 4;
+const static constexpr float kIntTolerance = 1;
+const static constexpr float kFloatTolerance = 1e-4;
+const static constexpr float kUnityGain = 1;
+const static constexpr int32_t kInt24Min = -(1 << 23);
+const static constexpr int32_t kInt24Max = (1 << 23) - 1;
+const static constexpr float kFloatMin = -1;
+const static constexpr float kFloatMax = 1;
+const static int32_t kQ8_23Min = 0x80000000;
+const static int32_t kQ8_23Max = 0x7FFFFFFF;
+const static std::vector<int16_t> kInt16Buffer = {10000,     100,   0,    INT16_MAX,
+                                                  INT16_MIN, -2500, 1000, -5800};
+const static std::vector<float> kFloatBuffer = {0.5, -0.6, kFloatMin, 0.01, kFloatMax, 0.0};
+const static std::vector<int32_t> kInt32Buffer = {100, 0, 8000, INT32_MAX, INT32_MIN, -300};
+const static std::vector<int32_t> kQ8_23Buffer = {
+        kQ8_23Min, kQ8_23Max, 0x00000000, 0x00000001, 0x00400000, static_cast<int32_t>(0xFFD33333)};
+const static std::vector<int32_t> kInt24Buffer = {200, 10, -100, 0, kInt24Min, kInt24Max};
+
+template <typename T>
+void* CopyToBuffer(int& bytesToTransfer, std::vector<T>& destBuffer,
+                   const std::vector<T>& srcBuffer) {
+    bytesToTransfer = srcBuffer.size() * sizeof(T);
+    destBuffer = srcBuffer;
+    return destBuffer.data();
+}
+
+template <typename T>
+void VerifyTypedBufferResults(const std::vector<T>& bufferWithGain, const std::vector<T>& srcBuffer,
+                              float gain, float tolerance) {
+    for (size_t i = 0; i < srcBuffer.size(); i++) {
+        EXPECT_NEAR(srcBuffer[i] * gain, static_cast<float>(bufferWithGain[i]), tolerance);
+    }
+}
+
+template <typename T>
+void VerifyTypedBufferResultsWithClamp(const std::vector<T>& bufferWithGain,
+                                       const std::vector<T>& srcBuffer, float gain, float tolerance,
+                                       T minValue, T maxValue) {
+    for (size_t i = 0; i < srcBuffer.size(); i++) {
+        float expectedResult = std::clamp(srcBuffer[i] * gain, static_cast<float>(minValue),
+                                          static_cast<float>(maxValue));
+        EXPECT_NEAR(expectedResult, static_cast<float>(bufferWithGain[i]), tolerance);
+    }
+}
+
+}  // namespace
+
+using ApplyGainTestParameters = std::tuple<pcm_format, int, float>;
+enum { INDEX_PCM_FORMAT, INDEX_CHANNEL_COUNT, INDEX_GAIN };
+
+class ApplyGainTest : public ::testing::TestWithParam<ApplyGainTestParameters> {
+  protected:
+    void SetUp() override;
+    void VerifyBufferResult(const pcm_format pcmFormat, const float gain);
+    void VerifyBufferResultWithClamp(const pcm_format pcmFormat, const float gain);
+
+    pcm_format mPcmFormat;
+    int mBufferSizeBytes;
+    void* mBuffer;
+
+  private:
+    std::vector<int16_t> mInt16BufferToConvert;
+    std::vector<float> mFloatBufferToConvert;
+    std::vector<int32_t> mInt32BufferToConvert;
+    std::vector<int32_t> mQ8_23BufferToConvert;
+    std::vector<int32_t> mInt24BufferToConvert;
+};
+
+void ApplyGainTest::SetUp() {
+    mPcmFormat = std::get<INDEX_PCM_FORMAT>(GetParam());
+    switch (mPcmFormat) {
+        case PCM_FORMAT_S16_LE:
+            mBuffer = CopyToBuffer(mBufferSizeBytes, mInt16BufferToConvert, kInt16Buffer);
+            break;
+        case PCM_FORMAT_FLOAT_LE:
+            mBuffer = CopyToBuffer(mBufferSizeBytes, mFloatBufferToConvert, kFloatBuffer);
+            break;
+        case PCM_FORMAT_S32_LE:
+            mBuffer = CopyToBuffer(mBufferSizeBytes, mInt32BufferToConvert, kInt32Buffer);
+            break;
+        case PCM_FORMAT_S24_LE:
+            mBuffer = CopyToBuffer(mBufferSizeBytes, mQ8_23BufferToConvert, kQ8_23Buffer);
+            break;
+        case PCM_FORMAT_S24_3LE: {
+            std::vector<int32_t> original32BitBuffer(kInt24Buffer.begin(), kInt24Buffer.end());
+            for (auto& val : original32BitBuffer) {
+                val <<= 8;
+            }
+            mInt24BufferToConvert = std::vector<int32_t>(kInt24Buffer.size());
+            mBufferSizeBytes = kInt24Buffer.size() * 3 * sizeof(uint8_t);
+            memcpy_to_p24_from_i32(reinterpret_cast<uint8_t*>(mInt24BufferToConvert.data()),
+                                   original32BitBuffer.data(), kInt24Buffer.size());
+            mBuffer = mInt24BufferToConvert.data();
+        } break;
+        default:
+            FAIL() << "Unsupported pcm format: " << mPcmFormat;
+            return;
+    }
+}
+
+void ApplyGainTest::VerifyBufferResult(const pcm_format pcmFormat, const float gain) {
+    switch (pcmFormat) {
+        case PCM_FORMAT_S16_LE:
+            VerifyTypedBufferResults(mInt16BufferToConvert, kInt16Buffer, gain, kInt16tTolerance);
+            break;
+        case PCM_FORMAT_FLOAT_LE:
+            VerifyTypedBufferResults(mFloatBufferToConvert, kFloatBuffer, gain, kFloatTolerance);
+            break;
+        case PCM_FORMAT_S32_LE:
+            VerifyTypedBufferResults(mInt32BufferToConvert, kInt32Buffer, gain, kIntTolerance);
+            break;
+        case PCM_FORMAT_S24_LE: {
+            for (size_t i = 0; i < kQ8_23Buffer.size(); i++) {
+                EXPECT_NEAR(float_from_q8_23(kQ8_23Buffer[i]) * gain,
+                            static_cast<float>(float_from_q8_23(mQ8_23BufferToConvert[i])),
+                            kFloatTolerance);
+            }
+        } break;
+        case PCM_FORMAT_S24_3LE: {
+            size_t bufferSize = kInt24Buffer.size();
+            std::vector<int32_t> result32BitBuffer(bufferSize);
+            memcpy_to_i32_from_p24(result32BitBuffer.data(),
+                                   reinterpret_cast<uint8_t*>(mInt24BufferToConvert.data()),
+                                   bufferSize);
+            for (size_t i = 0; i < bufferSize; i++) {
+                EXPECT_NEAR(kInt24Buffer[i] * gain, result32BitBuffer[i] >> 8, kIntTolerance);
+            }
+        } break;
+        default:
+            return;
+    }
+}
+
+void ApplyGainTest::VerifyBufferResultWithClamp(const pcm_format pcmFormat, const float gain) {
+    switch (pcmFormat) {
+        case PCM_FORMAT_S16_LE:
+            VerifyTypedBufferResultsWithClamp(mInt16BufferToConvert, kInt16Buffer, gain,
+                                              kInt16tTolerance, static_cast<int16_t>(INT16_MIN),
+                                              static_cast<int16_t>(INT16_MAX));
+            break;
+        case PCM_FORMAT_FLOAT_LE:
+            VerifyTypedBufferResultsWithClamp(mFloatBufferToConvert, kFloatBuffer, gain,
+                                              kFloatTolerance, kFloatMin, kFloatMax);
+            break;
+        case PCM_FORMAT_S32_LE:
+            VerifyTypedBufferResultsWithClamp(mInt32BufferToConvert, kInt32Buffer, gain,
+                                              kIntTolerance, INT32_MIN, INT32_MAX);
+            break;
+        case PCM_FORMAT_S24_LE: {
+            for (size_t i = 0; i < kQ8_23Buffer.size(); i++) {
+                float expectedResult =
+                        std::clamp(float_from_q8_23(kQ8_23Buffer[i]) * gain,
+                                   float_from_q8_23(kQ8_23Min), float_from_q8_23(kQ8_23Max));
+                EXPECT_NEAR(expectedResult,
+                            static_cast<float>(float_from_q8_23(mQ8_23BufferToConvert[i])),
+                            kFloatTolerance);
+            }
+        } break;
+        case PCM_FORMAT_S24_3LE: {
+            size_t bufferSize = kInt24Buffer.size();
+            std::vector<int32_t> result32BitBuffer(bufferSize);
+            memcpy_to_i32_from_p24(result32BitBuffer.data(),
+                                   reinterpret_cast<uint8_t*>(mInt24BufferToConvert.data()),
+                                   bufferSize);
+            for (size_t i = 0; i < bufferSize; i++) {
+                result32BitBuffer[i] >>= 8;
+            }
+            VerifyTypedBufferResultsWithClamp(result32BitBuffer, kInt24Buffer, gain, kIntTolerance,
+                                              kInt24Min, kInt24Max);
+        } break;
+        default:
+            return;
+    }
+}
+
+TEST_P(ApplyGainTest, ApplyGain) {
+    float gain = std::get<INDEX_GAIN>(GetParam());
+    int channelCount = std::get<INDEX_CHANNEL_COUNT>(GetParam());
+
+    alsa::applyGain(mBuffer, gain, mBufferSizeBytes, mPcmFormat, channelCount);
+
+    if (gain <= kUnityGain) {
+        VerifyBufferResult(mPcmFormat, gain);
+    } else {
+        VerifyBufferResultWithClamp(mPcmFormat, gain);
+    }
+}
+
+std::string GetApplyGainTestName(const testing::TestParamInfo<ApplyGainTestParameters>& info) {
+    std::string testNameStr;
+    switch (std::get<INDEX_PCM_FORMAT>(info.param)) {
+        case PCM_FORMAT_S16_LE:
+            testNameStr = "S16_LE";
+            break;
+        case PCM_FORMAT_FLOAT_LE:
+            testNameStr = "Float_LE";
+            break;
+        case PCM_FORMAT_S32_LE:
+            testNameStr = "S32_LE";
+            break;
+        case PCM_FORMAT_S24_LE:
+            testNameStr = "S24_LE";
+            break;
+        case PCM_FORMAT_S24_3LE:
+            testNameStr = "S24_3LE";
+            break;
+        default:
+            testNameStr = "UnsupportedPcmFormat";
+            break;
+    }
+    testNameStr += std::get<INDEX_CHANNEL_COUNT>(info.param) == 1 ? "_Mono_" : "_Stereo_";
+    testNameStr += std::get<INDEX_GAIN>(info.param) <= kUnityGain ? "WithoutClamp" : "WithClamp";
+    return testNameStr;
+}
+
+INSTANTIATE_TEST_SUITE_P(PerPcmFormat, ApplyGainTest,
+                         testing::Combine(testing::Values(PCM_FORMAT_S16_LE, PCM_FORMAT_FLOAT_LE,
+                                                          PCM_FORMAT_S32_LE, PCM_FORMAT_S24_LE,
+                                                          PCM_FORMAT_S24_3LE),
+                                          testing::Values(1, 2), testing::Values(0.6f, 1.5f)),
+                         GetApplyGainTestName);
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 5f0a608..14e70ef 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -31,6 +31,7 @@
     ],
     header_libs: [
         "libaudioaidl_headers",
+        "libaudioutils_headers",
         "libexpectedutils_headers",
     ],
     cflags: [
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index d23bdc9..5b78981 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -42,6 +42,7 @@
 using aidl::android::hardware::audio::effect::Flags;
 using aidl::android::hardware::audio::effect::IEffect;
 using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::kDestroyAnyStateSupportedVersion;
 using aidl::android::hardware::audio::effect::Parameter;
 using aidl::android::hardware::audio::effect::State;
 using aidl::android::media::audio::common::AudioDeviceDescription;
@@ -316,28 +317,39 @@
     ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
 }
 
-// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
+// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed before
+// `kDestroyAnyStateSupportedVersion`.
+// For any version after `kDestroyAnyStateSupportedVersion`, expect `destroy` to always success.
 TEST_P(AudioEffectTest, DestroyOpenEffects) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
     ASSERT_NO_FATAL_FAILURE(open(mEffect));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect, EX_ILLEGAL_STATE));
-
-    // cleanup
-    ASSERT_NO_FATAL_FAILURE(close(mEffect));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    if (mVersion < kDestroyAnyStateSupportedVersion) {
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect, EX_ILLEGAL_STATE));
+        // cleanup
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    } else {
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
 }
 
-// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed.
+// Expect EX_ILLEGAL_STATE if the effect instance is not in a proper state to be destroyed before
+// `kDestroyAnyStateSupportedVersion`.
+// For any version after `kDestroyAnyStateSupportedVersion`, expect `destroy` to always success.
 TEST_P(AudioEffectTest, DestroyProcessingEffects) {
     ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
     ASSERT_NO_FATAL_FAILURE(open(mEffect));
     ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::START));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect, EX_ILLEGAL_STATE));
 
-    // cleanup
-    ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
-    ASSERT_NO_FATAL_FAILURE(close(mEffect));
-    ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    if (mVersion < kDestroyAnyStateSupportedVersion) {
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect, EX_ILLEGAL_STATE));
+        // cleanup
+        ASSERT_NO_FATAL_FAILURE(command(mEffect, CommandId::STOP));
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    } else {
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
 }
 
 TEST_P(AudioEffectTest, NormalSequenceStates) {
diff --git a/automotive/TEST_MAPPING b/automotive/TEST_MAPPING
index 483a85f..2b2f6b0 100644
--- a/automotive/TEST_MAPPING
+++ b/automotive/TEST_MAPPING
@@ -64,7 +64,82 @@
       "name": "CarServiceTelemetryTest"
     },
     {
-      "name": "CarServiceUnitTest"
+      "name": "CarServiceCarUnitTest"
+    },
+    {
+      "name": "CarServiceWifiUnitTest"
+    },
+    {
+      "name": "CarServiceWatchdogUnitTest"
+    },
+    {
+      "name": "CarServiceVmsUnitTest"
+    },
+    {
+      "name": "CarServiceUtilUnitTest"
+    },
+    {
+      "name": "CarServiceUserUnitTest"
+    },
+    {
+      "name": "CarServiceTelemetryUnitTest"
+    },
+    {
+      "name": "CarServiceSystemUiUnitTest"
+    },
+    {
+      "name": "CarServiceSystemInterfaceUnitTest"
+    },
+    {
+      "name": "CarServiceStorageMonitoringUnitTest"
+    },
+    {
+      "name": "CarServiceStatsUnitTest"
+    },
+    {
+      "name": "CarServiceRemoteAccessUnitTest"
+    },
+    {
+      "name": "CarServicePropertyUnitTest"
+    },
+    {
+      "name": "CarServicePowerUnitTest"
+    },
+    {
+      "name": "CarServicePmUnitTest"
+    },
+    {
+      "name": "CarServiceOsUnitTest"
+    },
+    {
+      "name": "CarServiceOemUnitTest"
+    },
+    {
+      "name": "CarServiceOccupantConnectionUnitTest"
+    },
+    {
+      "name": "CarServiceHalUnitTest"
+    },
+    {
+      "name": "CarServiceGarageModeUnitTest"
+    },
+    {
+      "name": "CarServiceEvsUnitTest"
+    },
+    {
+      "name": "CarServiceClusterUnitTest"
+    },
+    {
+      "name": "CarServiceBluetoothUnitTest"
+    },
+    {
+      "name": "CarServiceAudioUnitTest"
+    },
+    {
+      "name": "CarServiceAmUnitTest"
+    },
+    {
+      "name": "CarServiceAdminUnitTest"
     },
     {
       "name": "CarServiceVmsTest"
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
similarity index 83%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
index a5eda52..2685f58 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioDeviceConfiguration {
+  android.hardware.automotive.audiocontrol.RoutingDeviceConfiguration routingConfig;
+  boolean useCoreAudioVolume;
+  boolean useHalDuckingSignals;
+  boolean useCarVolumeGroupMuting;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
similarity index 62%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
index a5eda52..0a3c677 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
@@ -31,9 +31,20 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioFadeConfiguration {
+  String name;
+  android.hardware.automotive.audiocontrol.FadeState fadeState;
+  long fadeInDurationMs = DEFAULT_FADE_IN_DURATION_MS /* 1000 */;
+  long fadeOutDurationMs = DEFAULT_FADE_OUT_DURATION_MS /* 2000 */;
+  long fadeInDelayedForOffendersMs = DEFAULT_DELAY_FADE_IN_OFFENDERS_MS /* 2000 */;
+  android.media.audio.common.AudioUsage[] fadeableUsages;
+  @nullable android.media.audio.common.AudioContentType[] unfadeableContentTypes;
+  List<android.media.audio.common.AudioAttributes> unfadableAudioAttributes;
+  List<android.hardware.automotive.audiocontrol.FadeConfiguration> fadeOutConfigurations;
+  List<android.hardware.automotive.audiocontrol.FadeConfiguration> fadeInConfigurations;
+  const long DEFAULT_FADE_IN_DURATION_MS = 1000;
+  const long DEFAULT_FADE_OUT_DURATION_MS = 2000;
+  const long DEFAULT_DELAY_FADE_IN_OFFENDERS_MS = 2000;
 }
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
index 58a3667..8eab521 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioFocusChange.aidl
@@ -39,7 +39,7 @@
   GAIN_TRANSIENT = 2,
   GAIN_TRANSIENT_MAY_DUCK = 3,
   GAIN_TRANSIENT_EXCLUSIVE = 4,
-  LOSS = -1,
-  LOSS_TRANSIENT = -2,
-  LOSS_TRANSIENT_CAN_DUCK = -3,
+  LOSS = ((-1) * GAIN) /* -1 */,
+  LOSS_TRANSIENT = ((-1) * GAIN_TRANSIENT) /* -2 */,
+  LOSS_TRANSIENT_CAN_DUCK = ((-1) * GAIN_TRANSIENT_MAY_DUCK) /* -3 */,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZone.aidl
similarity index 74%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZone.aidl
index a5eda52..57a9812 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZone.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZone {
+  String name;
+  int id = android.media.audio.common.AudioHalProductStrategy.ZoneId.DEFAULT /* 0 */;
+  int occupantZoneId = UNASSIGNED_OCCUPANT /* -1 */;
+  android.hardware.automotive.audiocontrol.AudioZoneContext audioZoneContext;
+  List<android.hardware.automotive.audiocontrol.AudioZoneConfig> audioZoneConfigs;
+  List<android.media.audio.common.AudioPort> inputAudioDevices;
+  const int UNASSIGNED_OCCUPANT = (-1) /* -1 */;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
similarity index 82%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
index a5eda52..3fd37bc 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZoneConfig {
+  String name;
+  boolean isDefault;
+  List<android.hardware.automotive.audiocontrol.VolumeGroupConfig> volumeGroups;
+  @nullable android.hardware.automotive.audiocontrol.AudioZoneFadeConfiguration fadeConfiguration;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
similarity index 87%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
index a5eda52..0f8b946 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZoneContext {
+  List<android.hardware.automotive.audiocontrol.AudioZoneContextInfo> audioContextInfos;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
similarity index 83%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
index a5eda52..01ab1be 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZoneContextInfo {
+  String name;
+  int id = UNASSIGNED_CONTEXT_ID /* -1 */;
+  List<android.media.audio.common.AudioAttributes> audioAttributes;
+  const int UNASSIGNED_CONTEXT_ID = (-1) /* -1 */;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
similarity index 82%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
index a5eda52..f3f32bf 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AudioZoneFadeConfiguration {
+  android.hardware.automotive.audiocontrol.AudioFadeConfiguration defaultConfiguration;
+  List<android.hardware.automotive.audiocontrol.TransientFadeConfigurationEntry> transientConfiguration;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
index a5eda52..923b0bd 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable DeviceToContextEntry {
+  List<String> contextNames;
+  android.media.audio.common.AudioPort device;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
similarity index 77%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
index a5eda52..2c978e7 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable FadeConfiguration {
+  long fadeDurationMillis;
+  android.hardware.automotive.audiocontrol.FadeConfiguration.AudioAttributesOrUsage audioAttributesOrUsage;
+  @JavaDerive(equals=true, toString=true) @VintfStability
+  union AudioAttributesOrUsage {
+    android.media.audio.common.AudioAttributes fadeAttribute;
+    android.media.audio.common.AudioUsage usage;
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeState.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeState.aidl
index a5eda52..9b25dfb 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/FadeState.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum FadeState {
+  FADE_STATE_DISABLED,
+  FADE_STATE_ENABLED_DEFAULT,
 }
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index ffd575d..fe39f92 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -12,6 +12,34 @@
  * 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.
+ *//**
+ * Important note on Metadata:
+ * Metadata qualifies a playback track for an output stream.
+ * This is highly closed to {@link android.media.AudioAttributes}.
+ * It allows to identify the audio stream rendered / requesting / abandonning the focus.
+ *
+ * AudioControl 1.0 was limited to identification through {@code AttributeUsage} listed as
+ * {@code audioUsage} in audio_policy_configuration.xsd.
+ *
+ * Any new OEM needs would not be possible without extension.
+ *
+ * Relying on {@link android.hardware.automotive.audiocontrol.PlaybackTrackMetadata} allows
+ * to use a combination of {@code AttributeUsage}, {@code AttributeContentType} and
+ * {@code AttributeTags} to identify the use case / routing thanks to
+ * {@link android.media.audiopolicy.AudioProductStrategy}.
+ * The belonging to a strategy is deduced by an AOSP logic (in sync at native and java layer).
+ *
+ * IMPORTANT NOTE ON TAGS:
+ * To limit the possibilies and prevent from confusion, we expect the String to follow
+ * a given formalism that will be enforced.
+ *
+ * 1 / By convention, tags shall be a "key=value" pair.
+ * Vendor must namespace their tag's key (for example com.google.strategy=VR) to avoid conflicts.
+ * vendor specific applications and must be prefixed by "VX_". Vendor must
+ *
+ * 2 / Tags reported here shall be the same as the tags used to define a given
+ * {@link android.media.audiopolicy.AudioProductStrategy} and so in
+ * audio_policy_engine_configuration.xml file.
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -48,4 +76,7 @@
   oneway void registerGainCallback(in android.hardware.automotive.audiocontrol.IAudioGainCallback callback);
   void setModuleChangeCallback(in android.hardware.automotive.audiocontrol.IModuleChangeCallback callback);
   void clearModuleChangeCallback();
+  android.hardware.automotive.audiocontrol.AudioDeviceConfiguration getAudioDeviceConfiguration();
+  List<android.media.audio.common.AudioPort> getOutputMirroringDevices();
+  List<android.hardware.automotive.audiocontrol.AudioZone> getCarAudioZones();
 }
diff --git a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
index c1e22d4..8d66985 100644
--- a/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/Reasons.aidl
@@ -34,14 +34,14 @@
 package android.hardware.automotive.audiocontrol;
 @Backing(type="int") @VintfStability
 enum Reasons {
-  FORCED_MASTER_MUTE = 1,
-  REMOTE_MUTE = 2,
-  TCU_MUTE = 4,
-  ADAS_DUCKING = 8,
-  NAV_DUCKING = 16,
-  PROJECTION_DUCKING = 32,
-  THERMAL_LIMITATION = 64,
-  SUSPEND_EXIT_VOL_LIMITATION = 128,
-  EXTERNAL_AMP_VOL_FEEDBACK = 256,
-  OTHER = -2147483648,
+  FORCED_MASTER_MUTE = 0x1,
+  REMOTE_MUTE = 0x2,
+  TCU_MUTE = 0x4,
+  ADAS_DUCKING = 0x8,
+  NAV_DUCKING = 0x10,
+  PROJECTION_DUCKING = 0x20,
+  THERMAL_LIMITATION = 0x40,
+  SUSPEND_EXIT_VOL_LIMITATION = 0x80,
+  EXTERNAL_AMP_VOL_FEEDBACK = 0x100,
+  OTHER = 0x80000000,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
similarity index 87%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
index a5eda52..901078c 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+enum RoutingDeviceConfiguration {
+  DEFAULT_AUDIO_ROUTING,
+  DYNAMIC_AUDIO_ROUTING,
+  CONFIGURABLE_AUDIO_ENGINE_ROUTING,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
similarity index 84%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
index a5eda52..72b247b 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable TransientFadeConfigurationEntry {
+  android.media.audio.common.AudioUsage[] transientUsages;
+  android.hardware.automotive.audiocontrol.AudioFadeConfiguration transientFadeConfiguration;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
similarity index 84%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
index a5eda52..50b76a1 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VolumeActivationConfiguration {
+  @nullable String name;
+  List<android.hardware.automotive.audiocontrol.VolumeActivationConfigurationEntry> volumeActivationEntries;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
similarity index 74%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
index a5eda52..d457e57 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VolumeActivationConfigurationEntry {
+  android.hardware.automotive.audiocontrol.VolumeInvocationType type = android.hardware.automotive.audiocontrol.VolumeInvocationType.ON_PLAYBACK_CHANGED;
+  int maxActivationVolumePercentage = DEFAULT_MAX_ACTIVATION_VALUE /* 100 */;
+  int minActivationVolumePercentage = DEFAULT_MIN_ACTIVATION_VALUE /* 0 */;
+  const int DEFAULT_MAX_ACTIVATION_VALUE = 100;
+  const int DEFAULT_MIN_ACTIVATION_VALUE = 0;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
similarity index 79%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
index a5eda52..cc90bbe 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable VolumeGroupConfig {
+  String name;
+  int id = UNASSIGNED_ID /* -1 */;
+  List<android.hardware.automotive.audiocontrol.DeviceToContextEntry> carAudioRoutes;
+  @nullable android.hardware.automotive.audiocontrol.VolumeActivationConfiguration activationConfiguration;
+  const int UNASSIGNED_ID = (-1) /* -1 */;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
index a5eda52..8ce8491 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/audiocontrol/aidl/aidl_api/android.hardware.automotive.audiocontrol/current/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.audiocontrol;
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum VolumeInvocationType {
+  ON_PLAYBACK_CHANGED,
+  ON_SOURCE_CHANGED,
+  ON_BOOT,
 }
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
new file mode 100644
index 0000000..9b5e724
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.RoutingDeviceConfiguration;
+
+/**
+ * Use to configure audio configurations at boot up time.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioDeviceConfiguration {
+    /**
+     * Use to configure audio device routing mechanism
+     */
+    RoutingDeviceConfiguration routingConfig;
+
+    /**
+     * Use to configure core audio volume usage in car audio service
+     */
+    boolean useCoreAudioVolume;
+
+    /**
+     * Use to determine if HAL ducking signal should be sent to audio control HAL from car audio
+     * service
+     */
+    boolean useHalDuckingSignals;
+
+    /**
+     * Use to determine if HAL volume signal should be sent to audio control HAL from car audio
+     * service
+     */
+    boolean useCarVolumeGroupMuting;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
new file mode 100644
index 0000000..4190c46
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioFadeConfiguration.aidl
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.FadeConfiguration;
+import android.hardware.automotive.audiocontrol.FadeState;
+import android.media.audio.common.AudioAttributes;
+import android.media.audio.common.AudioContentType;
+import android.media.audio.common.AudioUsage;
+
+/**
+ * Encapsulates the audio fade configuration info
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioFadeConfiguration {
+    /**
+     * Default fade in duration
+     */
+    const long DEFAULT_FADE_IN_DURATION_MS = 1000;
+
+    /**
+     * Default fade out duration
+     */
+    const long DEFAULT_FADE_OUT_DURATION_MS = 2000;
+
+    /**
+     * Default delay for fade in offenders
+     */
+    const long DEFAULT_DELAY_FADE_IN_OFFENDERS_MS = 2000;
+
+    /**
+     * Audio configuration name, use for debugging purposes
+     */
+    String name;
+
+    /**
+     * Audio configuration state
+     */
+    FadeState fadeState;
+
+    /**
+     * Fade in duration in milliseconds
+     *
+     * <p>Use to construct the default fade in configuration. This can be overwritten for different
+     * attributes/usages by passing a list of fade-in configuration,
+     * see {@code #fadeInConfigurations}
+     */
+    long fadeInDurationMs = DEFAULT_FADE_IN_DURATION_MS;
+
+    /**
+     * Fade out duration in milliseconds
+     *
+     * <p>Use to construct the default fade out configuration. This can be overwritten for different
+     * attributes/usages by passing a list of fade-out configuration,
+     * see {@code #fadeOutConfigurations}
+     */
+    long fadeOutDurationMs = DEFAULT_FADE_OUT_DURATION_MS;
+
+    /**
+     * Fade in delayed duration for audio focus offender in milliseconds
+     *
+     * <p>Fade offender are defined as audio players that do not stop playback after audio focus
+     * lost. This timeout serves to continue to fadeout the offender until audio is stopped or the
+     * timeout expires.
+     */
+    long fadeInDelayedForOffendersMs = DEFAULT_DELAY_FADE_IN_OFFENDERS_MS;
+
+    /**
+     * List of audio attribute usage that should be faded using the parameters in
+     * this configuration.
+     *
+     *<p>If the list is empty car audio service will overwrite the list for the confgiruation with
+     * default usages, e.g. {AudioUsage#MEDIA, AudioUsage#GAME}
+     */
+    AudioUsage[] fadeableUsages;
+
+    /**
+     * Optional list of audio attribute content types that should not be faded.
+     *
+     **<p>The list can be empty in cases where there are no unfadeable content types.
+     *
+     *<p>If the list is not set car audio service will overwrite the list for the confgiruation
+     * with default content type, e.g. {AudioContentType#SPEECH}.
+     */
+    @nullable AudioContentType[] unfadeableContentTypes;
+
+    /**
+     * List of audio attribute that should not be faded.
+     *
+     *<p>The list can be empty in cases where there are no unfadeable attributes
+     */
+    List<AudioAttributes> unfadableAudioAttributes;
+
+    /**
+     * List of fade out configutions which should apply to this audio fade configurations
+     *
+     *<p>The list can be empty in cases where there are no fade out configurations.
+     */
+    List<FadeConfiguration> fadeOutConfigurations;
+
+    /**
+     * List of fade in configutions which should apply to this audio fade configurations
+     *
+     *<p>The list can be empty in cases where there are no fade out configurations
+     */
+    List<FadeConfiguration> fadeInConfigurations;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZone.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZone.aidl
new file mode 100644
index 0000000..d31d6fd
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZone.aidl
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioZoneConfig;
+import android.hardware.automotive.audiocontrol.AudioZoneContext;
+import android.media.audio.common.AudioHalProductStrategy;
+import android.media.audio.common.AudioPort;
+
+/**
+ * Encapsulates the audio configurations for each audio zone
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZone {
+    /**
+     * Value indicating the occupant zone is not assigned.
+     */
+    const int UNASSIGNED_OCCUPANT = -1;
+
+    /**
+     * Audio zone name, only use for debug purposes.
+     *
+     * <p>If present it must be non-empty otherwise car audio service will construct a name
+     * based on audio zone id.
+     */
+    String name;
+
+    /**
+     * Audio zone id use to distiguish between the different audio zones for
+     * volume management, fade, and min/max activation management.
+     *
+     * <p>Value must start at {@link AudioHalProductStrategy#ZoneId#DEFAULT} for the primary zone
+     * and increase for each different zone. Zone id must also not repeat for different zones.
+     */
+    int id = AudioHalProductStrategy.ZoneId.DEFAULT;
+
+    /**
+     * Occupant zone id that should be mapped to this audio zone.
+     *
+     * <p>For audio zones not mapped to an occupant zone use UNASSIGNED_OCCUPANT
+     */
+    int occupantZoneId = UNASSIGNED_OCCUPANT;
+
+    /**
+     * Car audio context which can be used in the audio zone
+     */
+    AudioZoneContext audioZoneContext;
+
+    /**
+     * List of car audio configurations
+     */
+    List<AudioZoneConfig> audioZoneConfigs;
+
+    /**
+     * List of input audio devices used for this zone
+     */
+    List<AudioPort> inputAudioDevices;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
new file mode 100644
index 0000000..6822da5
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneConfig.aidl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioZoneFadeConfiguration;
+import android.hardware.automotive.audiocontrol.VolumeGroupConfig;
+
+/**
+ * Encapsulates the audio zone config information
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZoneConfig {
+    /**
+     * Audio zone config name
+     *
+     * <p>Must be non-empty and unique among the configurations within a zone.
+     */
+    String name;
+
+    /**
+     * Determines if the audio configuration is the default configuration.
+     *
+     * <p>There can only be a single default configuration per zone.
+     */
+    boolean isDefault;
+
+    /**
+     * List car volume group that should be managed within this configuration
+     */
+    List<VolumeGroupConfig> volumeGroups;
+
+    /**
+     * Car audio zone fade configuration
+     */
+    @nullable AudioZoneFadeConfiguration fadeConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
new file mode 100644
index 0000000..390cb09
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioZoneContextInfo;
+
+/**
+ * Encapsulates the list of car audio context info definitions
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZoneContext {
+    /**
+     * List of car audio context info.
+     *
+     * <p>The list must include all audio attributes usages currently supported so that all audio
+     * attribute usages can be routed for each car audio configuration.
+     */
+    List<AudioZoneContextInfo> audioContextInfos;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
new file mode 100644
index 0000000..0ca425c
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.aidl
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.media.audio.common.AudioAttributes;
+
+/**
+ * Encapsulates groups of audio attributes which should be managed together.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZoneContextInfo {
+    /**
+     * Value indicating the context info id is not assigned.
+     */
+    const int UNASSIGNED_CONTEXT_ID = -1;
+
+    /**
+     * Context name which can be used to map the info to an audio route
+     * management as described in each audio configuration.
+     *
+     * <P>Name must be non-empty and unique among all audio context info within the same
+     * {@link android.hardware.automotive.audiocontrol.AudioZoneContext} container.
+     */
+    String name;
+
+    /**
+     * Used in car audio service to manage the info
+     *
+     * <P>Must be non-negative integer if assigned, or UNASSIGNED_CONTEXT_ID otherwise. If using
+     * configurable audio policy engine audio routing with multi-zone configurations the value must
+     * be assigned.
+     */
+    int id = UNASSIGNED_CONTEXT_ID;
+
+    /**
+     * List of audio attributes that belong to the context
+     */
+    List<AudioAttributes> audioAttributes;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
new file mode 100644
index 0000000..a604214
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/AudioZoneFadeConfiguration.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioFadeConfiguration;
+import android.hardware.automotive.audiocontrol.TransientFadeConfigurationEntry;
+
+/**
+ * Encapsulates the audio zone fade configuration
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioZoneFadeConfiguration {
+    /**
+     * Defines the default fade configuration
+     */
+    AudioFadeConfiguration defaultConfiguration;
+
+    /**
+     * List of transient fade configurations.
+     *
+     * <p>The list can be empty if the fade configuration for the zone does not have transient fade
+     * configurations.
+     */
+    List<TransientFadeConfigurationEntry> transientConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
new file mode 100644
index 0000000..bcb5ee7
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/DeviceToContextEntry.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.media.audio.common.AudioPort;
+
+/**
+ * Encapsulates the audio context that should be route to particular device
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable DeviceToContextEntry {
+    /**
+     * List of audio context names that should be routed to the audio device.
+     *
+     * <p>The names must match a {@link AudioZoneContextInfo#name} in the corresponding
+     * {@link AudioZone#audioZoneContext).
+     *
+     * <p>Within a {@link AudioZoneConfig} a context name must not repeat among the different
+     * {@link VolumeGroupConfig}. The value can repeat among different {@link AudioZoneConfig}
+     * within a {@link AudioZone}.
+     */
+    List<String> contextNames;
+
+    /**
+     * Audio port where contexts should be routed.
+     *
+     * <p>For dynamic devices (OUT_HEADSET, OUT_HEADPHONE, etc.) , the audio device address can be
+     * omitted since the information will be obtained at run time when the device is
+     * connected/enabled.
+     */
+    AudioPort device;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
new file mode 100644
index 0000000..e700d6c
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeConfiguration.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.media.audio.common.AudioAttributes;
+import android.media.audio.common.AudioUsage;
+
+/**
+ * Encapsulates the in/out fade configuration
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable FadeConfiguration {
+    /**
+     * Fade duration in milliseconds
+     */
+    long fadeDurationMillis;
+
+    @JavaDerive(equals=true, toString=true)
+    @VintfStability
+    union AudioAttributesOrUsage {
+        AudioAttributes fadeAttribute;
+        AudioUsage usage;
+    }
+
+    /**
+     * Audio attribute or usage that should be impacted by the fade out duration
+     * {@code #fadeDurationMillis}
+     */
+    AudioAttributesOrUsage audioAttributesOrUsage;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeState.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeState.aidl
new file mode 100644
index 0000000..346caae
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/FadeState.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+/**
+ * Encapsulates the audio fade configuration state
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum FadeState {
+    /**
+     * Fade configuration should be disabled
+     */
+    FADE_STATE_DISABLED,
+    /**
+     * Fade configuration should be enabled by default
+     */
+    FADE_STATE_ENABLED_DEFAULT,
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
index 9564efc..1202b4c 100644
--- a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/IAudioControl.aidl
@@ -46,14 +46,17 @@
  * audio_policy_engine_configuration.xml file.
  */
 import android.hardware.audio.common.PlaybackTrackMetadata;
+import android.hardware.automotive.audiocontrol.AudioDeviceConfiguration;
 import android.hardware.automotive.audiocontrol.AudioFocusChange;
 import android.hardware.automotive.audiocontrol.AudioGainConfigInfo;
+import android.hardware.automotive.audiocontrol.AudioZone;
 import android.hardware.automotive.audiocontrol.DuckingInfo;
 import android.hardware.automotive.audiocontrol.IAudioGainCallback;
 import android.hardware.automotive.audiocontrol.IFocusListener;
 import android.hardware.automotive.audiocontrol.IModuleChangeCallback;
 import android.hardware.automotive.audiocontrol.MutingInfo;
 import android.hardware.automotive.audiocontrol.Reasons;
+import android.media.audio.common.AudioPort;
 
 /**
  * Interacts with the car's audio subsystem to manage audio sources and volumes
@@ -206,4 +209,41 @@
      * @throws EX_UNSUPPORTED_OPERATION if dynamic audio configs are not supported.
      */
     void clearModuleChangeCallback();
+
+    /**
+     * Returns the audio device configurations that should be used to configure
+     * the car audio service audio management.
+     *
+     * <p>If this method is not supported, car audio service will attempt to configure the car audio
+     * service properties based on previously supported mechanisms.
+     *
+     * <p>If the returned value contains the
+     * {@link RoutingDeviceConfiguration#DEFAULT_AUDIO_ROUTING} value, the car audio service will
+     * attempt to configure audio routing based on the mechanism previously supported by car audio
+     * service (e.g. car audio configuration file). Otherwise, the {@link #getCarAudioZones()}
+     * API must return valid audio zone(s) configuration(s) for the device.
+     *
+     */
+    AudioDeviceConfiguration getAudioDeviceConfiguration();
+
+    /**
+     * Returns the list of audio devices that can be used for mirroring between different audio
+     * zones.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION if mirroring devices are not supported.
+     */
+    List<AudioPort> getOutputMirroringDevices();
+
+    /**
+     * List of audio zones used to configure car audio service at bootup.
+     *
+     * <p>If the returned value from {@link #getAudioDeviceConfiguration()} contains
+     * {@link RoutingDeviceConfiguration#DEFAULT_AUDIO_ROUTING} value, the car audio service will
+     * attempt to configure the audio routing based on the mechanism previously supported by
+     * car audio service (e.g. car audio configuration file). Otherwise, this method must return
+     * valid audio zone(s) configuration(s) for the device.
+     *
+     * @throws EX_UNSUPPORTED_OPERATION if audio zone configuration are not supported.
+     */
+    List<AudioZone> getCarAudioZones();
 }
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
new file mode 100644
index 0000000..2d17540
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+/**
+ * Use to configure audio device routing mechanism
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+enum RoutingDeviceConfiguration {
+    /**
+     * Use to indicate that audio should be managed based on previously supportec mechamisms in
+     * car audio service.
+     *
+     * <p>If this used then the API to setup the audio zones can just throw
+     * {@code EX_UNSUPPORTED_OPERATION} if called.
+     */
+    DEFAULT_AUDIO_ROUTING,
+    /**
+     * Use to indicate that audio should be managed using the dynamic audio
+     * policy as setup by car audio service using the setup configuration from
+     * the {@Link android.hardware.automotive.audiocontrol.AudioZone}'s info from audio control HAL.
+     *
+     * <p>If this used then the APIs to setup the audio zones must return a valid audio zone
+     * configuration for the device.
+     */
+    DYNAMIC_AUDIO_ROUTING,
+    /**
+     * Use to indicate that audio should be managed using the core audio
+     * routing as setup by car audio service using the setup configuration from
+     * the {@Link android.hardware.automotive.audiocontrol.AudioZone}'s info from audio control HAL
+     * and the information contained within the configurable audio policy engine.
+     *
+     * <p>If this used then the APIs to setup the audio zone(s) must return valid audio zone
+     * configuration(s) for the device.
+     */
+    CONFIGURABLE_AUDIO_ENGINE_ROUTING,
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
new file mode 100644
index 0000000..1984236
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/TransientFadeConfigurationEntry.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.AudioFadeConfiguration;
+import android.media.audio.common.AudioUsage;
+
+/**
+ * Encapsulates the transient audio fade configuration entry.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable TransientFadeConfigurationEntry {
+    /**
+     * List of audio usages gainers that should be used for this configuration entry.
+     */
+    AudioUsage[] transientUsages;
+
+    /**
+     * Defines the transient fade configuration that should be used for the focus interaction with
+     * the usages defined in {@link #transientUsages}
+     */
+    AudioFadeConfiguration transientFadeConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
new file mode 100644
index 0000000..edc5f60
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfiguration.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.VolumeActivationConfigurationEntry;
+
+/**
+ * Use to configure audio activiations, only used at boot up time.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable VolumeActivationConfiguration {
+    /**
+     * Configuration name used for debugging purposes to identify config used.
+     *
+     * <p>Is present, it must be non-empty and unique for all volume acvitations, otherwise
+     * car audio service will construct one based on audio zone, configuration and volume group
+     * info.
+     */
+    @nullable String name;
+
+    /**
+     * List of activation configurations.
+     *
+     * <P>Car audio service currently only  uses the first activation config on the list.
+     */
+    List<VolumeActivationConfigurationEntry> volumeActivationEntries;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
new file mode 100644
index 0000000..7072a2c
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeActivationConfigurationEntry.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.VolumeInvocationType;
+
+/**
+ * Audio activiation volume configuration entry.
+ *
+ * <p> The entry can defined both the minimum and maximum activation values or only one. The latter
+ * allows activations to occur only on the minimum value or maximum value as configured.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable VolumeActivationConfigurationEntry {
+    /**
+     * Default maximum activation value.
+     */
+    const int DEFAULT_MAX_ACTIVATION_VALUE = 100;
+
+    /**
+     * Default minimum activation value.
+     */
+    const int DEFAULT_MIN_ACTIVATION_VALUE = 0;
+
+    /**
+     * Activation type, should be one of:
+     *  ON_PLAYBACK_CHANGED, ON_SOURCE_CHANGED, ON_BOOT
+     */
+    VolumeInvocationType type = VolumeInvocationType.ON_PLAYBACK_CHANGED;
+
+    /**
+     * Max activation percentage between {@code DEFAULT_MIN_ACTIVATION_VALUE} to
+     * {@code DEFAULT_MAX_ACTIVATION_VALUE} percen.
+     *
+     * <p>The value should be {@code DEFAULT_MAX_ACTIVATION_VALUE} if max activation should not
+     * apply.
+     */
+    int maxActivationVolumePercentage = DEFAULT_MAX_ACTIVATION_VALUE;
+
+    /**
+     * Min activation percentage between {@code DEFAULT_MIN_ACTIVATION_VALUE} to
+     * {@code DEFAULT_MAX_ACTIVATION_VALUE} percent.
+     *
+     * <p>The value should be {@code DEFAULT_MIN_ACTIVATION_VALUE} if min activation should not
+     * apply.
+     */
+    int minActivationVolumePercentage = DEFAULT_MIN_ACTIVATION_VALUE;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
new file mode 100644
index 0000000..bea80ce
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeGroupConfig.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+import android.hardware.automotive.audiocontrol.DeviceToContextEntry;
+import android.hardware.automotive.audiocontrol.VolumeActivationConfiguration;
+
+/**
+ * Encapsulates the audio volume grouping for audio zone config.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable VolumeGroupConfig {
+    /**
+     * Value indicating the volume group is not assigned an ID.
+     */
+    const int UNASSIGNED_ID = -1;
+
+    /**
+     * Audio zone group name.
+     *
+     * <p>Must be non-empty if using configurable audio policy engine volume management,
+     * {@see AudioDeviceConfiguration#useCoreAudioVolume} for details. For non-core volume group
+     * management this can be left empty or use for debugging purposes.
+     */
+    String name;
+
+    /**
+     * Audio zone group id.
+     *
+     * <p>Must be set if using configurable audio policy engine volume management, can be
+     * {@code #UNASSIGNED_ID} otherwise. See {@code AudioDeviceConfiguration#useCoreAudioVolume}
+     * for details.
+     */
+    int id = UNASSIGNED_ID;
+
+    /**
+     * Entries of audio device to audio context that are managed similarly for this volume group.
+     */
+    List<DeviceToContextEntry> carAudioRoutes;
+
+    /**
+     * Optional volume activation configuration that should be used for this volume group.
+     */
+    @nullable VolumeActivationConfiguration activationConfiguration;
+}
diff --git a/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
new file mode 100644
index 0000000..0323505
--- /dev/null
+++ b/automotive/audiocontrol/aidl/android/hardware/automotive/audiocontrol/VolumeInvocationType.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol;
+
+/**
+ * Audio activiation type which can be used to activate the min/max
+ * volume changes.
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum VolumeInvocationType {
+    /**
+     * Invocation of volume group activation performed at every playback change.
+     */
+    ON_PLAYBACK_CHANGED,
+    /**
+     * Invocation of volume group activation performed only once at playback after first playback
+     * for a client (app/service UID).
+     */
+    ON_SOURCE_CHANGED,
+    /**
+     * Invocation of volume group activation in perform only at playback once after boot up.
+     */
+    ON_BOOT,
+}
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index fd7e167..1c11c989 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -31,13 +31,19 @@
         "latest_android_hardware_audio_common_ndk_shared",
         "latest_android_hardware_automotive_audiocontrol_ndk_shared",
         "powerpolicyclient_defaults",
+        "car.audio.configuration.xsd.default",
+        "car.fade.configuration.xsd.default",
     ],
     shared_libs: [
         "android.hardware.audio.common@7.0-enums",
-        "libbase",
         "libbinder_ndk",
         "libcutils",
         "liblog",
+        "libbase",
+        "libxml2",
+        "libutils",
+        "android.hardware.audiocontrol.internal",
+        "libaudio_aidl_conversion_common_ndk",
     ],
     srcs: [
         "AudioControl.cpp",
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.cpp b/automotive/audiocontrol/aidl/default/AudioControl.cpp
index 7e7e145..9ae422b 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.cpp
+++ b/automotive/audiocontrol/aidl/default/AudioControl.cpp
@@ -19,6 +19,7 @@
 
 #include "AudioControl.h"
 
+#include <aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.h>
 #include <aidl/android/hardware/automotive/audiocontrol/AudioFocusChange.h>
 #include <aidl/android/hardware/automotive/audiocontrol/DuckingInfo.h>
 #include <aidl/android/hardware/automotive/audiocontrol/IFocusListener.h>
@@ -27,8 +28,8 @@
 #include <android-base/parsebool.h>
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
-
 #include <android_audio_policy_configuration_V7_0-enums.h>
+
 #include <private/android_filesystem_config.h>
 
 #include <numeric>
@@ -41,16 +42,18 @@
 using ::android::base::ParseBool;
 using ::android::base::ParseBoolResult;
 using ::android::base::ParseInt;
+using ::android::hardware::audiocontrol::internal::CarAudioConfigurationXmlConverter;
 using ::std::shared_ptr;
 using ::std::string;
 
-namespace xsd {
-using namespace ::android::audio::policy::configuration::V7_0;
+namespace converter {
+using namespace ::android::hardware::audiocontrol::internal;
 }
 
+namespace api = aidl::android::hardware::automotive::audiocontrol;
+namespace xsd = ::android::audio::policy::configuration::V7_0;
+
 namespace {
-const float kLowerBound = -1.0f;
-const float kUpperBound = 1.0f;
 bool checkCallerHasWritePermissions(int fd) {
     // Double check that's only called by root - it should be be blocked at debug() level,
     // but it doesn't hurt to make sure...
@@ -62,7 +65,7 @@
 }
 
 bool isValidValue(float value) {
-    return (value >= kLowerBound) && (value <= kUpperBound);
+    return (value >= -1.0f) && (value <= 1.0f);
 }
 
 bool safelyParseInt(string s, int* out) {
@@ -71,6 +74,53 @@
     }
     return true;
 }
+
+std::string formatDump(const std::string& input) {
+    const char kSpacer = ' ';
+    std::string output;
+    int indentLevel = 0;
+    bool newLine = false;
+
+    for (char c : input) {
+        switch (c) {
+            case '{':
+                if (!newLine) {
+                    output += '\n';
+                }
+                newLine = true;
+                indentLevel++;
+                for (int i = 0; i < indentLevel; ++i) {
+                    output += kSpacer;
+                }
+                break;
+            case '}':
+                if (!newLine) {
+                    output += '\n';
+                }
+                newLine = true;
+                indentLevel--;
+                for (int i = 0; i < indentLevel; ++i) {
+                    output += kSpacer;
+                }
+                break;
+            case ',':
+                if (!newLine) {
+                    output += '\n';
+                }
+                newLine = true;
+                for (int i = 0; i < indentLevel; ++i) {
+                    output += kSpacer;
+                }
+                break;
+            default:
+                newLine = false;
+                output += c;
+        }
+    }
+
+    return output;
+}
+
 }  // namespace
 
 namespace {
@@ -90,6 +140,9 @@
 using ::aidl::android::media::audio::common::AudioProfile;
 using ::aidl::android::media::audio::common::PcmType;
 
+const static std::string kAudioConfigFile = "/vendor/etc/car_audio_configuration.xml";
+const static std::string kFadeConfigFile = "/vendor/etc/car_audio_fade_configuration.xml";
+
 // reuse common code artifacts
 void fillProfile(const std::vector<int32_t>& channelLayouts,
                  const std::vector<int32_t>& sampleRates, AudioProfile* profile) {
@@ -162,6 +215,12 @@
 }
 }  // namespace
 
+AudioControl::AudioControl() : AudioControl(kAudioConfigFile, kFadeConfigFile) {}
+
+AudioControl::AudioControl(const std::string& carAudioConfig, const std::string& audioFadeConfig)
+    : mCarAudioConfigurationConverter(std::make_shared<CarAudioConfigurationXmlConverter>(
+              carAudioConfig, audioFadeConfig)) {}
+
 ndk::ScopedAStatus AudioControl::registerFocusListener(
         const shared_ptr<IFocusListener>& in_listener) {
     LOG(DEBUG) << "registering focus listener";
@@ -245,14 +304,23 @@
 static inline std::string toString(const std::vector<aidl_type>& in_values) {
     return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
                            [](const std::string& ls, const aidl_type& rs) {
-                               return ls + (ls.empty() ? "" : ",") + rs.toString();
+                               return ls + (ls.empty() ? "" : ", ") + rs.toString();
                            });
 }
 template <typename aidl_enum_type>
 static inline std::string toEnumString(const std::vector<aidl_enum_type>& in_values) {
     return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
                            [](const std::string& ls, const aidl_enum_type& rs) {
-                               return ls + (ls.empty() ? "" : ",") + toString(rs);
+                               return ls + (ls.empty() ? "" : ", ") + toString(rs);
+                           });
+}
+
+template <typename aidl_type>
+static inline std::string toString(const std::vector<std::optional<aidl_type>>& in_values) {
+    return std::accumulate(std::begin(in_values), std::end(in_values), std::string{},
+                           [](const std::string& ls, const std::optional<aidl_type>& rs) {
+                               return ls + (ls.empty() ? "" : ", ") +
+                                      (rs.has_value() ? rs.value().toString() : "empty");
                            });
 }
 
@@ -309,6 +377,50 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus AudioControl::getAudioDeviceConfiguration(
+        AudioDeviceConfiguration* audioDeviceConfig) {
+    if (!audioDeviceConfig) {
+        LOG(ERROR) << __func__ << "Audio device configuration must not be null";
+        return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
+    }
+    if (!mCarAudioConfigurationConverter) {
+        return ndk::ScopedAStatus::ok();
+    }
+    const auto& innerDeviceConfig = mCarAudioConfigurationConverter->getAudioDeviceConfiguration();
+    audioDeviceConfig->routingConfig = innerDeviceConfig.routingConfig;
+    audioDeviceConfig->useCoreAudioVolume = innerDeviceConfig.useCoreAudioVolume;
+    audioDeviceConfig->useCarVolumeGroupMuting = innerDeviceConfig.useCarVolumeGroupMuting;
+    audioDeviceConfig->useHalDuckingSignals = innerDeviceConfig.useHalDuckingSignals;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::getOutputMirroringDevices(
+        std::vector<AudioPort>* mirroringDevices) {
+    if (!mirroringDevices) {
+        LOG(ERROR) << __func__ << "Mirroring devices must not be null";
+        return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
+    }
+    if (!mCarAudioConfigurationConverter || !mCarAudioConfigurationConverter->getErrors().empty()) {
+        return ndk::ScopedAStatus::ok();
+    }
+    const auto& innerDevice = mCarAudioConfigurationConverter->getOutputMirroringDevices();
+    mirroringDevices->insert(mirroringDevices->end(), innerDevice.begin(), innerDevice.end());
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus AudioControl::getCarAudioZones(std::vector<AudioZone>* audioZones) {
+    if (!audioZones) {
+        LOG(ERROR) << __func__ << "Audio zones must not be null";
+        return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL);
+    }
+    if (!mCarAudioConfigurationConverter || !mCarAudioConfigurationConverter->getErrors().empty()) {
+        return ndk::ScopedAStatus::ok();
+    }
+    const auto& innerZones = mCarAudioConfigurationConverter->getAudioZones();
+    audioZones->insert(audioZones->end(), innerZones.begin(), innerZones.end());
+    return ndk::ScopedAStatus::ok();
+}
+
 binder_status_t AudioControl::dump(int fd, const char** args, uint32_t numArgs) {
     if (numArgs == 0) {
         return dumpsys(fd);
@@ -342,6 +454,25 @@
         dprintf(fd, "Focus listener registered\n");
     }
     dprintf(fd, "AudioGainCallback %sregistered\n", (mAudioGainCallback == nullptr ? "NOT " : ""));
+
+    AudioDeviceConfiguration configuration;
+    if (getAudioDeviceConfiguration(&configuration).isOk()) {
+        dprintf(fd, "AudioDeviceConfiguration: %s\n", configuration.toString().c_str());
+    }
+    std::vector<AudioZone> audioZones;
+    if (getCarAudioZones(&audioZones).isOk()) {
+        dprintf(fd, "Audio zones count: %zu\n", audioZones.size());
+        for (const auto& zone : audioZones) {
+            dprintf(fd, "AudioZone: %s\n", formatDump(zone.toString()).c_str());
+        }
+    }
+    std::vector<AudioPort> mirroringDevices;
+    if (getOutputMirroringDevices(&mirroringDevices).isOk()) {
+        dprintf(fd, "Mirroring devices count: %zu\n", mirroringDevices.size());
+        for (const auto& device : mirroringDevices) {
+            dprintf(fd, "Mirroring device: %s\n", formatDump(device.toString()).c_str());
+        }
+    }
     return STATUS_OK;
 }
 
diff --git a/automotive/audiocontrol/aidl/default/AudioControl.h b/automotive/audiocontrol/aidl/default/AudioControl.h
index 7eca446..0425570 100644
--- a/automotive/audiocontrol/aidl/default/AudioControl.h
+++ b/automotive/audiocontrol/aidl/default/AudioControl.h
@@ -35,13 +35,17 @@
 #include <aidl/android/media/audio/common/AudioIoFlags.h>
 #include <aidl/android/media/audio/common/AudioOutputFlags.h>
 
+#include "converter/include/CarAudioConfigurationXmlConverter.h"
+
 namespace aidl::android::hardware::automotive::audiocontrol {
 
-namespace audiohalcommon = ::aidl::android::hardware::audio::common;
 namespace audiomediacommon = ::aidl::android::media::audio::common;
+namespace audiohalcommon = ::aidl::android::hardware::audio::common;
 
 class AudioControl : public BnAudioControl {
   public:
+    AudioControl();
+    AudioControl(const std::string& carAudioConfig, const std::string& audioFadeConfig);
     ndk::ScopedAStatus onAudioFocusChange(const std::string& in_usage, int32_t in_zoneId,
                                           AudioFocusChange in_focusChange) override;
     ndk::ScopedAStatus onDevicesToDuckChange(
@@ -63,6 +67,11 @@
     ndk::ScopedAStatus setModuleChangeCallback(
             const std::shared_ptr<IModuleChangeCallback>& in_callback) override;
     ndk::ScopedAStatus clearModuleChangeCallback() override;
+    ndk::ScopedAStatus getAudioDeviceConfiguration(
+            AudioDeviceConfiguration* audioDeviceConfig) override;
+    ndk::ScopedAStatus getOutputMirroringDevices(
+            std::vector<::aidl::android::media::audio::common::AudioPort>* mirrorDevices) override;
+    ndk::ScopedAStatus getCarAudioZones(std::vector<AudioZone>* audioZones) override;
 
     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
 
@@ -81,6 +90,9 @@
 
     std::shared_ptr<IModuleChangeCallback> mModuleChangeCallback = nullptr;
 
+    std::shared_ptr<::android::hardware::audiocontrol::internal::CarAudioConfigurationXmlConverter>
+            mCarAudioConfigurationConverter = nullptr;
+
     binder_status_t cmdHelp(int fd) const;
     binder_status_t cmdRequestFocus(int fd, const char** args, uint32_t numArgs);
     binder_status_t cmdAbandonFocus(int fd, const char** args, uint32_t numArgs);
diff --git a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
index bcb5669..ffef7fc 100644
--- a/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
+++ b/automotive/audiocontrol/aidl/default/audiocontrol-default.xml
@@ -1,7 +1,7 @@
 <manifest version="2.0" type="device">
     <hal format="aidl">
         <name>android.hardware.automotive.audiocontrol</name>
-        <version>4</version>
+        <version>5</version>
         <fqname>IAudioControl/default</fqname>
     </hal>
 </manifest>
diff --git a/automotive/audiocontrol/aidl/default/converter/Android.bp b/automotive/audiocontrol/aidl/default/converter/Android.bp
new file mode 100644
index 0000000..c00afa2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/Android.bp
@@ -0,0 +1,56 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+    name: "android.hardware.audiocontrol.internal",
+    vendor: true,
+    srcs: [
+        "src/CarAudioConfigurationXmlConverter.cpp",
+        "src/CarAudioConfigurationUtils.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    defaults: [
+        "latest_android_hardware_audio_common_ndk_static",
+        "latest_android_hardware_automotive_audiocontrol_ndk_shared",
+        "car.audio.configuration.xsd.default",
+        "car.fade.configuration.xsd.default",
+        "aidlaudioservice_defaults",
+        "latest_android_media_audio_common_types_ndk_static",
+    ],
+    shared_libs: [
+        "libbase",
+        "libutils",
+        "libmedia_helper",
+        "car.audio.configuration.xsd.default",
+        "car.fade.configuration.xsd.default",
+        "liblog",
+    ],
+    static_libs: [
+        "libaudio_aidl_conversion_common_ndk_cpp",
+    ],
+    header_libs: [
+        "libaudio_system_headers",
+    ],
+}
diff --git a/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationUtils.h b/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationUtils.h
new file mode 100644
index 0000000..29fec0b
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationUtils.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_AUDIOCONTROL_INTERNAL_CONFIGURATION_UTILS_H
+#define ANDROID_HARDWARE_AUDIOCONTROL_INTERNAL_CONFIGURATION_UTILS_H
+
+#include <string>
+
+#include <aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioZoneContextInfo.h>
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace internal {
+
+::aidl::android::hardware::automotive::audiocontrol::AudioZoneContext getDefaultCarAudioContext();
+
+}  // namespace internal
+}  // namespace audiocontrol
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_AUDIOCONTROL_INTERNAL_CONFIGURATION_UTILS_H
diff --git a/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationXmlConverter.h b/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationXmlConverter.h
new file mode 100644
index 0000000..ed29172
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/include/CarAudioConfigurationXmlConverter.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef MAIN8_CARAUDIOCONFIGURATIONXMLCONVERTER_H
+#define MAIN8_CARAUDIOCONFIGURATIONXMLCONVERTER_H
+
+#include <string>
+
+#include "../include/CarAudioConfigurationUtils.h"
+
+#include <aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioZone.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioZoneContext.h>
+
+namespace android::hardware::automotive::audiocontrol {
+class CarAudioConfigurationType;
+}
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace internal {
+
+class CarAudioConfigurationXmlConverter {
+  public:
+    explicit CarAudioConfigurationXmlConverter(const std::string& audioConfigFile,
+                                               const std::string& fadeConfigFile)
+        : mAudioConfigFile(audioConfigFile), mFadeConfigFile(fadeConfigFile) {
+        init();
+    }
+
+    ::aidl::android::hardware::automotive::audiocontrol::AudioDeviceConfiguration
+    getAudioDeviceConfiguration() const;
+
+    std::vector<::aidl::android::hardware::automotive::audiocontrol::AudioZone> getAudioZones()
+            const;
+    std::vector<::aidl::android::media::audio::common::AudioPort> getOutputMirroringDevices() const;
+
+    const std::string getErrors() const { return mParseErrors; }
+
+  private:
+    void init();
+    void initNonDynamicRouting();
+    void initFadeConfigurations();
+    void initAudioDeviceConfiguration(
+            const ::android::hardware::automotive::audiocontrol::CarAudioConfigurationType&
+                    carAudioConfigurationType);
+    void initCarAudioConfigurations(
+            const ::android::hardware::automotive::audiocontrol::CarAudioConfigurationType&
+                    carAudioConfigurationType);
+    void parseAudioDeviceConfigurations(
+            const ::android::hardware::automotive::audiocontrol::CarAudioConfigurationType&
+                    carAudioConfigurationType);
+
+    const std::string mAudioConfigFile;
+    const std::string mFadeConfigFile;
+    ::aidl::android::hardware::automotive::audiocontrol::AudioDeviceConfiguration
+            mAudioDeviceConfiguration;
+    std::optional<::aidl::android::hardware::automotive::audiocontrol::AudioZoneContext>
+            mAudioZoneContext;
+    std::vector<::aidl::android::hardware::automotive::audiocontrol::AudioZone> mAudioZones;
+    std::vector<::aidl::android::media::audio::common::AudioPort> mOutputMirroringDevices;
+    std::string mParseErrors;
+    std::unordered_map<std::string,
+                       ::aidl::android::hardware::automotive::audiocontrol::AudioFadeConfiguration>
+            mFadeConfigurations;
+};
+
+}  // namespace internal
+}  // namespace audiocontrol
+}  // namespace hardware
+}  // namespace android
+
+#endif  // MAIN8_CARAUDIOCONFIGURATIONXMLCONVERTER_H
diff --git a/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationUtils.cpp b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationUtils.cpp
new file mode 100644
index 0000000..e2f8191
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationUtils.cpp
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+
+#include "../include/CarAudioConfigurationUtils.h"
+
+#include <aidl/android/media/audio/common/AudioAttributes.h>
+#include <aidl/android/media/audio/common/AudioUsage.h>
+
+#include <tuple>
+#include <vector>
+
+using ::aidl::android::hardware::automotive::audiocontrol::AudioZoneContext;
+using ::aidl::android::hardware::automotive::audiocontrol::AudioZoneContextInfo;
+
+using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioUsage;
+using aidl::android::media::audio::common::AudioUsage::ALARM;
+using aidl::android::media::audio::common::AudioUsage::ANNOUNCEMENT;
+using aidl::android::media::audio::common::AudioUsage::ASSISTANCE_ACCESSIBILITY;
+using aidl::android::media::audio::common::AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE;
+using aidl::android::media::audio::common::AudioUsage::ASSISTANCE_SONIFICATION;
+using aidl::android::media::audio::common::AudioUsage::ASSISTANT;
+using aidl::android::media::audio::common::AudioUsage::CALL_ASSISTANT;
+using aidl::android::media::audio::common::AudioUsage::EMERGENCY;
+using aidl::android::media::audio::common::AudioUsage::GAME;
+using aidl::android::media::audio::common::AudioUsage::MEDIA;
+using aidl::android::media::audio::common::AudioUsage::NOTIFICATION;
+using aidl::android::media::audio::common::AudioUsage::NOTIFICATION_EVENT;
+using aidl::android::media::audio::common::AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE;
+using aidl::android::media::audio::common::AudioUsage::SAFETY;
+using aidl::android::media::audio::common::AudioUsage::UNKNOWN;
+using aidl::android::media::audio::common::AudioUsage::VEHICLE_STATUS;
+using aidl::android::media::audio::common::AudioUsage::VOICE_COMMUNICATION;
+using aidl::android::media::audio::common::AudioUsage::VOICE_COMMUNICATION_SIGNALLING;
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace internal {
+
+std::vector<AudioAttributes> createAudioAttributes(const std::vector<AudioUsage>& usages) {
+    std::vector<AudioAttributes> audioAttributes;
+    for (const auto& usage : usages) {
+        AudioAttributes attributes;
+        attributes.usage = usage;
+        audioAttributes.push_back(attributes);
+    }
+    return audioAttributes;
+}
+
+AudioZoneContextInfo createAudioZoneContextInfo(const std::string& name, int id,
+                                                const std::vector<AudioUsage>& usages) {
+    AudioZoneContextInfo info;
+    info.name = name;
+    info.id = id;
+    info.audioAttributes = createAudioAttributes(usages);
+    return info;
+}
+
+AudioZoneContext createAudioZoneContextInfo(const std::vector<AudioZoneContextInfo>& info) {
+    AudioZoneContext context;
+    context.audioContextInfos.insert(context.audioContextInfos.begin(), info.begin(), info.end());
+    return context;
+}
+
+AudioZoneContext getDefaultCarAudioContext() {
+    // For legacy reasons, context names are lower case here.
+    static const AudioZoneContext kDefaultContext = createAudioZoneContextInfo(
+            {createAudioZoneContextInfo("music", 1, {UNKNOWN, MEDIA, GAME}),
+             createAudioZoneContextInfo("navigation", 2, {ASSISTANCE_NAVIGATION_GUIDANCE}),
+             createAudioZoneContextInfo("voice_command", 3, {ASSISTANCE_ACCESSIBILITY, ASSISTANT}),
+             createAudioZoneContextInfo("call_ring", 4, {NOTIFICATION_TELEPHONY_RINGTONE}),
+             createAudioZoneContextInfo(
+                     "call", 5,
+                     {VOICE_COMMUNICATION, CALL_ASSISTANT, VOICE_COMMUNICATION_SIGNALLING}),
+             createAudioZoneContextInfo("alarm", 6, {ALARM}),
+             createAudioZoneContextInfo("notification", 7, {NOTIFICATION, NOTIFICATION_EVENT}),
+             createAudioZoneContextInfo("system_sound", 8, {ASSISTANCE_SONIFICATION}),
+             createAudioZoneContextInfo("emergency", 9, {EMERGENCY}),
+             createAudioZoneContextInfo("safety", 10, {SAFETY}),
+             createAudioZoneContextInfo("vehicle_status", 11, {VEHICLE_STATUS}),
+             createAudioZoneContextInfo("announcement", 12, {ANNOUNCEMENT})});
+    return kDefaultContext;
+}
+
+}  // namespace internal
+}  // namespace audiocontrol
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp
new file mode 100644
index 0000000..f4e8123
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp
@@ -0,0 +1,1134 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AudioControl::XSD_Converter"
+
+#define LOG_NDEBUG 0
+#include <android-base/logging.h>
+
+#include "../include/CarAudioConfigurationXmlConverter.h"
+
+#include <aidl/android/hardware/automotive/audiocontrol/RoutingDeviceConfiguration.h>
+#include <android-base/parsebool.h>
+#include <android_hardware_automotive_audiocontrol.h>
+#include <android_hardware_automotive_audiocontrol_fade.h>
+
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+#include <media/AidlConversionCppNdk.h>
+#include <media/TypeConverter.h>
+#include <media/convert.h>
+#include <system/audio.h>
+#include <unistd.h>
+#include <unordered_map>
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace internal {
+namespace xsd = ::android::hardware::automotive::audiocontrol;
+namespace fade = android::hardware::automotive::audiocontrol::fade;
+namespace api = ::aidl::android::hardware::automotive::audiocontrol;
+
+using aidl::android::media::audio::common::AudioAttributes;
+using aidl::android::media::audio::common::AudioContentType;
+using aidl::android::media::audio::common::AudioDevice;
+using aidl::android::media::audio::common::AudioDeviceAddress;
+using aidl::android::media::audio::common::AudioDeviceDescription;
+using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioHalProductStrategy;
+using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortDeviceExt;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioUsage;
+
+using namespace ::android::base;
+
+namespace {
+
+static const std::string kUseCoreRouting{"useCoreAudioRouting"};
+static const std::string kUseCoreVolume{"useCoreAudioVolume"};
+static const std::string kUseHalDuckingSignals{"useHalDuckingSignals"};
+static const std::string kUseCarVolumeGroupMuting{"useCarVolumeGroupMuting"};
+
+static constexpr char kOutBusType[] = "AUDIO_DEVICE_OUT_BUS";
+static constexpr char kInBusType[] = "AUDIO_DEVICE_IN_BUS";
+
+using ActivationMap = std::unordered_map<std::string, api::VolumeActivationConfiguration>;
+using FadeConfigurationMap = std::unordered_map<
+        std::string, ::aidl::android::hardware::automotive::audiocontrol::AudioFadeConfiguration>;
+
+inline bool isReadableConfigurationFile(const std::string& filePath) {
+    return !filePath.empty() && filePath.ends_with(".xml") && (access(filePath.c_str(), R_OK) == 0);
+}
+
+inline bool parseBoolOrDefaultIfFailed(const std::string& value, bool defaultValue) {
+    ParseBoolResult results = ParseBool(value);
+    return results == ParseBoolResult::kError ? defaultValue : results == ParseBoolResult::kTrue;
+}
+
+void parseCoreRoutingInfo(const std::string& value, api::AudioDeviceConfiguration& config) {
+    if (!parseBoolOrDefaultIfFailed(value, /* defaultValue= */ false)) {
+        return;
+    }
+    config.routingConfig = api::RoutingDeviceConfiguration::CONFIGURABLE_AUDIO_ENGINE_ROUTING;
+}
+
+void parseCoreVolumeInfo(const std::string& value, api::AudioDeviceConfiguration& config) {
+    config.useCoreAudioVolume = parseBoolOrDefaultIfFailed(value, config.useCoreAudioVolume);
+}
+
+void parseHalDuckingInfo(const std::string& value, api::AudioDeviceConfiguration& config) {
+    config.useHalDuckingSignals = parseBoolOrDefaultIfFailed(value, config.useHalDuckingSignals);
+}
+
+void parseHalMutingInfo(const std::string& value, api::AudioDeviceConfiguration& config) {
+    config.useCarVolumeGroupMuting =
+            parseBoolOrDefaultIfFailed(value, config.useCarVolumeGroupMuting);
+}
+
+bool parseAudioAttributeUsageString(const std::string& usageString, AudioUsage& usage) {
+    audio_usage_t legacyUsage;
+    if (!::android::UsageTypeConverter::fromString(usageString, legacyUsage)) {
+        LOG(ERROR) << __func__ << " could not parse usage from string " << usageString;
+        return false;
+    }
+    ConversionResult<AudioUsage> result =
+            ::aidl::android::legacy2aidl_audio_usage_t_AudioUsage(legacyUsage);
+    if (!result.ok()) {
+        LOG(ERROR) << __func__ << " could not parse usage legacy type " << legacyUsage;
+        return false;
+    }
+    usage = result.value();
+    return true;
+}
+
+bool parseAudioAttributeUsage(const xsd::UsageType& usageType, AudioAttributes& attributes) {
+    if (!usageType.hasValue()) {
+        LOG(ERROR) << __func__ << " usage does not have value";
+        return false;
+    }
+    if (!parseAudioAttributeUsageString(xsd::toString(usageType.getValue()), attributes.usage)) {
+        return false;
+    }
+    return true;
+}
+
+bool parseAudioAttributesUsages(const std::vector<xsd::UsageType>& usages,
+                                std::vector<AudioAttributes>& audioAttributes) {
+    for (const auto& xsdUsage : usages) {
+        AudioAttributes attributes;
+        if (!parseAudioAttributeUsage(xsdUsage, attributes)) {
+            return false;
+        }
+        audioAttributes.push_back(attributes);
+    }
+    return true;
+}
+
+bool parseContentTypeString(const std::string& typeString, AudioContentType& type) {
+    audio_content_type_t legacyContentType;
+    if (!::android::AudioContentTypeConverter::fromString(typeString, legacyContentType)) {
+        LOG(ERROR) << __func__ << " could not parse content type from string " << typeString;
+        return false;
+    }
+    ConversionResult<AudioContentType> result =
+            ::aidl::android::legacy2aidl_audio_content_type_t_AudioContentType(legacyContentType);
+    if (!result.ok()) {
+        LOG(ERROR) << __func__ << " could not convert legacy content type " << legacyContentType;
+        return false;
+    }
+    type = result.value();
+    return true;
+}
+
+bool parseAudioAttribute(const xsd::AttributesType& attributesType, AudioAttributes& attributes) {
+    if (attributesType.hasUsage()) {
+        if (!parseAudioAttributeUsageString(xsd::toString(attributesType.getUsage()),
+                                            attributes.usage)) {
+            LOG(ERROR) << __func__ << " could not parse audio usage: "
+                       << xsd::toString(attributesType.getUsage());
+            return false;
+        }
+    }
+
+    if (attributesType.hasContentType()) {
+        if (!parseContentTypeString(xsd::toString(attributesType.getContentType()),
+                                    attributes.contentType)) {
+            return false;
+        }
+    }
+
+    if (attributesType.hasTags()) {
+        attributes.tags.push_back(attributesType.getTags());
+    }
+    return true;
+}
+
+bool parseAudioAttributes(const std::vector<xsd::AttributesType>& xsdAttributes,
+                          std::vector<AudioAttributes>& audioAttributes) {
+    for (const auto& xsdAttribute : xsdAttributes) {
+        AudioAttributes attribute;
+        if (!parseAudioAttribute(xsdAttribute, attribute)) {
+            return false;
+        }
+        audioAttributes.push_back(attribute);
+    }
+    return true;
+}
+
+bool parseAudioAttributes(const xsd::AudioAttributesUsagesType& xsdAttributeOrUsages,
+                          std::vector<AudioAttributes>& audioAttributes) {
+    if (xsdAttributeOrUsages.hasUsage_optional()) {
+        if (!parseAudioAttributesUsages(xsdAttributeOrUsages.getUsage_optional(),
+                                        audioAttributes)) {
+            LOG(ERROR) << __func__ << " could not parse audio usages";
+            return false;
+        }
+    }
+
+    if (xsdAttributeOrUsages.hasAudioAttribute_optional()) {
+        if (!parseAudioAttributes(xsdAttributeOrUsages.getAudioAttribute_optional(),
+                                  audioAttributes)) {
+            LOG(ERROR) << __func__ << " could not parse audio attributes";
+            return false;
+        }
+    }
+    return true;
+}
+
+bool parseAudioContext(const xsd::OemContextType& xsdContextInfo,
+                       api::AudioZoneContextInfo& contextInfo) {
+    if (!xsdContextInfo.hasName()) {
+        LOG(ERROR) << __func__ << " Audio context info missing name";
+        return false;
+    }
+
+    contextInfo.name = xsdContextInfo.getName();
+
+    if (xsdContextInfo.hasId()) {
+        ParseInt(xsdContextInfo.getId().c_str(), &contextInfo.id);
+    }
+
+    if (xsdContextInfo.hasAudioAttributes()) {
+        if (!parseAudioAttributes(*xsdContextInfo.getFirstAudioAttributes(),
+                                  contextInfo.audioAttributes)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool parseAudioContexts(const xsd::OemContextsType* xsdContexts, api::AudioZoneContext& context) {
+    if (!xsdContexts->hasOemContext()) {
+        return false;
+    }
+    const auto xsdContextInfos = xsdContexts->getOemContext();
+    for (const auto& xsdContextInfo : xsdContextInfos) {
+        api::AudioZoneContextInfo info;
+        if (!parseAudioContext(xsdContextInfo, info)) {
+            continue;
+        }
+        context.audioContextInfos.push_back(info);
+    }
+    return true;
+}
+
+bool createAudioDevice(const std::string& address, const std::string& type, AudioPort& port) {
+    audio_devices_t legacyDeviceType = AUDIO_DEVICE_NONE;
+    ::android::DeviceConverter::fromString(type, legacyDeviceType);
+    std::string tempString;
+    ::android::DeviceConverter::toString(legacyDeviceType, tempString);
+    ConversionResult<AudioDeviceDescription> result =
+            ::aidl::android::legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyDeviceType);
+    if (legacyDeviceType == AUDIO_DEVICE_NONE || !result.ok()) {
+        LOG(ERROR) << __func__ << " could not parse legacy device type";
+        return false;
+    }
+    AudioDevice device;
+    if (!address.empty()) {
+        device.address = AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(address);
+    }
+    device.type = result.value();
+
+    port.ext = AudioPortExt::make<AudioPortExt::Tag::device>(device);
+
+    return true;
+}
+
+std::string outTypeToOutAudioDevice(const std::string& device) {
+    const static std::unordered_map<std::string, std::string> typeToOutDevice{
+            {"TYPE_BUILTIN_SPEAKER", "AUDIO_DEVICE_OUT_SPEAKER"},
+            {"TYPE_WIRED_HEADSET", "AUDIO_DEVICE_OUT_WIRED_HEADSET"},
+            {"TYPE_WIRED_HEADPHONES", "AUDIO_DEVICE_OUT_WIRED_HEADPHONE,"},
+            {"TYPE_BLUETOOTH_A2DP", "AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"},
+            {"TYPE_HDMI", "AUDIO_DEVICE_OUT_HDMI"},
+            {"TYPE_USB_ACCESSORY", "AUDIO_DEVICE_OUT_USB_ACCESSORY"},
+            {"TYPE_USB_DEVICE", "AUDIO_DEVICE_OUT_USB_DEVICE,"},
+            {"TYPE_USB_HEADSET", "AUDIO_DEVICE_OUT_USB_HEADSET"},
+            {"TYPE_AUX_LINE", "AUDIO_DEVICE_OUT_AUX_LINE"},
+            {"TYPE_BUS", "AUDIO_DEVICE_OUT_BUS"},
+            {"TYPE_BLE_HEADSET", "AUDIO_DEVICE_OUT_BLE_HEADSET"},
+            {"TYPE_BLE_SPEAKER", "AUDIO_DEVICE_OUT_BLE_SPEAKER"},
+            {"TYPE_BLE_BROADCAST", "AUDIO_DEVICE_OUT_BLE_BROADCAST"},
+    };
+
+    if (!device.starts_with("TYPE_")) {
+        return device;
+    }
+
+    const auto it = typeToOutDevice.find(device);
+    return it != typeToOutDevice.end() ? it->second : device;
+}
+
+bool parseAudioDeviceToContexts(const xsd::DeviceRoutesType& deviceRoutesType,
+                                api::DeviceToContextEntry& route) {
+    std::string address = deviceRoutesType.hasAddress() ? deviceRoutesType.getAddress() : "";
+    // Default type is bus for schema
+    std::string type = outTypeToOutAudioDevice(deviceRoutesType.hasType()
+                                                       ? xsd::toString(deviceRoutesType.getType())
+                                                       : std::string(kOutBusType));
+    // Address must be present for audio device bus
+    if (address.empty() && type == std::string(kOutBusType)) {
+        LOG(ERROR) << __func__ << " empty device address for bus device type";
+        return false;
+    }
+    if (!createAudioDevice(address, type, route.device)) {
+        return false;
+    }
+
+    if (!deviceRoutesType.hasContext()) {
+        LOG(ERROR) << __func__ << " empty device context mapping";
+        return false;
+    }
+
+    for (const auto& xsdContext : deviceRoutesType.getContext()) {
+        if (!xsdContext.hasContext()) {
+            LOG(ERROR) << __func__ << " audio device route missing context info";
+            return false;
+        }
+        route.contextNames.push_back(xsdContext.getContext());
+    }
+
+    return true;
+}
+
+bool parseAudioDeviceRoutes(const std::vector<xsd::DeviceRoutesType> deviceRoutesTypes,
+                            std::vector<api::DeviceToContextEntry>& routes) {
+    for (const auto& deviceRouteType : deviceRoutesTypes) {
+        api::DeviceToContextEntry entry;
+        if (!parseAudioDeviceToContexts(deviceRouteType, entry)) {
+            return false;
+        }
+        routes.push_back(entry);
+    }
+    return true;
+}
+
+void parseVolumeGroupActivation(const std::string& activationConfigName,
+                                const ActivationMap& activations,
+                                api::VolumeGroupConfig& volumeGroup) {
+    if (activationConfigName.empty()) {
+        LOG(ERROR) << __func__ << " Volume group " << volumeGroup.name
+                   << " has empty volume group activation name";
+        return;
+    }
+    const auto& it = activations.find(activationConfigName);
+    if (it == activations.end()) {
+        LOG(ERROR) << __func__ << " Volume group " << volumeGroup.name
+                   << " has non-existing volume group activation name " << activationConfigName;
+        return;
+    }
+    volumeGroup.activationConfiguration = it->second;
+}
+
+bool parseVolumeGroup(const xsd::VolumeGroupType& volumeGroupType, const ActivationMap& activations,
+                      api::VolumeGroupConfig& volumeGroup) {
+    if (!volumeGroupType.hasDevice()) {
+        LOG(ERROR) << __func__ << " no device found";
+        return false;
+    }
+
+    if (volumeGroupType.hasName()) {
+        volumeGroup.name = volumeGroupType.getName();
+    }
+
+    if (!parseAudioDeviceRoutes(volumeGroupType.getDevice(), volumeGroup.carAudioRoutes)) {
+        return false;
+    }
+
+    if (volumeGroupType.hasActivationConfig()) {
+        parseVolumeGroupActivation(volumeGroupType.getActivationConfig(), activations, volumeGroup);
+    }
+
+    return true;
+}
+
+bool parseVolumeGroups(const xsd::VolumeGroupsType* volumeGroupsType,
+                       const ActivationMap& activations,
+                       std::vector<api::VolumeGroupConfig>& volumeGroups) {
+    if (!volumeGroupsType->hasGroup()) {
+        LOG(ERROR) << __func__ << " no volume groups found";
+        return false;
+    }
+    for (const auto& volumeGroupType : volumeGroupsType->getGroup()) {
+        api::VolumeGroupConfig volumeGroup;
+        if (!parseVolumeGroup(volumeGroupType, activations, volumeGroup)) {
+            return false;
+        }
+        volumeGroups.push_back(volumeGroup);
+    }
+    return true;
+}
+
+void parseFadeConfigurationUsages(const xsd::ApplyFadeConfigType& fadeConfigType,
+                                  std::vector<AudioUsage>& usages) {
+    if (!fadeConfigType.hasAudioAttributes()) {
+        return;
+    }
+    const xsd::AudioAttributeUsagesType* attributesOrUsagesType =
+            fadeConfigType.getFirstAudioAttributes();
+    if (!attributesOrUsagesType->hasUsage()) {
+        return;
+    }
+    for (const auto& usageType : attributesOrUsagesType->getUsage()) {
+        AudioUsage usage;
+        if (!usageType.hasValue() ||
+            !parseAudioAttributeUsageString(xsd::toString(usageType.getValue()), usage)) {
+            continue;
+        }
+        usages.push_back(usage);
+    }
+}
+
+void parseZoneFadeConfiguration(const xsd::ApplyFadeConfigType& fadeConfigType,
+                                const FadeConfigurationMap& fadeConfigurations,
+                                api::AudioZoneFadeConfiguration& zoneFadeConfiguration) {
+    if (!fadeConfigType.hasName()) {
+        LOG(ERROR) << __func__ << " Found a fade config without a name, skipping assignment";
+        return;
+    }
+
+    const auto it = fadeConfigurations.find(fadeConfigType.getName());
+    if (it == fadeConfigurations.end()) {
+        LOG(ERROR) << __func__ << " Config name " << fadeConfigType.getName()
+                   << " not found, skipping assignment";
+        return;
+    }
+    // Return for default since default configurations do not have any audio attributes mapping
+    if (fadeConfigType.hasIsDefault()) {
+        zoneFadeConfiguration.defaultConfiguration = it->second;
+        return;
+    }
+
+    api::TransientFadeConfigurationEntry entry;
+    entry.transientFadeConfiguration = it->second;
+    parseFadeConfigurationUsages(fadeConfigType, entry.transientUsages);
+    zoneFadeConfiguration.transientConfiguration.push_back(entry);
+}
+
+void parseZoneFadeConfigurations(const xsd::ZoneConfigType& zoneConfigType,
+                                 const FadeConfigurationMap& fadeConfigurations,
+                                 std::optional<api::AudioZoneFadeConfiguration>& zoneFadeConfig) {
+    if (!zoneConfigType.hasApplyFadeConfigs()) {
+        return;
+    }
+    const xsd::ApplyFadeConfigsType* applyFadeConfigs = zoneConfigType.getFirstApplyFadeConfigs();
+    if (!applyFadeConfigs->hasFadeConfig()) {
+        return;
+    }
+    api::AudioZoneFadeConfiguration zoneFadeConfiguration;
+    for (const auto& fadeConfigType : applyFadeConfigs->getFadeConfig()) {
+        parseZoneFadeConfiguration(fadeConfigType, fadeConfigurations, zoneFadeConfiguration);
+    }
+    zoneFadeConfig = zoneFadeConfiguration;
+}
+
+bool parseAudioZoneConfig(const xsd::ZoneConfigType& zoneConfigType,
+                          const ActivationMap& activations,
+                          const FadeConfigurationMap& fadeConfigurations,
+                          api::AudioZoneConfig& config) {
+    if (!zoneConfigType.hasVolumeGroups()) {
+        LOG(ERROR) << __func__ << " no volume groups found";
+        return false;
+    }
+
+    if (zoneConfigType.hasName()) {
+        config.name = zoneConfigType.getName();
+    }
+    if (!parseVolumeGroups(zoneConfigType.getFirstVolumeGroups(), activations,
+                           config.volumeGroups)) {
+        return false;
+    }
+
+    parseZoneFadeConfigurations(zoneConfigType, fadeConfigurations, config.fadeConfiguration);
+
+    config.isDefault = zoneConfigType.hasIsDefault() && zoneConfigType.getIsDefault();
+
+    return true;
+}
+
+bool parseAudioZoneConfigs(const xsd::ZoneConfigsType* zoneConfigsType,
+                           const ActivationMap& activations,
+                           const FadeConfigurationMap& fadeConfigurations,
+                           std::vector<api::AudioZoneConfig>& configs) {
+    if (!zoneConfigsType->hasZoneConfig()) {
+        LOG(ERROR) << __func__ << " No zone configs found";
+        return false;
+    }
+
+    if (zoneConfigsType->getZoneConfig().empty()) {
+        LOG(ERROR) << __func__ << " Empty list of audio configurations";
+        return false;
+    }
+
+    for (const auto& zoneConfigType : zoneConfigsType->getZoneConfig()) {
+        api::AudioZoneConfig config;
+        if (!parseAudioZoneConfig(zoneConfigType, activations, fadeConfigurations, config)) {
+            return false;
+        }
+        configs.push_back(config);
+    }
+
+    return true;
+}
+
+bool parseInputDevice(const xsd::InputDeviceType& xsdInputDevice, AudioPort& inputDevice) {
+    // Input device must have a non-empty address
+    if (!xsdInputDevice.hasAddress() || xsdInputDevice.getAddress().empty()) {
+        LOG(ERROR) << __func__ << " missing device address";
+        return false;
+    }
+    // By default a device is bus type, unless specified
+    std::string inputDeviceType =
+            xsdInputDevice.hasType() ? xsd::toString(xsdInputDevice.getType()) : kInBusType;
+    if (!createAudioDevice(xsdInputDevice.getAddress(), inputDeviceType, inputDevice)) {
+        return false;
+    }
+    return true;
+}
+
+void parseInputDevices(const xsd::InputDevicesType* xsdInputDevices,
+                       std::vector<AudioPort>& inputDevices) {
+    if (!xsdInputDevices->hasInputDevice()) {
+        return;
+    }
+    for (const auto& xsdInputDevice : xsdInputDevices->getInputDevice()) {
+        AudioPort inputDevice;
+        if (!parseInputDevice(xsdInputDevice, inputDevice)) {
+            continue;
+        }
+        inputDevices.push_back(inputDevice);
+    }
+}
+
+bool parseAudioZone(const xsd::ZoneType& zone, const ActivationMap& activations,
+                    const FadeConfigurationMap& fadeConfigurations, api::AudioZone& audioZone) {
+    static int kPrimaryZoneId = static_cast<int>(AudioHalProductStrategy::ZoneId::DEFAULT);
+    if (zone.hasName()) {
+        audioZone.name = zone.getName();
+    }
+
+    if (zone.hasOccupantZoneId()) {
+        ParseInt(zone.getOccupantZoneId().c_str(), &audioZone.occupantZoneId);
+    }
+
+    if (zone.hasInputDevices()) {
+        parseInputDevices(zone.getFirstInputDevices(), audioZone.inputAudioDevices);
+    }
+
+    // Audio zone id is required
+    if (!zone.hasAudioZoneId()) {
+        LOG(ERROR) << __func__ << " Audio zone id required for each zone";
+        return false;
+    }
+
+    bool isPrimary = zone.hasIsPrimary() && zone.getIsPrimary();
+
+    if (isPrimary) {
+        audioZone.id = kPrimaryZoneId;
+    }
+
+    // ID not required in XML for primary zone
+    if (!ParseInt(zone.getAudioZoneId().c_str(), &audioZone.id) && !isPrimary) {
+        LOG(ERROR) << __func__
+                   << " Could not parse audio zone id, must be a non-negative integer or isPrimary "
+                      "must be specify as true for primary zone";
+        return false;
+    }
+
+    if (isPrimary && audioZone.id != kPrimaryZoneId) {
+        LOG(ERROR) << __func__ << " Audio zone is primary but has zone id "
+                   << std::to_string(audioZone.id) << " instead of primary zone id "
+                   << std::to_string(kPrimaryZoneId);
+        return false;
+    }
+
+    if (!zone.hasZoneConfigs()) {
+        LOG(ERROR) << __func__ << " Missing audio zone configs for audio zone id " << audioZone.id;
+        return false;
+    }
+    if (!parseAudioZoneConfigs(zone.getFirstZoneConfigs(), activations, fadeConfigurations,
+                               audioZone.audioZoneConfigs)) {
+        LOG(ERROR) << __func__ << " Could not parse zone configs for audio zone id " << audioZone.id
+                   << ", name " << audioZone.name;
+        return false;
+    }
+
+    return true;
+}
+
+std::string parseAudioZones(const xsd::ZonesType* zones, const api::AudioZoneContext& context,
+                            const ActivationMap& activations,
+                            const FadeConfigurationMap& fadeConfigurations,
+                            std::vector<api::AudioZone>& audioZones) {
+    if (!zones->hasZone()) {
+        return "audio zones are missing";
+    }
+    const auto& xsdZones = zones->getZone();
+    for (const auto& xsdZone : xsdZones) {
+        api::AudioZone audioZone;
+        audioZone.audioZoneContext = context;
+        if (!parseAudioZone(xsdZone, activations, fadeConfigurations, audioZone)) {
+            continue;
+        }
+        audioZones.push_back(audioZone);
+    }
+    return "";
+}
+
+std::unordered_map<std::string,
+                   std::function<void(const std::string&, api::AudioDeviceConfiguration&)>>
+getConfigsParsers() {
+    static const std::unordered_map<
+            std::string, std::function<void(const std::string&, api::AudioDeviceConfiguration&)>>
+            parsers{
+                    {kUseCoreRouting, parseCoreRoutingInfo},
+                    {kUseCoreVolume, parseCoreVolumeInfo},
+                    {kUseHalDuckingSignals, parseHalDuckingInfo},
+                    {kUseCarVolumeGroupMuting, parseHalMutingInfo},
+            };
+
+    return parsers;
+}
+
+bool parseVolumeActivationType(const xsd::ActivationType& xsdType,
+                               api::VolumeInvocationType& activationType) {
+    switch (xsdType) {
+        case xsd::ActivationType::onBoot:
+            activationType = api::VolumeInvocationType::ON_BOOT;
+            break;
+        case xsd::ActivationType::onSourceChanged:
+            activationType = api::VolumeInvocationType::ON_SOURCE_CHANGED;
+            break;
+        case xsd::ActivationType::onPlaybackChanged:
+            activationType = api::VolumeInvocationType::ON_PLAYBACK_CHANGED;
+            break;
+        default:
+            return false;
+    }
+    return true;
+}
+
+bool parseVolumeGroupActivationEntry(const xsd::ActivationVolumeConfigEntryType& xsdEntry,
+                                     api::VolumeActivationConfigurationEntry& entry) {
+    if (!xsdEntry.hasInvocationType()) {
+        // Legacy file had default invocation type as on playback changed
+        entry.type = api::VolumeInvocationType::ON_PLAYBACK_CHANGED;
+    } else if (!parseVolumeActivationType(xsdEntry.getInvocationType(), entry.type)) {
+        LOG(ERROR) << __func__ << " Could not parse configuration entry type";
+        return false;
+    }
+
+    if (xsdEntry.hasMaxActivationVolumePercentage()) {
+        // Parse int ranges are not inclusive
+        ParseInt(xsdEntry.getMaxActivationVolumePercentage().c_str(),
+                 &entry.maxActivationVolumePercentage,
+                 api::VolumeActivationConfigurationEntry::DEFAULT_MIN_ACTIVATION_VALUE - 1,
+                 api::VolumeActivationConfigurationEntry::DEFAULT_MAX_ACTIVATION_VALUE + 1);
+    }
+
+    if (xsdEntry.hasMinActivationVolumePercentage()) {
+        // Parse int ranges are not inclusive
+        ParseInt(xsdEntry.getMinActivationVolumePercentage().c_str(),
+                 &entry.minActivationVolumePercentage,
+                 api::VolumeActivationConfigurationEntry::DEFAULT_MIN_ACTIVATION_VALUE - 1,
+                 api::VolumeActivationConfigurationEntry::DEFAULT_MAX_ACTIVATION_VALUE + 1);
+    }
+
+    return true;
+}
+
+bool parseVolumeGroupActivationEntries(
+        const std::vector<xsd::ActivationVolumeConfigEntryType>& xsdEntries,
+        std::vector<api::VolumeActivationConfigurationEntry>& entries) {
+    for (const auto& xsdEntry : xsdEntries) {
+        api::VolumeActivationConfigurationEntry entry;
+        if (!parseVolumeGroupActivationEntry(xsdEntry, entry)) {
+            LOG(ERROR) << __func__ << " Could not parse volume group activation entries";
+            return false;
+        }
+        entries.push_back(entry);
+    }
+    return true;
+}
+
+bool parseVolumeGroupActivation(const xsd::ActivationVolumeConfigType& xsdActivationConfig,
+                                api::VolumeActivationConfiguration& activation) {
+    if (!xsdActivationConfig.hasName()) {
+        LOG(ERROR) << __func__ << " Activation config missing volume activation name";
+        return false;
+    }
+    if (!xsdActivationConfig.hasActivationVolumeConfigEntry()) {
+        LOG(ERROR) << __func__ << " Activation config missing volume activation entries";
+        return false;
+    }
+    if (!parseVolumeGroupActivationEntries(xsdActivationConfig.getActivationVolumeConfigEntry(),
+                                           activation.volumeActivationEntries)) {
+        LOG(ERROR) << __func__ << " Could not parse volume activation name";
+        return false;
+    }
+    activation.name = xsdActivationConfig.getName();
+    return true;
+}
+
+void parseVolumeGroupActivations(const xsd::ActivationVolumeConfigsType* xsdActivationConfigs,
+                                 ActivationMap& activations) {
+    if (!xsdActivationConfigs->hasActivationVolumeConfig()) {
+        LOG(ERROR) << __func__ << " No volume group activations found";
+        return;
+    }
+    for (const auto& xsdActivationConfig : xsdActivationConfigs->getActivationVolumeConfig()) {
+        api::VolumeActivationConfiguration activationConfiguration;
+        if (!parseVolumeGroupActivation(xsdActivationConfig, activationConfiguration)) {
+            continue;
+        }
+        std::string name = xsdActivationConfig.getName();
+        activations.emplace(name, activationConfiguration);
+    }
+}
+
+void parseOutputMirroringDevices(const xsd::MirroringDevicesType* mirroringDevicesType,
+                                 std::vector<AudioPort>& mirroringDevices) {
+    if (!mirroringDevicesType->hasMirroringDevice()) {
+        LOG(ERROR) << __func__ << " Missing audio mirroring devices";
+        return;
+    }
+    for (const auto& xsdMirrorDevice : mirroringDevicesType->getMirroringDevice()) {
+        AudioPort mirrorDevicePort;
+        if (!xsdMirrorDevice.hasAddress()) {
+            LOG(ERROR) << __func__ << " Missing audio mirroring device address";
+            continue;
+        }
+        if (!createAudioDevice(xsdMirrorDevice.getAddress(), kOutBusType, mirrorDevicePort)) {
+            LOG(ERROR) << __func__ << " Could not create mirror device with address "
+                       << xsdMirrorDevice.getAddress();
+            continue;
+        }
+        mirroringDevices.push_back(mirrorDevicePort);
+    }
+}
+
+api::FadeState getFadeState(const fade::FadeStateType& xsdFadeState) {
+    // Return default value if missing
+    if (!xsdFadeState.hasValue()) {
+        return api::FadeState::FADE_STATE_ENABLED_DEFAULT;
+    }
+    // For legacy files, "0" and "1 " need to be supported.
+    switch (xsdFadeState.getValue()) {
+        case fade::FadeStateEnumType::_0:
+            // Fallthrough
+        case fade::FadeStateEnumType::FADE_STATE_DISABLED:
+            return api::FadeState::FADE_STATE_DISABLED;
+        case fade::FadeStateEnumType::_1:
+            // Fallthrough
+        case fade::FadeStateEnumType::FADE_STATE_ENABLED_DEFAULT:
+            // Fallthrough
+        default:
+            return api::FadeState::FADE_STATE_ENABLED_DEFAULT;
+    }
+}
+
+void parseFadeableUsages(const fade::FadeableUsagesType& fadeUsages,
+                         std::vector<AudioUsage>& usages) {
+    if (!fadeUsages.hasUsage()) {
+        return;
+    }
+    for (const auto& fadeUsage : fadeUsages.getUsage()) {
+        AudioUsage audioUsage;
+        if (!fadeUsage.hasValue() ||
+            !parseAudioAttributeUsageString(fade::toString(fadeUsage.getValue()), audioUsage)) {
+            continue;
+        }
+        usages.push_back(audioUsage);
+    }
+}
+
+void parseFadeAudioAttribute(const fade::AttributesType& fadeAttributes,
+                             AudioAttributes& attributes) {
+    if (fadeAttributes.hasUsage()) {
+        parseAudioAttributeUsageString(fade::toString(fadeAttributes.getUsage()), attributes.usage);
+    }
+    if (fadeAttributes.hasContentType()) {
+        parseContentTypeString(fade::toString(fadeAttributes.getContentType()),
+                               attributes.contentType);
+    }
+    if (fadeAttributes.hasTags()) {
+        attributes.tags.push_back(fadeAttributes.getTags());
+    }
+}
+
+bool parseFadeAudioAttribute(const fade::AudioAttributesUsagesType& fadeAttributes,
+                             std::vector<AudioAttributes>& audioAttributes) {
+    if (fadeAttributes.hasUsage_optional()) {
+        for (const auto& usage : fadeAttributes.getUsage_optional()) {
+            AudioAttributes attributes;
+            if (!usage.hasValue() || !parseAudioAttributeUsageString(
+                                             fade::toString(usage.getValue()), attributes.usage)) {
+                continue;
+            }
+            audioAttributes.push_back(attributes);
+        }
+    }
+    if (fadeAttributes.hasAudioAttribute_optional()) {
+        for (const auto& fadeAttribute : fadeAttributes.getAudioAttribute_optional()) {
+            AudioAttributes attribute;
+            parseFadeAudioAttribute(fadeAttribute, attribute);
+            audioAttributes.push_back(attribute);
+        }
+    }
+    return true;
+}
+
+void parseUnfadeableAudioAttributes(const fade::UnfadeableAudioAttributesType& fadeAttributes,
+                                    std::vector<AudioAttributes>& audioAttributes) {
+    if (!fadeAttributes.hasAudioAttributes()) {
+        return;
+    }
+    parseFadeAudioAttribute(*fadeAttributes.getFirstAudioAttributes(), audioAttributes);
+}
+
+void parseUnfadeableContentType(const fade::UnfadeableContentTypesType& fadeTypes,
+                                std::optional<std::vector<AudioContentType>>& contentTypes) {
+    if (!fadeTypes.hasContentType()) {
+        return;
+    }
+    std::vector<AudioContentType> contents;
+    for (const auto& fadeContentType : fadeTypes.getContentType()) {
+        AudioContentType contentType;
+        if (!fadeContentType.hasValue() ||
+            !parseContentTypeString(fade::toString(fadeContentType.getValue()), contentType)) {
+            continue;
+        }
+        contents.push_back(contentType);
+    }
+    contentTypes = contents;
+}
+
+void parseFadeConfigAudioAttributes(const fade::AudioAttributesUsagesType& fadeAudioAttributesType,
+                                    const int64_t fadeDurationMillins,
+                                    std::vector<api::FadeConfiguration>& fadeInConfigurations) {
+    if (fadeAudioAttributesType.hasAudioAttribute_optional()) {
+        for (const auto& fadeAudioAttribute :
+             fadeAudioAttributesType.getAudioAttribute_optional()) {
+            api::FadeConfiguration fadeConfiguration;
+            AudioAttributes attributes;
+            parseFadeAudioAttribute(fadeAudioAttribute, attributes);
+            fadeConfiguration.fadeDurationMillis = fadeDurationMillins;
+            fadeConfiguration.audioAttributesOrUsage
+                    .set<api::FadeConfiguration::AudioAttributesOrUsage::fadeAttribute>(attributes);
+            fadeInConfigurations.push_back(fadeConfiguration);
+        }
+    }
+
+    if (fadeAudioAttributesType.hasUsage_optional()) {
+        for (const auto& fadeAudioUsage : fadeAudioAttributesType.getUsage_optional()) {
+            api::FadeConfiguration fadeConfiguration;
+            AudioUsage usage;
+            if (!fadeAudioUsage.hasValue() ||
+                !parseAudioAttributeUsageString(fade::toString(fadeAudioUsage.getValue()), usage)) {
+                continue;
+            }
+            fadeConfiguration.fadeDurationMillis = fadeDurationMillins;
+            fadeConfiguration.audioAttributesOrUsage
+                    .set<api::FadeConfiguration::AudioAttributesOrUsage::usage>(usage);
+            fadeInConfigurations.push_back(fadeConfiguration);
+        }
+    }
+}
+void parseFadeConfiguration(const fade::FadeConfigurationType& fadeConfigurationType,
+                            std::vector<api::FadeConfiguration>& fadeConfigurations) {
+    if (!fadeConfigurationType.hasFadeDurationMillis() ||
+        !fadeConfigurationType.hasAudioAttributes() ||
+        fadeConfigurationType.getAudioAttributes().empty()) {
+        return;
+    }
+
+    int64_t fadeDurationMillis = 0L;
+
+    if (!ParseInt(fadeConfigurationType.getFadeDurationMillis().c_str(), &fadeDurationMillis,
+                  static_cast<int64_t>(0))) {
+        return;
+    }
+    parseFadeConfigAudioAttributes(*fadeConfigurationType.getFirstAudioAttributes(),
+                                   fadeDurationMillis, fadeConfigurations);
+}
+
+void parseFadeInConfigurations(const fade::FadeInConfigurationsType& fadeInConfigurationsType,
+                               std::vector<api::FadeConfiguration>& fadeInConfigurations) {
+    if (!fadeInConfigurationsType.hasFadeConfiguration()) {
+        return;
+    }
+    for (const auto& fadeConfigurationType : fadeInConfigurationsType.getFadeConfiguration()) {
+        parseFadeConfiguration(fadeConfigurationType, fadeInConfigurations);
+    }
+}
+
+void parseFadeOutConfigurations(const fade::FadeOutConfigurationsType& fadeOutConfigurationsType,
+                                std::vector<api::FadeConfiguration>& fadeOutConfigurations) {
+    if (!fadeOutConfigurationsType.hasFadeConfiguration()) {
+        return;
+    }
+    for (const auto& fadeConfigurationType : fadeOutConfigurationsType.getFadeConfiguration()) {
+        parseFadeConfiguration(fadeConfigurationType, fadeOutConfigurations);
+    }
+}
+
+bool parseFadeConfig(const fade::FadeConfigurationConfig& fadeConfig,
+                     api::AudioFadeConfiguration& configuration) {
+    // Fade configuration must have a name for zone association. Fade state is also needed to
+    // determine accurate usage.
+    if (!fadeConfig.hasName()) {
+        LOG(ERROR) << __func__ << " Fade configuration missing name";
+        return false;
+    }
+    if (!fadeConfig.hasFadeState()) {
+        LOG(ERROR) << __func__ << " Fade configuration missing fade state";
+        return false;
+    }
+    configuration.name = fadeConfig.getName();
+    configuration.fadeState = getFadeState(*fadeConfig.getFirstFadeState());
+    if (fadeConfig.hasDefaultFadeOutDurationInMillis()) {
+        ParseInt(fadeConfig.getDefaultFadeOutDurationInMillis().c_str(),
+                 &configuration.fadeOutDurationMs, static_cast<int64_t>(0));
+    }
+    if (fadeConfig.hasDefaultFadeInDurationInMillis()) {
+        ParseInt(fadeConfig.getDefaultFadeInDurationInMillis().c_str(),
+                 &configuration.fadeInDurationMs, static_cast<int64_t>(0));
+    }
+    if (fadeConfig.hasDefaultFadeInDelayForOffenders()) {
+        ParseInt(fadeConfig.getDefaultFadeInDelayForOffenders().c_str(),
+                 &configuration.fadeInDelayedForOffendersMs, static_cast<int64_t>(0));
+    }
+
+    if (fadeConfig.hasFadeableUsages()) {
+        parseFadeableUsages(*fadeConfig.getFirstFadeableUsages(), configuration.fadeableUsages);
+    }
+
+    if (fadeConfig.hasUnfadeableContentTypes()) {
+        parseUnfadeableContentType(*fadeConfig.getFirstUnfadeableContentTypes(),
+                                   configuration.unfadeableContentTypes);
+    }
+
+    if (fadeConfig.hasUnfadeableAudioAttributes()) {
+        parseUnfadeableAudioAttributes(*fadeConfig.getFirstUnfadeableAudioAttributes(),
+                                       configuration.unfadableAudioAttributes);
+    }
+    if (fadeConfig.hasFadeInConfigurations()) {
+        parseFadeInConfigurations(*fadeConfig.getFirstFadeInConfigurations(),
+                                  configuration.fadeInConfigurations);
+    }
+    if (fadeConfig.hasFadeOutConfigurations()) {
+        parseFadeOutConfigurations(*fadeConfig.getFirstFadeOutConfigurations(),
+                                   configuration.fadeOutConfigurations);
+    }
+
+    return true;
+}
+
+void parseFadeConfigs(const std::vector<fade::FadeConfigurationConfig>& fadeConfigTypes,
+                      std::vector<api::AudioFadeConfiguration>& fadeConfigs) {
+    for (const auto& fadeConfig : fadeConfigTypes) {
+        api::AudioFadeConfiguration configuration;
+        if (!parseFadeConfig(fadeConfig, configuration)) {
+            continue;
+        }
+        fadeConfigs.push_back(configuration);
+    }
+}
+
+void parseFadeConfigs(const fade::FadeConfigurationConfigs& fadeConfigsType,
+                      std::vector<api::AudioFadeConfiguration>& fadeConfigs) {
+    if (!fadeConfigsType.hasConfig()) {
+        LOG(ERROR) << __func__ << " Fade config file does not contains any fade configs";
+        return;
+    }
+    parseFadeConfigs(fadeConfigsType.getConfig(), fadeConfigs);
+}
+}  // namespace
+
+void CarAudioConfigurationXmlConverter::init() {
+    if (!isReadableConfigurationFile(mAudioConfigFile)) {
+        mParseErrors = "Configuration file " + mAudioConfigFile + " is not readable";
+        initNonDynamicRouting();
+        return;
+    }
+
+    // Supports loading legacy fade configurations from a different file
+    if (isReadableConfigurationFile(mFadeConfigFile)) {
+        initFadeConfigurations();
+    }
+
+    const auto& configOptional = xsd::read(mAudioConfigFile.c_str());
+
+    if (!configOptional.has_value()) {
+        mParseErrors =
+                "Configuration file " + mAudioConfigFile + " , does not have any configurations";
+        initNonDynamicRouting();
+        return;
+    }
+
+    const auto& configurations = configOptional.value();
+    initAudioDeviceConfiguration(configurations);
+    initCarAudioConfigurations(configurations);
+}
+
+void CarAudioConfigurationXmlConverter::initFadeConfigurations() {
+    const auto& fadeConfigOptional = fade::read(mFadeConfigFile.c_str());
+    if (!fadeConfigOptional.has_value() || !fadeConfigOptional.value().hasConfigs()) {
+        LOG(ERROR) << __func__ << " Fade config file " << mFadeConfigFile.c_str()
+                   << " does not contains fade configuration";
+        return;
+    }
+
+    const auto& fadeConfigs = fadeConfigOptional.value().getConfigs();
+
+    if (fadeConfigs.empty()) {
+        LOG(ERROR) << __func__ << " Fade config file " << mFadeConfigFile.c_str()
+                   << " does not contains fade configs";
+    }
+    std::vector<api::AudioFadeConfiguration> fadeConfigurations;
+    parseFadeConfigs(fadeConfigs.front(), fadeConfigurations);
+    for (const auto& fadeConfiguration : fadeConfigurations) {
+        mFadeConfigurations.emplace(fadeConfiguration.name, fadeConfiguration);
+    }
+}
+
+void CarAudioConfigurationXmlConverter::initNonDynamicRouting() {
+    mAudioDeviceConfiguration.routingConfig =
+            api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING;
+}
+
+void CarAudioConfigurationXmlConverter::initAudioDeviceConfiguration(
+        const xsd::CarAudioConfigurationType& carAudioConfigurationType) {
+    parseAudioDeviceConfigurations(carAudioConfigurationType);
+}
+
+void CarAudioConfigurationXmlConverter::parseAudioDeviceConfigurations(
+        const xsd::CarAudioConfigurationType& carAudioConfigurationType) {
+    if (!carAudioConfigurationType.hasDeviceConfigurations()) {
+        return;
+    }
+
+    mAudioDeviceConfiguration.routingConfig =
+            api::RoutingDeviceConfiguration::DYNAMIC_AUDIO_ROUTING;
+
+    const auto deviceConfigs = carAudioConfigurationType.getFirstDeviceConfigurations();
+    if (!deviceConfigs->hasDeviceConfiguration()) {
+        return;
+    }
+
+    std::vector<::android::hardware::automotive::audiocontrol::DeviceConfigurationType> configs =
+            deviceConfigs->getDeviceConfiguration();
+    const auto& parsers = getConfigsParsers();
+    for (const auto& deviceConfig : configs) {
+        if (!deviceConfig.hasName() || !deviceConfig.hasValue()) {
+            continue;
+        }
+        const auto& parser = parsers.find(deviceConfig.getName());
+        if (parser == parsers.end()) {
+            continue;
+        }
+        const auto& method = parser->second;
+        method(deviceConfig.getValue(), mAudioDeviceConfiguration);
+    }
+}
+
+void CarAudioConfigurationXmlConverter::initCarAudioConfigurations(
+        const automotive::audiocontrol::CarAudioConfigurationType& carAudioConfigurationType) {
+    if (!carAudioConfigurationType.hasZones()) {
+        mParseErrors = "Audio zones not found in file " + mAudioConfigFile;
+        initNonDynamicRouting();
+        return;
+    }
+
+    api::AudioZoneContext context;
+    if (!carAudioConfigurationType.hasOemContexts() ||
+        !parseAudioContexts(carAudioConfigurationType.getFirstOemContexts(), context)) {
+        context = getDefaultCarAudioContext();
+    }
+
+    ActivationMap activations;
+    if (carAudioConfigurationType.hasActivationVolumeConfigs()) {
+        parseVolumeGroupActivations(carAudioConfigurationType.getFirstActivationVolumeConfigs(),
+                                    activations);
+    }
+
+    if (carAudioConfigurationType.hasMirroringDevices()) {
+        parseOutputMirroringDevices(carAudioConfigurationType.getFirstMirroringDevices(),
+                                    mOutputMirroringDevices);
+    }
+
+    const auto audioZones = carAudioConfigurationType.getFirstZones();
+
+    std::string message =
+            parseAudioZones(audioZones, context, activations, mFadeConfigurations, mAudioZones);
+
+    // Assign dynamic configuration if not assigned
+    if (!mAudioZones.empty() && mAudioDeviceConfiguration.routingConfig ==
+                                        api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING) {
+        mAudioDeviceConfiguration.routingConfig =
+                api::RoutingDeviceConfiguration::DYNAMIC_AUDIO_ROUTING;
+    }
+
+    if (message.empty()) {
+        return;
+    }
+    mParseErrors =
+            "Error parsing audio zone(s) in file " + mAudioConfigFile + ", message: " + message;
+    LOG(ERROR) << __func__ << " Error parsing zones: " << message;
+    initNonDynamicRouting();
+}
+
+api::AudioDeviceConfiguration CarAudioConfigurationXmlConverter::getAudioDeviceConfiguration()
+        const {
+    return mAudioDeviceConfiguration;
+}
+
+std::vector<api::AudioZone> CarAudioConfigurationXmlConverter::getAudioZones() const {
+    return mAudioZones;
+}
+
+std::vector<::aidl::android::media::audio::common::AudioPort>
+CarAudioConfigurationXmlConverter::getOutputMirroringDevices() const {
+    return mOutputMirroringDevices;
+}
+
+}  // namespace internal
+}  // namespace audiocontrol
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/automotive/audiocontrol/aidl/default/converter/test/Android.bp b/automotive/audiocontrol/aidl/default/converter/test/Android.bp
new file mode 100644
index 0000000..70d4a20
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/Android.bp
@@ -0,0 +1,63 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_team: "trendy_team_aaos_framework",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+filegroup {
+    name: "simple_car_audio_configuration_xml",
+    srcs: [
+        "simple_car_audio_configuration.xml",
+        "simple_car_audio_configuration_with_device_type.xml",
+        "multi_zone_car_audio_configuration.xml",
+        "car_audio_configuration_without_configuration.xml",
+        "car_audio_configuration_with_default_context.xml",
+        "car_audio_configuration_with_missing_zones.xml",
+        "car_audio_configuration_without_audio_zone.xml",
+        "car_audio_fade_configuration.xml",
+    ],
+}
+
+cc_test {
+    name: "AudioControlConverterUnitTest",
+    vendor: true,
+    require_root: true,
+    srcs: ["*.cpp"],
+    stl: "libc++_static",
+    static_libs: [
+        "libbase",
+        "android.hardware.audiocontrol.internal",
+        "libgtest",
+        "libgmock",
+        "libutils",
+        "libaudio_aidl_conversion_common_ndk",
+    ],
+    shared_libs: ["liblog"],
+    defaults: [
+        "latest_android_hardware_audio_common_ndk_static",
+        "car.audio.configuration.xsd.default",
+        "car.fade.configuration.xsd.default",
+        "latest_android_hardware_automotive_audiocontrol_ndk_static",
+        "latest_android_media_audio_common_types_ndk_static",
+    ],
+    data: [
+        ":simple_car_audio_configuration_xml",
+    ],
+    test_suites: ["device-tests"],
+    exclude_shared_libs: [
+        "android.hardware.automotive.audiocontrol-V5-ndk",
+    ],
+}
diff --git a/automotive/audiocontrol/aidl/default/converter/test/AudioControlConverterUnitTest.cpp b/automotive/audiocontrol/aidl/default/converter/test/AudioControlConverterUnitTest.cpp
new file mode 100644
index 0000000..d11a59a
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/AudioControlConverterUnitTest.cpp
@@ -0,0 +1,835 @@
+/*
+ * 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.
+ */
+
+#include <android-base/file.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include <CarAudioConfigurationXmlConverter.h>
+#include <aidl/android/hardware/automotive/audiocontrol/AudioDeviceConfiguration.h>
+
+namespace converter = ::android::hardware::audiocontrol::internal;
+namespace api = ::aidl::android::hardware::automotive::audiocontrol;
+
+using ::testing::ContainsRegex;
+using ::testing::UnorderedElementsAreArray;
+
+namespace {
+
+using ::aidl::android::media::audio::common::AudioAttributes;
+using ::aidl::android::media::audio::common::AudioContentType;
+using ::aidl::android::media::audio::common::AudioDevice;
+using ::aidl::android::media::audio::common::AudioDeviceAddress;
+using ::aidl::android::media::audio::common::AudioDeviceDescription;
+using ::aidl::android::media::audio::common::AudioDeviceType;
+using ::aidl::android::media::audio::common::AudioHalProductStrategy;
+using ::aidl::android::media::audio::common::AudioPort;
+using ::aidl::android::media::audio::common::AudioPortDeviceExt;
+using ::aidl::android::media::audio::common::AudioPortExt;
+using ::aidl::android::media::audio::common::AudioUsage;
+
+std::string getTestFilePath(const std::string& filename) {
+    static std::string baseDir = android::base::GetExecutableDirectory();
+    return baseDir + "/" + filename;
+}
+
+AudioAttributes createAudioAttributes(const AudioUsage& usage,
+                                      const AudioContentType& type = AudioContentType::UNKNOWN,
+                                      const std::string tags = "") {
+    AudioAttributes attributes;
+    attributes.usage = usage;
+    attributes.contentType = type;
+    if (!tags.empty()) {
+        attributes.tags.push_back(tags);
+    }
+    return attributes;
+}
+
+api::AudioZoneContextInfo createContextInfo(const std::string& name,
+                                            const std::vector<AudioAttributes>& attributes,
+                                            const int id = -1) {
+    api::AudioZoneContextInfo info;
+    info.name = name;
+    if (id != -1) {
+        info.id = id;
+    }
+    for (const auto& attribute : attributes) {
+        info.audioAttributes.push_back(attribute);
+    }
+    return info;
+}
+
+api::AudioZoneContextInfo createContextInfo(const std::string& name,
+                                            const std::vector<AudioUsage>& usages,
+                                            const int id = -1) {
+    std::vector<AudioAttributes> attributes;
+    attributes.reserve(usages.size());
+    for (const auto& usage : usages) {
+        attributes.push_back(createAudioAttributes(usage));
+    }
+    return createContextInfo(name, attributes, id);
+}
+
+AudioPort createAudioPort(const std::string& address, const AudioDeviceType& type,
+                          const std::string& connection = "") {
+    AudioPort port;
+    AudioDevice device;
+    device.address = AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(address);
+
+    AudioDeviceDescription description;
+    description.type = type;
+    description.connection = connection;
+    device.type = description;
+
+    port.ext = AudioPortExt::make<AudioPortExt::Tag::device>(device);
+
+    return port;
+}
+
+api::DeviceToContextEntry createRoutes(const AudioPort& port,
+                                       const std::vector<std::string>& contexts) {
+    api::DeviceToContextEntry entry;
+    entry.device = port;
+    entry.contextNames = contexts;
+    return entry;
+}
+
+api::VolumeGroupConfig createVolumeGroup(const std::string& name,
+                                         const api::VolumeActivationConfiguration& activation,
+                                         const std::vector<api::DeviceToContextEntry>& routes) {
+    api::VolumeGroupConfig config;
+    config.name = name;
+    config.activationConfiguration = activation;
+    config.carAudioRoutes = routes;
+    return config;
+}
+
+api::AudioZoneConfig createAudioZoneConfig(const std::string& name,
+                                           const api::AudioZoneFadeConfiguration& fadeConfiguration,
+                                           const std::vector<api::VolumeGroupConfig>& groups,
+                                           bool isDefault = false) {
+    api::AudioZoneConfig config;
+    config.name = name;
+    config.isDefault = isDefault;
+    config.volumeGroups = groups;
+    config.fadeConfiguration = fadeConfiguration;
+    return config;
+}
+
+api::VolumeActivationConfiguration createVolumeActivation(const std::string& name,
+                                                          const api::VolumeInvocationType& type,
+                                                          int minVolume, int maxVolume) {
+    api::VolumeActivationConfiguration activation;
+    activation.name = name;
+    api::VolumeActivationConfigurationEntry entry;
+    entry.maxActivationVolumePercentage = maxVolume;
+    entry.minActivationVolumePercentage = minVolume;
+    entry.type = type;
+    activation.volumeActivationEntries.push_back(entry);
+
+    return activation;
+}
+
+api::FadeConfiguration createFadeConfiguration(const long& fadeDurationsMillis,
+                                               const AudioAttributes& audioAttributes) {
+    api::FadeConfiguration configuration;
+    configuration.fadeDurationMillis = fadeDurationsMillis;
+    configuration.audioAttributesOrUsage
+            .set<api::FadeConfiguration::AudioAttributesOrUsage::Tag::fadeAttribute>(
+                    audioAttributes);
+    return configuration;
+}
+
+api::FadeConfiguration createFadeConfiguration(const long& fadeDurationsMillis,
+                                               const AudioUsage& audioUsage) {
+    api::FadeConfiguration configuration;
+    configuration.fadeDurationMillis = fadeDurationsMillis;
+    configuration.audioAttributesOrUsage
+            .set<api::FadeConfiguration::AudioAttributesOrUsage::Tag::usage>(audioUsage);
+    return configuration;
+}
+
+api::AudioFadeConfiguration createAudioFadeConfiguration(
+        const std::string& name, const api::FadeState& state,
+        const std::vector<AudioUsage>& fadeableUsages = std::vector<AudioUsage>(),
+        const std::optional<std::vector<AudioContentType>>& unfadeableContentTypes = std::nullopt,
+        const std::vector<AudioAttributes> unfadeableAudioAttributes =
+                std::vector<AudioAttributes>(),
+        const std::vector<api::FadeConfiguration> fadeOutConfigurations =
+                std::vector<api::FadeConfiguration>(),
+        const std::vector<api::FadeConfiguration> fadeInConfigurations =
+                std::vector<api::FadeConfiguration>(),
+        const long& fadeOutDurationMs = api::AudioFadeConfiguration::DEFAULT_FADE_OUT_DURATION_MS,
+        const long& fadeInDurationMs = api::AudioFadeConfiguration::DEFAULT_FADE_IN_DURATION_MS,
+        const long& fadeInDelayedForOffendersMs =
+                api::AudioFadeConfiguration::DEFAULT_DELAY_FADE_IN_OFFENDERS_MS) {
+    api::AudioFadeConfiguration audioZoneFadeConfiguration;
+    audioZoneFadeConfiguration.name = name;
+    audioZoneFadeConfiguration.fadeInDurationMs = fadeInDurationMs;
+    audioZoneFadeConfiguration.fadeOutDurationMs = fadeOutDurationMs;
+    audioZoneFadeConfiguration.fadeInDelayedForOffendersMs = fadeInDelayedForOffendersMs;
+    audioZoneFadeConfiguration.fadeState = state;
+    audioZoneFadeConfiguration.fadeableUsages = fadeableUsages;
+    audioZoneFadeConfiguration.unfadeableContentTypes = unfadeableContentTypes;
+    audioZoneFadeConfiguration.unfadableAudioAttributes = unfadeableAudioAttributes;
+    audioZoneFadeConfiguration.fadeOutConfigurations = fadeOutConfigurations;
+    audioZoneFadeConfiguration.fadeInConfigurations = fadeInConfigurations;
+
+    return audioZoneFadeConfiguration;
+}
+
+api::TransientFadeConfigurationEntry createTransientFadeConfiguration(
+        const api::AudioFadeConfiguration& fadeConfig, const std::vector<AudioUsage>& usages) {
+    api::TransientFadeConfigurationEntry entry;
+    entry.transientFadeConfiguration = fadeConfig;
+    entry.transientUsages = usages;
+    return entry;
+}
+
+api::AudioZoneFadeConfiguration createAudioZoneFadeConfiguration(
+        const api::AudioFadeConfiguration& defaultConfig,
+        const std::vector<api::TransientFadeConfigurationEntry>& transientConfigs) {
+    api::AudioZoneFadeConfiguration zoneFadeConfiguration;
+    zoneFadeConfiguration.defaultConfiguration = defaultConfig;
+    zoneFadeConfiguration.transientConfiguration = transientConfigs;
+    return zoneFadeConfiguration;
+}
+
+api::AudioZone createAudioZone(const std::string& name, const int zoneId,
+                               const std::vector<api::AudioZoneContextInfo>& contexts,
+                               const std::vector<api::AudioZoneConfig>& configs) {
+    api::AudioZone zone;
+    zone.name = name;
+    zone.id = zoneId;
+    zone.occupantZoneId = zoneId;
+    zone.audioZoneContext.audioContextInfos = contexts;
+    zone.audioZoneConfigs = configs;
+    return zone;
+}
+
+const std::vector<AudioUsage> kFadeableUsages = {AudioUsage::MEDIA,
+                                                 AudioUsage::GAME,
+                                                 AudioUsage::ASSISTANCE_SONIFICATION,
+                                                 AudioUsage::ASSISTANCE_ACCESSIBILITY,
+                                                 AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE,
+                                                 AudioUsage::ASSISTANT,
+                                                 AudioUsage::NOTIFICATION,
+                                                 AudioUsage::ANNOUNCEMENT};
+
+const std::vector<AudioAttributes> kUnfadeableAudioAttributes = {
+        createAudioAttributes(AudioUsage::MEDIA, AudioContentType::UNKNOWN, "oem_specific_tag1")};
+
+const std::vector<api::FadeConfiguration> kFadeOutConfigurations = {
+        createFadeConfiguration(
+                500, createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+                                           "oem_specific_tag2")),
+        createFadeConfiguration(500, AudioUsage::MEDIA),
+        createFadeConfiguration(500, AudioUsage::GAME),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_SONIFICATION),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+        createFadeConfiguration(800, AudioUsage::ASSISTANT),
+        createFadeConfiguration(800, AudioUsage::ANNOUNCEMENT),
+};
+
+const std::vector<api::FadeConfiguration> kFadeInConfigurations = {
+        createFadeConfiguration(
+                1000, createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+                                            "oem_specific_tag2")),
+        createFadeConfiguration(1000, AudioUsage::MEDIA),
+        createFadeConfiguration(1000, AudioUsage::GAME),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_SONIFICATION),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+        createFadeConfiguration(800, AudioUsage::ASSISTANT),
+        createFadeConfiguration(800, AudioUsage::ANNOUNCEMENT),
+};
+
+const api::AudioFadeConfiguration kRelaxedFading = createAudioFadeConfiguration(
+        "relaxed fading", api::FadeState::FADE_STATE_ENABLED_DEFAULT, kFadeableUsages,
+        std::optional<std::vector<AudioContentType>>(
+                {AudioContentType::SPEECH, AudioContentType::SONIFICATION}),
+        kUnfadeableAudioAttributes, kFadeOutConfigurations, kFadeInConfigurations, 800, 500, 10000);
+
+const std::vector<AudioAttributes> kAggressiveUnfadeableAudioAttributes = {
+        createAudioAttributes(AudioUsage::MEDIA, AudioContentType::UNKNOWN, "oem_specific_tag1"),
+        createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+                              "oem_projection_service"),
+};
+
+const std::vector<api::FadeConfiguration> kAggressiveFadeOutConfigurations = {
+        createFadeConfiguration(150, AudioUsage::MEDIA),
+        createFadeConfiguration(150, AudioUsage::GAME),
+        createFadeConfiguration(400, AudioUsage::ASSISTANCE_SONIFICATION),
+        createFadeConfiguration(400, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+        createFadeConfiguration(400, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+        createFadeConfiguration(400, AudioUsage::ASSISTANT),
+        createFadeConfiguration(400, AudioUsage::ANNOUNCEMENT),
+};
+
+const std::vector<api::FadeConfiguration> kAggressiveFadeInConfigurations = {
+        createFadeConfiguration(300, AudioUsage::MEDIA),
+        createFadeConfiguration(300, AudioUsage::GAME),
+        createFadeConfiguration(550, AudioUsage::ASSISTANCE_SONIFICATION),
+        createFadeConfiguration(550, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+        createFadeConfiguration(550, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+        createFadeConfiguration(550, AudioUsage::ASSISTANT),
+        createFadeConfiguration(550, AudioUsage::ANNOUNCEMENT),
+};
+
+const api::AudioFadeConfiguration kAggressiveFading = createAudioFadeConfiguration(
+        "aggressive fading", api::FadeState::FADE_STATE_ENABLED_DEFAULT, kFadeableUsages,
+        std::optional<std::vector<AudioContentType>>(
+                {AudioContentType::SPEECH, AudioContentType::MUSIC}),
+        kAggressiveUnfadeableAudioAttributes, kAggressiveFadeOutConfigurations,
+        kAggressiveFadeInConfigurations);
+
+const api::AudioFadeConfiguration kDisabledFading =
+        createAudioFadeConfiguration("disabled fading", api::FadeState::FADE_STATE_DISABLED);
+
+const std::vector<api::FadeConfiguration> kDynamicFadeOutConfigurations = {
+        createFadeConfiguration(
+                500, createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+                                           "oem_specific_tag2")),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_SONIFICATION),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+        createFadeConfiguration(800, AudioUsage::ASSISTANT),
+        createFadeConfiguration(800, AudioUsage::ANNOUNCEMENT),
+};
+
+const std::vector<api::FadeConfiguration> kDynamicFadeInConfigurations = {
+        createFadeConfiguration(
+                1000, createAudioAttributes(AudioUsage::ASSISTANT, AudioContentType::UNKNOWN,
+                                            "oem_specific_tag2")),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_SONIFICATION),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_ACCESSIBILITY),
+        createFadeConfiguration(800, AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE),
+        createFadeConfiguration(800, AudioUsage::ASSISTANT),
+        createFadeConfiguration(800, AudioUsage::ANNOUNCEMENT),
+};
+
+const api::AudioFadeConfiguration kDynamicFading = createAudioFadeConfiguration(
+        "dynamic fading", api::FadeState::FADE_STATE_ENABLED_DEFAULT, kFadeableUsages,
+        std::optional<std::vector<AudioContentType>>(
+                {AudioContentType::SPEECH, AudioContentType::MOVIE}),
+        kUnfadeableAudioAttributes, kDynamicFadeOutConfigurations, kDynamicFadeInConfigurations,
+        800, 500);
+
+const api::AudioZoneFadeConfiguration kDefaultAudioConfigFading = createAudioZoneFadeConfiguration(
+        kRelaxedFading,
+        {createTransientFadeConfiguration(
+                 kAggressiveFading, {AudioUsage::VOICE_COMMUNICATION, AudioUsage::ANNOUNCEMENT,
+                                     AudioUsage::VEHICLE_STATUS, AudioUsage::SAFETY}),
+         createTransientFadeConfiguration(kDisabledFading, {AudioUsage::EMERGENCY})});
+
+const api::AudioZoneFadeConfiguration kDynamicDeviceAudioConfigFading =
+        createAudioZoneFadeConfiguration(
+                kDynamicFading,
+                {createTransientFadeConfiguration(
+                         kAggressiveFading,
+                         {AudioUsage::VOICE_COMMUNICATION, AudioUsage::ANNOUNCEMENT,
+                          AudioUsage::VEHICLE_STATUS, AudioUsage::SAFETY}),
+                 createTransientFadeConfiguration(kDisabledFading, {AudioUsage::EMERGENCY})});
+
+const api::AudioZoneContextInfo kMusicContextInfo =
+        createContextInfo("oem_music", {AudioUsage::MEDIA, AudioUsage::GAME, AudioUsage::UNKNOWN});
+const api::AudioZoneContextInfo kNotificationContextInfo = createContextInfo(
+        "oem_notification", {AudioUsage::NOTIFICATION, AudioUsage::NOTIFICATION_EVENT});
+const api::AudioZoneContextInfo kVoiceContextInfo = createContextInfo(
+        "oem_voice_command", {AudioUsage::ASSISTANT, AudioUsage::ASSISTANCE_ACCESSIBILITY,
+                              AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE});
+const api::AudioZoneContextInfo kCallContextInfo =
+        createContextInfo("oem_call", {AudioUsage::VOICE_COMMUNICATION, AudioUsage::CALL_ASSISTANT,
+                                       AudioUsage::VOICE_COMMUNICATION_SIGNALLING});
+const api::AudioZoneContextInfo kRingContextInfo =
+        createContextInfo("oem_call_ring", {AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE});
+const api::AudioZoneContextInfo kAlarmContextInfo =
+        createContextInfo("oem_alarm", {AudioUsage::ALARM});
+const api::AudioZoneContextInfo kSystemContextInfo = createContextInfo(
+        "oem_system_sound",
+        {AudioUsage::ASSISTANCE_SONIFICATION, AudioUsage::EMERGENCY, AudioUsage::SAFETY,
+         AudioUsage::VEHICLE_STATUS, AudioUsage::ANNOUNCEMENT});
+const api::AudioZoneContextInfo kOemContextInfo = createContextInfo(
+        "oem_context", {createAudioAttributes(AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE,
+                                              AudioContentType::SPEECH, "oem=extension_8675309")});
+
+const std::vector<api::AudioZoneContextInfo> kSimpleCarAudioConfigurationContext = {
+        kOemContextInfo,  kMusicContextInfo, kNotificationContextInfo, kVoiceContextInfo,
+        kCallContextInfo, kRingContextInfo,  kAlarmContextInfo,        kSystemContextInfo};
+
+const api::AudioZoneContextInfo kDefaultMusicContextInfo =
+        createContextInfo("music", {AudioUsage::UNKNOWN, AudioUsage::MEDIA, AudioUsage::GAME}, 1);
+const api::AudioZoneContextInfo kDefaultNavContextInfo =
+        createContextInfo("navigation", {AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE}, 2);
+const api::AudioZoneContextInfo kDefaultVoiceContextInfo = createContextInfo(
+        "voice_command", {AudioUsage::ASSISTANCE_ACCESSIBILITY, AudioUsage::ASSISTANT}, 3);
+const api::AudioZoneContextInfo kDefaultRingContextInfo =
+        createContextInfo("call_ring", {AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE}, 4);
+const api::AudioZoneContextInfo kDefaultCallContextInfo =
+        createContextInfo("call",
+                          {AudioUsage::VOICE_COMMUNICATION, AudioUsage::CALL_ASSISTANT,
+                           AudioUsage::VOICE_COMMUNICATION_SIGNALLING},
+                          5);
+const api::AudioZoneContextInfo kDefaultAlarmContextInfo =
+        createContextInfo("alarm", {AudioUsage::ALARM}, 6);
+const api::AudioZoneContextInfo kDefaultNotificationContextInfo = createContextInfo(
+        "notification", {AudioUsage::NOTIFICATION, AudioUsage::NOTIFICATION_EVENT}, 7);
+const api::AudioZoneContextInfo kDefaultSystemContextInfo =
+        createContextInfo("system_sound", {AudioUsage::ASSISTANCE_SONIFICATION}, 8);
+const api::AudioZoneContextInfo kDefaultEmergencyContextInfo =
+        createContextInfo("emergency", {AudioUsage::EMERGENCY}, 9);
+const api::AudioZoneContextInfo kDefaultSafetyContextInfo =
+        createContextInfo("safety", {AudioUsage::SAFETY}, 10);
+const api::AudioZoneContextInfo kDefaultVehicleStatusContextInfo =
+        createContextInfo("vehicle_status", {AudioUsage::VEHICLE_STATUS}, 11);
+const api::AudioZoneContextInfo kDefaultAnnouncementContextInfo =
+        createContextInfo("announcement", {AudioUsage::ANNOUNCEMENT}, 12);
+
+const std::vector<api::AudioZoneContextInfo> kDefaultCarAudioConfigurationContext = {
+        kDefaultMusicContextInfo,         kDefaultNavContextInfo,
+        kDefaultVoiceContextInfo,         kDefaultRingContextInfo,
+        kDefaultCallContextInfo,          kDefaultAlarmContextInfo,
+        kDefaultNotificationContextInfo,  kDefaultSystemContextInfo,
+        kDefaultEmergencyContextInfo,     kDefaultSafetyContextInfo,
+        kDefaultVehicleStatusContextInfo, kDefaultAnnouncementContextInfo};
+
+const api::VolumeActivationConfiguration kOnBootVolumeActivation =
+        createVolumeActivation("on_boot_config", api::VolumeInvocationType::ON_BOOT, 0, 80);
+const api::VolumeActivationConfiguration kOnSourceVolumeActivation = createVolumeActivation(
+        "on_source_changed_config", api::VolumeInvocationType::ON_SOURCE_CHANGED, 20, 80);
+const api::VolumeActivationConfiguration kOnPlayVolumeActivation = createVolumeActivation(
+        "on_playback_changed_config", api::VolumeInvocationType::ON_PLAYBACK_CHANGED, 10, 90);
+
+const AudioPort kBusMediaDevice = createAudioPort("BUS00_MEDIA", AudioDeviceType::OUT_BUS);
+const AudioPort kBTMediaDevice = createAudioPort("temp", AudioDeviceType::OUT_DEVICE, "bt-a2dp");
+const AudioPort kUSBMediaDevice = createAudioPort("", AudioDeviceType::OUT_HEADSET, "usb");
+
+const AudioPort kBusNavDevice = createAudioPort("BUS02_NAV_GUIDANCE", AudioDeviceType::OUT_BUS);
+const AudioPort kBusPhoneDevice = createAudioPort("BUS03_PHONE", AudioDeviceType::OUT_BUS);
+const AudioPort kBusSysDevice = createAudioPort("BUS01_SYS_NOTIFICATION", AudioDeviceType::OUT_BUS);
+
+const AudioPort kMirrorDevice1 = createAudioPort("mirror_bus_device_1", AudioDeviceType::OUT_BUS);
+const AudioPort kMirrorDevice2 = createAudioPort("mirror_bus_device_2", AudioDeviceType::OUT_BUS);
+const std::vector<AudioPort> kMirroringDevices = {kMirrorDevice1, kMirrorDevice2};
+
+const AudioPort kMirrorDeviceThree =
+        createAudioPort("mirror_bus_device_three", AudioDeviceType::OUT_BUS);
+const AudioPort kMirrorDeviceFour =
+        createAudioPort("mirror_bus_device_four", AudioDeviceType::OUT_BUS);
+const std::vector<AudioPort> kMultiZoneMirroringDevices = {kMirrorDeviceThree, kMirrorDeviceFour};
+
+const AudioPort kInFMTunerDevice = createAudioPort("fm_tuner", AudioDeviceType::IN_FM_TUNER);
+const AudioPort kInMicDevice = createAudioPort("built_in_mic", AudioDeviceType::IN_MICROPHONE);
+const AudioPort kInBusDevice = createAudioPort("in_bus_device", AudioDeviceType::IN_BUS);
+const std::vector<AudioPort> kInputDevices{kInFMTunerDevice, kInMicDevice, kInBusDevice};
+
+const api::VolumeGroupConfig kBusMediaVolumeGroup = createVolumeGroup(
+        "entertainment", kOnBootVolumeActivation, {createRoutes(kBusMediaDevice, {"oem_music"})});
+const api::VolumeGroupConfig kUSBMediaVolumeGroup = createVolumeGroup(
+        "entertainment", kOnBootVolumeActivation, {createRoutes(kUSBMediaDevice, {"oem_music"})});
+const api::VolumeGroupConfig kBTMediaVolumeGroup = createVolumeGroup(
+        "entertainment", kOnBootVolumeActivation, {createRoutes(kBTMediaDevice, {"oem_music"})});
+const api::VolumeGroupConfig kBusNavVolumeGroup =
+        createVolumeGroup("navvoicecommand", kOnSourceVolumeActivation,
+                          {createRoutes(kBusNavDevice, {"oem_voice_command"})});
+const api::VolumeGroupConfig kBusCallVolumeGroup =
+        createVolumeGroup("telringvol", kOnPlayVolumeActivation,
+                          {createRoutes(kBusPhoneDevice, {"oem_call", "oem_call_ring"})});
+const api::VolumeGroupConfig kBusSysVolumeGroup = createVolumeGroup(
+        "systemalarm", kOnSourceVolumeActivation,
+        {createRoutes(kBusSysDevice, {"oem_alarm", "oem_system_sound", "oem_notification"})});
+
+const api::AudioZoneConfig kAllBusZoneConfig = createAudioZoneConfig(
+        "primary zone config 0", kDefaultAudioConfigFading,
+        {kBusMediaVolumeGroup, kBusNavVolumeGroup, kBusCallVolumeGroup, kBusSysVolumeGroup}, true);
+const api::AudioZoneConfig kBTMediaZoneConfig = createAudioZoneConfig(
+        "primary zone BT media", kDynamicDeviceAudioConfigFading,
+        {kBTMediaVolumeGroup, kBusNavVolumeGroup, kBusCallVolumeGroup, kBusSysVolumeGroup});
+const api::AudioZoneConfig kUsBMediaZoneConfig = createAudioZoneConfig(
+        "primary zone USB media", kDynamicDeviceAudioConfigFading,
+        {kUSBMediaVolumeGroup, kBusNavVolumeGroup, kBusCallVolumeGroup, kBusSysVolumeGroup});
+
+const std::unordered_map<std::string, api::AudioZoneConfig> kConfigNameToZoneConfig = {
+        {kAllBusZoneConfig.name, kAllBusZoneConfig},
+        {kBTMediaZoneConfig.name, kBTMediaZoneConfig},
+        {kUsBMediaZoneConfig.name, kUsBMediaZoneConfig},
+};
+
+const api::AudioZoneConfig kDriverZoneConfig = createAudioZoneConfig(
+        "driver zone config 0", kDefaultAudioConfigFading,
+        {kBusMediaVolumeGroup, kBusNavVolumeGroup, kBusCallVolumeGroup, kBusSysVolumeGroup}, true);
+
+const api::AudioZone kDriverZone =
+        createAudioZone("driver zone", static_cast<int>(AudioHalProductStrategy::ZoneId::DEFAULT),
+                        kSimpleCarAudioConfigurationContext, {kDriverZoneConfig});
+
+const api::AudioZoneFadeConfiguration kZoneAudioConfigFading = createAudioZoneFadeConfiguration(
+        kRelaxedFading,
+        {createTransientFadeConfiguration(kDisabledFading, {AudioUsage::EMERGENCY})});
+
+const AudioPort kBusFrontDevice = createAudioPort("BUS_FRONT", AudioDeviceType::OUT_BUS);
+const api::VolumeGroupConfig kFrontVolumeGroup = createVolumeGroup(
+        "entertainment", kOnBootVolumeActivation,
+        {createRoutes(kBusFrontDevice,
+                      {"oem_music", "oem_voice_command", "oem_call", "oem_call_ring", "oem_alarm",
+                       "oem_system_sound", "oem_notification"})});
+const api::AudioZoneConfig kFrontZoneConfig = createAudioZoneConfig(
+        "front passenger config 0", kZoneAudioConfigFading, {kFrontVolumeGroup}, true);
+const api::AudioZone kFrontZone = createAudioZone(
+        "front passenger zone", static_cast<int>(AudioHalProductStrategy::ZoneId::DEFAULT) + 1,
+        kSimpleCarAudioConfigurationContext, {kFrontZoneConfig});
+
+const AudioPort kBusRearDevice = createAudioPort("BUS_REAR", AudioDeviceType::OUT_BUS);
+const api::VolumeGroupConfig kRearVolumeGroup =
+        createVolumeGroup("entertainment", kOnBootVolumeActivation,
+                          {createRoutes(kBusRearDevice, {"oem_music", "oem_voice_command",
+                                                         "oem_call", "oem_call_ring", "oem_alarm",
+                                                         "oem_system_sound", "oem_notification"})});
+const api::AudioZoneConfig kRearZoneConfig = createAudioZoneConfig(
+        "rear seat config 0", kZoneAudioConfigFading, {kRearVolumeGroup}, true);
+const api::AudioZone kRearZone = createAudioZone(
+        "rear seat zone", static_cast<int>(AudioHalProductStrategy::ZoneId::DEFAULT) + 2,
+        kSimpleCarAudioConfigurationContext, {kRearZoneConfig});
+
+std::vector<api::AudioZone> kMultiZones = {kDriverZone, kFrontZone, kRearZone};
+
+void expectSameFadeConfiguration(const api::AudioFadeConfiguration& actual,
+                                 const api::AudioFadeConfiguration& expected,
+                                 const std::string& configName) {
+    EXPECT_EQ(actual.name, expected.name) << "Audio fade configuration for config " << configName;
+    const std::string fadeConfigInfo =
+            "fade config " + actual.name + " in config name " + configName;
+    EXPECT_EQ(actual.fadeState, expected.fadeState)
+            << "Audio fade config state for " << fadeConfigInfo;
+    EXPECT_EQ(actual.fadeInDurationMs, expected.fadeInDurationMs)
+            << "Audio fade in duration for " << fadeConfigInfo;
+    EXPECT_EQ(actual.fadeOutDurationMs, expected.fadeOutDurationMs)
+            << "Audio fade out duration for " << fadeConfigInfo;
+    EXPECT_EQ(actual.fadeInDelayedForOffendersMs, expected.fadeInDelayedForOffendersMs)
+            << "Audio fade in delayed for offenders duration for " << fadeConfigInfo;
+    EXPECT_THAT(actual.fadeableUsages, UnorderedElementsAreArray(expected.fadeableUsages))
+            << "Fadeable usages for " << fadeConfigInfo;
+    EXPECT_TRUE(actual.unfadeableContentTypes.has_value() ==
+                expected.unfadeableContentTypes.has_value())
+            << "Optional unfadeable for " << fadeConfigInfo;
+    if (actual.unfadeableContentTypes.has_value() && expected.unfadeableContentTypes.has_value()) {
+        EXPECT_THAT(actual.unfadeableContentTypes.value(),
+                    UnorderedElementsAreArray(expected.unfadeableContentTypes.value()))
+                << "Unfadeable content type for " << fadeConfigInfo;
+    }
+    EXPECT_THAT(actual.unfadableAudioAttributes,
+                UnorderedElementsAreArray(expected.unfadableAudioAttributes))
+            << "Unfadeable audio attributes type for " << fadeConfigInfo;
+    EXPECT_THAT(actual.fadeOutConfigurations,
+                UnorderedElementsAreArray(expected.fadeOutConfigurations))
+            << "Fade-out configurations for " << fadeConfigInfo;
+    EXPECT_THAT(actual.fadeInConfigurations,
+                UnorderedElementsAreArray(expected.fadeInConfigurations))
+            << "Fade-in configurations for " << fadeConfigInfo;
+}
+
+void expectSameAudioZoneFadeConfiguration(
+        const std::optional<api::AudioZoneFadeConfiguration>& actual,
+        const std::optional<api::AudioZoneFadeConfiguration>& expected,
+        const std::string& configName) {
+    if (!actual.has_value() || !expected.has_value()) {
+        EXPECT_EQ(actual.has_value(), expected.has_value())
+                << "Audio zone config " << configName << " fade configuration missing";
+        return;
+    }
+    const api::AudioZoneFadeConfiguration& actualConfig = actual.value();
+    const api::AudioZoneFadeConfiguration& expectedConfig = expected.value();
+    expectSameFadeConfiguration(actualConfig.defaultConfiguration,
+                                expectedConfig.defaultConfiguration, configName);
+    EXPECT_THAT(actualConfig.transientConfiguration,
+                UnorderedElementsAreArray(expectedConfig.transientConfiguration))
+            << "Transient fade configuration for config " << configName;
+}
+
+void expectSameAudioZoneConfiguration(const api::AudioZoneConfig& actual,
+                                      const api::AudioZoneConfig& expected) {
+    EXPECT_EQ(actual.isDefault, expected.isDefault)
+            << "Zone default's status do not match for config " << actual.name;
+    EXPECT_THAT(actual.volumeGroups, UnorderedElementsAreArray(expected.volumeGroups))
+            << "Volume groups for config " << actual.name;
+    expectSameAudioZoneFadeConfiguration(actual.fadeConfiguration, expected.fadeConfiguration,
+                                         actual.name);
+}
+
+class CarAudioConfigurationTest : public testing::Test {
+  protected:
+    void SetUp() override;
+    void TearDown() override;
+
+    std::unique_ptr<converter::CarAudioConfigurationXmlConverter> converter;
+
+  protected:
+    virtual std::string getCarAudioConfiguration() = 0;
+    virtual std::string getCarFadeConfiguration() = 0;
+};
+
+void CarAudioConfigurationTest::SetUp() {
+    converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+            getTestFilePath(getCarAudioConfiguration()),
+            getTestFilePath(getCarFadeConfiguration()));
+}
+
+void CarAudioConfigurationTest::TearDown() {
+    converter.reset();
+}
+
+class SimpleCarAudioConfigurationTest : public CarAudioConfigurationTest {
+    virtual std::string getCarAudioConfiguration() { return "simple_car_audio_configuration.xml"; }
+
+    virtual std::string getCarFadeConfiguration() { return "car_audio_fade_configuration.xml"; }
+};
+
+TEST_F(SimpleCarAudioConfigurationTest, TestLoadSimpleConfiguration) {
+    EXPECT_EQ(converter->getErrors(), "");
+
+    const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+    EXPECT_EQ(audioDeviceConfigs.routingConfig,
+              api::RoutingDeviceConfiguration::DYNAMIC_AUDIO_ROUTING);
+    EXPECT_FALSE(audioDeviceConfigs.useCoreAudioVolume);
+    EXPECT_TRUE(audioDeviceConfigs.useHalDuckingSignals);
+    EXPECT_TRUE(audioDeviceConfigs.useCarVolumeGroupMuting);
+
+    const auto& mirroringDevices = converter->getOutputMirroringDevices();
+
+    EXPECT_EQ(mirroringDevices.size(), 2) << "Mirroring device size";
+    for (const auto& mirroringDevice : mirroringDevices) {
+        const auto& it =
+                std::find(kMirroringDevices.begin(), kMirroringDevices.end(), mirroringDevice);
+        EXPECT_TRUE(it != kMirroringDevices.end())
+                << "Mirroring device not found " << mirroringDevice.toString();
+    }
+
+    const auto zones = converter->getAudioZones();
+    EXPECT_EQ(zones.size(), 1);
+
+    const auto& zone = zones.front();
+    EXPECT_EQ(zone.id, static_cast<int>(AudioHalProductStrategy::ZoneId::DEFAULT));
+    EXPECT_EQ(zone.occupantZoneId, 0);
+    EXPECT_EQ(zone.name, "primary zone");
+
+    EXPECT_EQ(zone.audioZoneContext.audioContextInfos.size(),
+              kSimpleCarAudioConfigurationContext.size());
+    for (const auto& info : zone.audioZoneContext.audioContextInfos) {
+        const auto iterator = std::find(kSimpleCarAudioConfigurationContext.begin(),
+                                        kSimpleCarAudioConfigurationContext.end(), info);
+        EXPECT_TRUE(iterator != kSimpleCarAudioConfigurationContext.end())
+                << "Context name " << info.toString() << kMusicContextInfo.toString();
+    }
+
+    for (const auto& config : zone.audioZoneConfigs) {
+        const auto& iterator = kConfigNameToZoneConfig.find(config.name);
+        EXPECT_TRUE(iterator != kConfigNameToZoneConfig.end())
+                << "Zone config not found " << config.name;
+        expectSameAudioZoneConfiguration(config, iterator->second);
+    }
+
+    const auto& inputDevices = zone.inputAudioDevices;
+    EXPECT_EQ(inputDevices.size(), 3) << "Input devices";
+    for (const auto& inputDevice : inputDevices) {
+        const auto& it = std::find(kInputDevices.begin(), kInputDevices.end(), inputDevice);
+        EXPECT_TRUE(it != kInputDevices.end())
+                << "Input device " << inputDevice.toString() << " not found";
+    }
+}
+
+class TypeDeviceCarAudioConfigurationTest : public CarAudioConfigurationTest {
+    virtual std::string getCarAudioConfiguration() {
+        return "simple_car_audio_configuration_with_device_type.xml";
+    }
+
+    virtual std::string getCarFadeConfiguration() { return "car_audio_fade_configuration.xml"; }
+};
+
+TEST_F(TypeDeviceCarAudioConfigurationTest, TestLoadConfigurationWithDeviceType) {
+    EXPECT_EQ(converter->getErrors(), "");
+
+    const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+    EXPECT_EQ(audioDeviceConfigs.routingConfig,
+              api::RoutingDeviceConfiguration::DYNAMIC_AUDIO_ROUTING);
+    EXPECT_FALSE(audioDeviceConfigs.useCoreAudioVolume);
+    EXPECT_TRUE(audioDeviceConfigs.useHalDuckingSignals);
+    EXPECT_TRUE(audioDeviceConfigs.useCarVolumeGroupMuting);
+
+    const auto& mirroringDevices = converter->getOutputMirroringDevices();
+
+    EXPECT_EQ(mirroringDevices.size(), 2) << "Mirroring device size";
+    for (const auto& mirroringDevice : mirroringDevices) {
+        const auto& it =
+                std::find(kMirroringDevices.begin(), kMirroringDevices.end(), mirroringDevice);
+        EXPECT_TRUE(it != kMirroringDevices.end())
+                << "Mirroring device not found " << mirroringDevice.toString();
+    }
+
+    const auto zones = converter->getAudioZones();
+    EXPECT_EQ(zones.size(), 1);
+
+    const auto& zone = zones.front();
+    EXPECT_EQ(zone.id, static_cast<int>(AudioHalProductStrategy::ZoneId::DEFAULT));
+    EXPECT_EQ(zone.occupantZoneId, 0);
+    EXPECT_EQ(zone.name, "primary zone");
+
+    EXPECT_EQ(zone.audioZoneContext.audioContextInfos.size(),
+              kSimpleCarAudioConfigurationContext.size());
+    for (const auto& info : zone.audioZoneContext.audioContextInfos) {
+        const auto iterator = std::find(kSimpleCarAudioConfigurationContext.begin(),
+                                        kSimpleCarAudioConfigurationContext.end(), info);
+        EXPECT_TRUE(iterator != kSimpleCarAudioConfigurationContext.end())
+                << "Context name " << info.toString() << kMusicContextInfo.toString();
+    }
+
+    for (const auto& config : zone.audioZoneConfigs) {
+        const auto& iterator = kConfigNameToZoneConfig.find(config.name);
+        EXPECT_TRUE(iterator != kConfigNameToZoneConfig.end())
+                << "Zone config not found " << config.name;
+        expectSameAudioZoneConfiguration(config, iterator->second);
+    }
+
+    const auto& inputDevices = zone.inputAudioDevices;
+    EXPECT_EQ(inputDevices.size(), 3) << "Input devices";
+    for (const auto& inputDevice : inputDevices) {
+        const auto& it = std::find(kInputDevices.begin(), kInputDevices.end(), inputDevice);
+        EXPECT_TRUE(it != kInputDevices.end())
+                << "Input device " << inputDevice.toString() << " not found";
+    }
+}
+
+class CarAudioConfigurationWithDefaultContextTest : public CarAudioConfigurationTest {
+    virtual std::string getCarAudioConfiguration() {
+        return "car_audio_configuration_with_default_context.xml";
+    }
+
+    virtual std::string getCarFadeConfiguration() { return ""; }
+};
+
+TEST_F(CarAudioConfigurationWithDefaultContextTest, TestLoadConfiguration) {
+    EXPECT_EQ(converter->getErrors(), "");
+    const auto& zones = converter->getAudioZones();
+    EXPECT_EQ(zones.size(), 1) << "Default audio context zones";
+    const auto& zone = zones.front();
+    const auto& context = zone.audioZoneContext;
+    EXPECT_THAT(context.audioContextInfos,
+                UnorderedElementsAreArray(kDefaultCarAudioConfigurationContext))
+            << "Default audio contexts";
+}
+
+class MultiZoneCarAudioConfigurationTest : public CarAudioConfigurationTest {
+    std::string getCarAudioConfiguration() override {
+        return "multi_zone_car_audio_configuration.xml";
+    }
+
+    std::string getCarFadeConfiguration() override { return "car_audio_fade_configuration.xml"; }
+};
+
+TEST_F(MultiZoneCarAudioConfigurationTest, TestLoadMultiZoneConfiguration) {
+    EXPECT_EQ(converter->getErrors(), "");
+
+    const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+    EXPECT_EQ(audioDeviceConfigs.routingConfig,
+              api::RoutingDeviceConfiguration::CONFIGURABLE_AUDIO_ENGINE_ROUTING);
+    EXPECT_TRUE(audioDeviceConfigs.useCoreAudioVolume);
+    EXPECT_FALSE(audioDeviceConfigs.useHalDuckingSignals);
+    EXPECT_FALSE(audioDeviceConfigs.useCarVolumeGroupMuting);
+
+    const auto& mirroringDevices = converter->getOutputMirroringDevices();
+
+    EXPECT_THAT(mirroringDevices, UnorderedElementsAreArray(kMultiZoneMirroringDevices));
+
+    const auto zones = converter->getAudioZones();
+    EXPECT_THAT(zones, UnorderedElementsAreArray(kMultiZones));
+}
+
+class MalformedCarAudioConfigurationTest : public testing::Test {
+  protected:
+    void TearDown() override;
+
+    std::unique_ptr<converter::CarAudioConfigurationXmlConverter> converter;
+};
+
+void MalformedCarAudioConfigurationTest::TearDown() {
+    converter.reset();
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadEmptyConfiguration) {
+    converter =
+            std::make_unique<converter::CarAudioConfigurationXmlConverter>(getTestFilePath(""), "");
+    EXPECT_THAT(converter->getErrors(), ContainsRegex("Configuration file .+ is not readable"))
+            << "Empty configuration file";
+
+    const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+    EXPECT_EQ(audioDeviceConfigs.routingConfig,
+              api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+            << "Default configuration for empty file";
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadNonExistingConfiguration) {
+    converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+            getTestFilePath("non_existing_file.xml"), "");
+    EXPECT_THAT(converter->getErrors(), ContainsRegex("Configuration file .+ is not readable"))
+            << "Empty configuration file";
+
+    const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+    EXPECT_EQ(audioDeviceConfigs.routingConfig,
+              api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+            << "Default configuration for empty file";
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadMalforedConfiguration) {
+    converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+            getTestFilePath("car_audio_configuration_without_configuration.xml"), "");
+    EXPECT_THAT(converter->getErrors(),
+                ContainsRegex("Configuration file .+ does not have any configurations"))
+            << "Configuration file without configurations";
+
+    const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+    EXPECT_EQ(audioDeviceConfigs.routingConfig,
+              api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+            << "Default configuration for malformed file";
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadConfigurationWithoutZones) {
+    converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+            getTestFilePath("car_audio_configuration_without_audio_zone.xml"), "");
+    EXPECT_THAT(converter->getErrors(), ContainsRegex("Audio zones not found in file"))
+            << "Configuration file without zones";
+
+    const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+    EXPECT_EQ(audioDeviceConfigs.routingConfig,
+              api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+            << "Default configuration for file without zones";
+}
+
+TEST_F(MalformedCarAudioConfigurationTest, TestLoadConfigurationWithMissingZones) {
+    converter = std::make_unique<converter::CarAudioConfigurationXmlConverter>(
+            getTestFilePath("car_audio_configuration_with_missing_zones.xml"), "");
+    EXPECT_THAT(converter->getErrors(), ContainsRegex("Error parsing audio zone"))
+            << "Configuration file with missing zones";
+
+    const auto audioDeviceConfigs = converter->getAudioDeviceConfiguration();
+    EXPECT_EQ(audioDeviceConfigs.routingConfig,
+              api::RoutingDeviceConfiguration::DEFAULT_AUDIO_ROUTING)
+            << "Default configuration for file with missing zones";
+}
+
+}  // namespace
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_default_context.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_default_context.xml
new file mode 100644
index 0000000..80cb5cd
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_default_context.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<carAudioConfiguration version="4">
+    <zones>
+        <zone name="primary zone" isPrimary="true">
+            <zoneConfigs>
+                <zoneConfig name="primary zone config" isDefault="true">
+                    <volumeGroups>
+                        <group name="entertainment" >
+                            <device address="BUS00_MEDIA">
+                                <context context="MUSIC"/>
+                            </device>
+                        </group>
+                        <group name="navvoicecommand" >
+                            <device address="BUS02_NAV_GUIDANCE">
+                                <context context="NAVIGATION"/>
+                                <context context="VOICE_COMMAND"/>
+                            </device>
+                        </group>
+                        <group name="telringvol" >
+                            <device address="BUS03_PHONE">
+                                <context context="CALL"/>
+                                <context context="CALL_RING"/>
+                            </device>
+                        </group>
+                        <group name="alarm" >
+                            <device address="BUS01_NOTIFICATION">
+                                <context context="ALARM"/>
+                                <context context="NOTIFICATION"/>
+                            </device>
+                        </group>
+                        <group name="system" >
+                            <device address="BUS05_SYSTEM">
+                                <context context="SYSTEM_SOUND"/>
+                                <context context="EMERGENCY"/>
+                                <context context="SAFETY"/>
+                                <context context="VEHICLE_STATUS"/>
+                                <context context="ANNOUNCEMENT"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                </zoneConfig>
+            </zoneConfigs>
+        </zone>
+    </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_missing_zones.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_missing_zones.xml
new file mode 100644
index 0000000..a5880b3
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_with_missing_zones.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<carAudioConfiguration version="4">
+    <deviceConfigurations>
+        <deviceConfiguration name="useHalDuckingSignals" value="true" />
+        <deviceConfiguration name="useCoreAudioRouting" value="false" />
+        <deviceConfiguration name="useCoreAudioVolume" value="false" />
+        <deviceConfiguration name="useCarVolumeGroupMuting" value="true" />
+    </deviceConfigurations>
+    <oemContexts>
+        <oemContext name="oem_context">
+            <audioAttributes>
+                <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+                    contentType="AUDIO_CONTENT_TYPE_SPEECH"
+                    tags="oem=extension_8675309" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_music">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_MEDIA" />
+                <usage value="AUDIO_USAGE_GAME" />
+                <usage value="AUDIO_USAGE_UNKNOWN" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_notification">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION" />
+                <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_voice_command">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANT" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call_ring">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_alarm">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ALARM" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_system_sound">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                <usage value="AUDIO_USAGE_EMERGENCY" />
+                <usage value="AUDIO_USAGE_SAFETY" />
+                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+            </audioAttributes>
+        </oemContext>
+    </oemContexts>
+    <activationVolumeConfigs>
+        <activationVolumeConfig name="on_boot_config">
+            <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_source_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_playback_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+        </activationVolumeConfig>
+    </activationVolumeConfigs>
+    <mirroringDevices>
+        <mirroringDevice address="mirror_bus_device_1"/>
+        <mirroringDevice address="mirror_bus_device_2"/>
+    </mirroringDevices>
+    <zones>
+    </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_audio_zone.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_audio_zone.xml
new file mode 100644
index 0000000..1e50e6e
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_audio_zone.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<carAudioConfiguration version="4">
+    <deviceConfigurations>
+        <deviceConfiguration name="useHalDuckingSignals" value="true" />
+        <deviceConfiguration name="useCoreAudioRouting" value="false" />
+        <deviceConfiguration name="useCoreAudioVolume" value="false" />
+        <deviceConfiguration name="useCarVolumeGroupMuting" value="true" />
+    </deviceConfigurations>
+    <oemContexts>
+        <oemContext name="oem_context">
+            <audioAttributes>
+                <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+                    contentType="AUDIO_CONTENT_TYPE_SPEECH"
+                    tags="oem=extension_8675309" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_music">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_MEDIA" />
+                <usage value="AUDIO_USAGE_GAME" />
+                <usage value="AUDIO_USAGE_UNKNOWN" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_notification">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION" />
+                <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_voice_command">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANT" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call_ring">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_alarm">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ALARM" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_system_sound">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                <usage value="AUDIO_USAGE_EMERGENCY" />
+                <usage value="AUDIO_USAGE_SAFETY" />
+                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+            </audioAttributes>
+        </oemContext>
+    </oemContexts>
+    <activationVolumeConfigs>
+        <activationVolumeConfig name="on_boot_config">
+            <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_source_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_playback_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+        </activationVolumeConfig>
+    </activationVolumeConfigs>
+    <mirroringDevices>
+        <mirroringDevice address="mirror_bus_device_1"/>
+        <mirroringDevice address="mirror_bus_device_2"/>
+    </mirroringDevices>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_configuration.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_configuration.xml
new file mode 100644
index 0000000..4f50ca2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_configuration_without_configuration.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<nonCarAudioConfiguration version="4">
+
+</nonCarAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/car_audio_fade_configuration.xml b/automotive/audiocontrol/aidl/default/converter/test/car_audio_fade_configuration.xml
new file mode 100644
index 0000000..249f915
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/car_audio_fade_configuration.xml
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<carAudioFadeConfiguration version="1">
+    <configs>
+        <config name="relaxed fading" defaultFadeOutDurationInMillis="800" defaultFadeInDurationInMillis="500" defaultFadeInDelayForOffenders="10000" >
+            <fadeState value="1" />
+            <fadeableUsages>
+                <usage value="AUDIO_USAGE_MEDIA" />
+                <usage value="AUDIO_USAGE_GAME" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                <usage value="AUDIO_USAGE_ASSISTANT" />
+                <usage value="AUDIO_USAGE_NOTIFICATION" />
+                <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+            </fadeableUsages>
+            <unfadeableContentTypes>
+                <contentType value="AUDIO_CONTENT_TYPE_SPEECH" />
+                <contentType value="AUDIO_CONTENT_TYPE_SONIFICATION" />
+            </unfadeableContentTypes>
+            <unfadeableAudioAttributes>
+                <audioAttributes>
+                    <audioAttribute usage="AUDIO_USAGE_MEDIA" tags="oem_specific_tag1" />
+                </audioAttributes>
+            </unfadeableAudioAttributes>
+            <fadeOutConfigurations>
+                <fadeConfiguration fadeDurationMillis="500">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_MEDIA" />
+                        <usage value="AUDIO_USAGE_GAME" />
+                        <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_specific_tag2" />
+                    </audioAttributes>
+                </fadeConfiguration>
+                <fadeConfiguration fadeDurationMillis="800">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                        <usage value="AUDIO_USAGE_ASSISTANT" />
+                        <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+                    </audioAttributes>
+                </fadeConfiguration>
+            </fadeOutConfigurations>
+            <fadeInConfigurations>
+                <fadeConfiguration fadeDurationMillis="1000">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_MEDIA" />
+                        <usage value="AUDIO_USAGE_GAME" />
+                        <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_specific_tag2" />
+                    </audioAttributes>
+                </fadeConfiguration>
+                <fadeConfiguration fadeDurationMillis="800">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                        <usage value="AUDIO_USAGE_ASSISTANT" />
+                        <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+                    </audioAttributes>
+                </fadeConfiguration>
+            </fadeInConfigurations>
+        </config>
+        <config name="aggressive fading">
+            <fadeState value="FADE_STATE_ENABLED_DEFAULT" />
+            <fadeableUsages>
+                <usage value="AUDIO_USAGE_MEDIA" />
+                <usage value="AUDIO_USAGE_GAME" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                <usage value="AUDIO_USAGE_ASSISTANT" />
+                <usage value="AUDIO_USAGE_NOTIFICATION" />
+                <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+            </fadeableUsages>
+            <unfadeableContentTypes>
+                <contentType value="AUDIO_CONTENT_TYPE_SPEECH" />
+                <contentType value="AUDIO_CONTENT_TYPE_MUSIC" />
+            </unfadeableContentTypes>
+            <unfadeableAudioAttributes>
+                <audioAttributes>
+                    <audioAttribute usage="AUDIO_USAGE_MEDIA" tags="oem_specific_tag1" />
+                    <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_projection_service" />
+                </audioAttributes>
+            </unfadeableAudioAttributes>
+            <fadeOutConfigurations>
+                <fadeConfiguration fadeDurationMillis="150">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_MEDIA" />
+                        <usage value="AUDIO_USAGE_GAME" />
+                    </audioAttributes>
+                </fadeConfiguration>
+                <fadeConfiguration fadeDurationMillis="400">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                        <usage value="AUDIO_USAGE_ASSISTANT" />
+                        <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+                    </audioAttributes>
+                </fadeConfiguration>
+            </fadeOutConfigurations>
+            <fadeInConfigurations>
+                <fadeConfiguration fadeDurationMillis="300">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_MEDIA" />
+                        <usage value="AUDIO_USAGE_GAME" />
+                    </audioAttributes>
+                </fadeConfiguration>
+                <fadeConfiguration fadeDurationMillis="550">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                        <usage value="AUDIO_USAGE_ASSISTANT" />
+                        <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+                    </audioAttributes>
+                </fadeConfiguration>
+            </fadeInConfigurations>
+        </config>
+        <config name="disabled fading">
+            <fadeState value="0" />
+        </config>
+        <config name="dynamic fading" defaultFadeOutDurationInMillis="800" defaultFadeInDurationInMillis="500">
+            <fadeState value="1" />
+            <fadeableUsages>
+                <usage value="AUDIO_USAGE_MEDIA" />
+                <usage value="AUDIO_USAGE_GAME" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                <usage value="AUDIO_USAGE_ASSISTANT" />
+                <usage value="AUDIO_USAGE_NOTIFICATION" />
+                <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+            </fadeableUsages>
+            <unfadeableContentTypes>
+                <contentType value="AUDIO_CONTENT_TYPE_SPEECH" />
+                <contentType value="AUDIO_CONTENT_TYPE_MOVIE" />
+            </unfadeableContentTypes>
+            <unfadeableAudioAttributes>
+                <audioAttributes>
+                    <audioAttribute usage="AUDIO_USAGE_MEDIA" tags="oem_specific_tag1" />
+                </audioAttributes>
+            </unfadeableAudioAttributes>
+            <fadeOutConfigurations>
+                <fadeConfiguration fadeDurationMillis="500">
+                    <audioAttributes>
+                        <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_specific_tag2" />
+                    </audioAttributes>
+                </fadeConfiguration>
+                <fadeConfiguration fadeDurationMillis="800">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                        <usage value="AUDIO_USAGE_ASSISTANT" />
+                        <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+                    </audioAttributes>
+                </fadeConfiguration>
+            </fadeOutConfigurations>
+            <fadeInConfigurations>
+                <fadeConfiguration fadeDurationMillis="1000">
+                    <audioAttributes>
+                        <audioAttribute usage="AUDIO_USAGE_ASSISTANT" tags="oem_specific_tag2" />
+                    </audioAttributes>
+                </fadeConfiguration>
+                <fadeConfiguration fadeDurationMillis="800">
+                    <audioAttributes>
+                        <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                        <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+                        <usage value="AUDIO_USAGE_ASSISTANT" />
+                        <usage value="AUDIO_USAGE_ANNOUNCEMENT"/>
+                    </audioAttributes>
+                </fadeConfiguration>
+            </fadeInConfigurations>
+        </config>
+    </configs>
+</carAudioFadeConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/multi_zone_car_audio_configuration.xml b/automotive/audiocontrol/aidl/default/converter/test/multi_zone_car_audio_configuration.xml
new file mode 100644
index 0000000..f0c9081
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/multi_zone_car_audio_configuration.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<carAudioConfiguration version="4">
+    <deviceConfigurations>
+        <deviceConfiguration name="useHalDuckingSignals" value="false" />
+        <deviceConfiguration name="useCoreAudioRouting" value="true" />
+        <deviceConfiguration name="useCoreAudioVolume" value="true" />
+        <deviceConfiguration name="useCarVolumeGroupMuting" value="false" />
+    </deviceConfigurations>
+    <oemContexts>
+        <oemContext name="oem_context">
+            <audioAttributes>
+                <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+                    contentType="AUDIO_CONTENT_TYPE_SPEECH"
+                    tags="oem=extension_8675309" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_music">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_MEDIA" />
+                <usage value="AUDIO_USAGE_GAME" />
+                <usage value="AUDIO_USAGE_UNKNOWN" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_notification">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION" />
+                <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_voice_command">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANT" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call_ring">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_alarm">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ALARM" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_system_sound">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                <usage value="AUDIO_USAGE_EMERGENCY" />
+                <usage value="AUDIO_USAGE_SAFETY" />
+                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+            </audioAttributes>
+        </oemContext>
+    </oemContexts>
+    <activationVolumeConfigs>
+        <activationVolumeConfig name="on_boot_config">
+            <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_source_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_playback_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+        </activationVolumeConfig>
+    </activationVolumeConfigs>
+    <mirroringDevices>
+        <mirroringDevice address="mirror_bus_device_three"/>
+        <mirroringDevice address="mirror_bus_device_four"/>
+    </mirroringDevices>
+    <zones>
+        <zone name="driver zone" isPrimary="true" audioZoneId="0" occupantZoneId="0">
+            <zoneConfigs>
+                <zoneConfig name="driver zone config 0" isDefault="true">
+                    <volumeGroups>
+                        <group name="entertainment" activationConfig="on_boot_config">
+                            <device address="BUS00_MEDIA">
+                                <context context="oem_music"/>
+                            </device>
+                        </group>
+                        <group name="navvoicecommand" activationConfig="on_source_changed_config">
+                            <device address="BUS02_NAV_GUIDANCE">
+                                <context context="oem_voice_command"/>
+                            </device>
+                        </group>
+                        <group name="telringvol" activationConfig="on_playback_changed_config">
+                            <device address="BUS03_PHONE">
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                            </device>
+                        </group>
+                        <group name="systemalarm" activationConfig="on_source_changed_config">
+                            <device address="BUS01_SYS_NOTIFICATION">
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="relaxed fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="aggressive fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+                                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                                <usage value="AUDIO_USAGE_SAFETY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+            </zoneConfigs>
+        </zone>
+        <zone name="front passenger zone" audioZoneId="1" occupantZoneId="1">
+            <zoneConfigs>
+                <zoneConfig name="front passenger config 0" isDefault="true">
+                    <volumeGroups>
+                        <group  name="entertainment" activationConfig="on_boot_config">
+                            <device address="BUS_FRONT">
+                                <context context="oem_music"/>
+                                <context context="oem_voice_command"/>
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="relaxed fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+            </zoneConfigs>
+        </zone>
+        <zone name="rear seat zone" audioZoneId="2" occupantZoneId="2">
+            <zoneConfigs>
+                <zoneConfig name="rear seat config 0" isDefault="true">
+                    <volumeGroups>
+                        <group  name="entertainment" activationConfig="on_boot_config">
+                            <device address="BUS_REAR">
+                                <context context="oem_music"/>
+                                <context context="oem_voice_command"/>
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="relaxed fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+            </zoneConfigs>
+        </zone>
+    </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration.xml b/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration.xml
new file mode 100644
index 0000000..a6f5317
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration.xml
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<carAudioConfiguration version="4">
+    <deviceConfigurations>
+        <deviceConfiguration name="useHalDuckingSignals" value="true" />
+        <deviceConfiguration name="useCoreAudioRouting" value="false" />
+        <deviceConfiguration name="useCoreAudioVolume" value="false" />
+        <deviceConfiguration name="useCarVolumeGroupMuting" value="true" />
+    </deviceConfigurations>
+    <oemContexts>
+        <oemContext name="oem_context">
+            <audioAttributes>
+                <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+                    contentType="AUDIO_CONTENT_TYPE_SPEECH"
+                    tags="oem=extension_8675309" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_music">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_MEDIA" />
+                <usage value="AUDIO_USAGE_GAME" />
+                <usage value="AUDIO_USAGE_UNKNOWN" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_notification">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION" />
+                <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_voice_command">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANT" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call_ring">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_alarm">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ALARM" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_system_sound">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                <usage value="AUDIO_USAGE_EMERGENCY" />
+                <usage value="AUDIO_USAGE_SAFETY" />
+                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+            </audioAttributes>
+        </oemContext>
+    </oemContexts>
+    <activationVolumeConfigs>
+        <activationVolumeConfig name="on_boot_config">
+            <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_source_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_playback_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+        </activationVolumeConfig>
+    </activationVolumeConfigs>
+    <mirroringDevices>
+        <mirroringDevice address="mirror_bus_device_1"/>
+        <mirroringDevice address="mirror_bus_device_2"/>
+    </mirroringDevices>
+    <zones>
+        <zone name="primary zone" isPrimary="true" audioZoneId="0" occupantZoneId="0">
+            <inputDevices>
+                <inputDevice address="fm_tuner" type="AUDIO_DEVICE_IN_FM_TUNER" />
+                <inputDevice address="built_in_mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" />
+                <inputDevice address="in_bus_device" type="AUDIO_DEVICE_IN_BUS" />
+            </inputDevices>
+            <zoneConfigs>
+                <zoneConfig name="primary zone config 0" isDefault="true">
+                    <volumeGroups>
+                        <group name="entertainment" activationConfig="on_boot_config">
+                            <device address="BUS00_MEDIA">
+                                <context context="oem_music"/>
+                            </device>
+                        </group>
+                        <group name="navvoicecommand" activationConfig="on_source_changed_config">
+                            <device address="BUS02_NAV_GUIDANCE">
+                                <context context="oem_voice_command"/>
+                            </device>
+                        </group>
+                        <group name="telringvol" activationConfig="on_playback_changed_config">
+                            <device address="BUS03_PHONE">
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                            </device>
+                        </group>
+                        <group name="systemalarm" activationConfig="on_source_changed_config">
+                            <device address="BUS01_SYS_NOTIFICATION">
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="relaxed fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="aggressive fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+                                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                                <usage value="AUDIO_USAGE_SAFETY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+                <zoneConfig name="primary zone BT media">
+                    <volumeGroups>
+                        <group name="entertainment" activationConfig="on_boot_config">
+                            <device type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" address="temp">
+                                <context context="oem_music"/>
+                            </device>
+                        </group>
+                        <group name="navvoicecommand" activationConfig="on_source_changed_config">
+                            <device address="BUS02_NAV_GUIDANCE">
+                                <context context="oem_voice_command"/>
+                            </device>
+                        </group>
+                        <group name="telringvol" activationConfig="on_playback_changed_config">
+                            <device address="BUS03_PHONE">
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                            </device>
+                        </group>
+                        <group name="systemalarm" activationConfig="on_source_changed_config">
+                            <device address="BUS01_SYS_NOTIFICATION">
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="dynamic fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="aggressive fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+                                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                                <usage value="AUDIO_USAGE_SAFETY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+                <zoneConfig name="primary zone USB media">
+                    <volumeGroups>
+                        <group name="entertainment" activationConfig="on_boot_config">
+                            <device type="AUDIO_DEVICE_OUT_USB_HEADSET">
+                                <context context="oem_music"/>
+                            </device>
+                        </group>
+                        <group name="navvoicecommand" activationConfig="on_source_changed_config">
+                            <device address="BUS02_NAV_GUIDANCE">
+                                <context context="oem_voice_command"/>
+                            </device>
+                        </group>
+                        <group name="telringvol" activationConfig="on_playback_changed_config">
+                            <device address="BUS03_PHONE">
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                            </device>
+                        </group>
+                        <group name="systemalarm" activationConfig="on_source_changed_config">
+                            <device address="BUS01_SYS_NOTIFICATION">
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="dynamic fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="aggressive fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+                                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                                <usage value="AUDIO_USAGE_SAFETY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+            </zoneConfigs>
+        </zone>
+    </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration_with_device_type.xml b/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration_with_device_type.xml
new file mode 100644
index 0000000..eec9db9
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/converter/test/simple_car_audio_configuration_with_device_type.xml
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<carAudioConfiguration version="4">
+    <deviceConfigurations>
+        <deviceConfiguration name="useHalDuckingSignals" value="true" />
+        <deviceConfiguration name="useCoreAudioRouting" value="false" />
+        <deviceConfiguration name="useCoreAudioVolume" value="false" />
+        <deviceConfiguration name="useCarVolumeGroupMuting" value="true" />
+    </deviceConfigurations>
+    <oemContexts>
+        <oemContext name="oem_context">
+            <audioAttributes>
+                <audioAttribute usage="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"
+                    contentType="AUDIO_CONTENT_TYPE_SPEECH"
+                    tags="oem=extension_8675309" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_music">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_MEDIA" />
+                <usage value="AUDIO_USAGE_GAME" />
+                <usage value="AUDIO_USAGE_UNKNOWN" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_notification">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION" />
+                <usage value="AUDIO_USAGE_NOTIFICATION_EVENT" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_voice_command">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANT" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY" />
+                <usage value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                <usage value="AUDIO_USAGE_CALL_ASSISTANT" />
+                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_call_ring">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_alarm">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ALARM" />
+            </audioAttributes>
+        </oemContext>
+        <oemContext name="oem_system_sound">
+            <audioAttributes>
+                <usage value="AUDIO_USAGE_ASSISTANCE_SONIFICATION" />
+                <usage value="AUDIO_USAGE_EMERGENCY" />
+                <usage value="AUDIO_USAGE_SAFETY" />
+                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+            </audioAttributes>
+        </oemContext>
+    </oemContexts>
+    <activationVolumeConfigs>
+        <activationVolumeConfig name="on_boot_config">
+            <activationVolumeConfigEntry maxActivationVolumePercentage="80" invocationType="onBoot" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_source_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="20" maxActivationVolumePercentage="80" invocationType="onSourceChanged" />
+        </activationVolumeConfig>
+        <activationVolumeConfig name="on_playback_changed_config">
+            <activationVolumeConfigEntry minActivationVolumePercentage="10" maxActivationVolumePercentage="90" invocationType="onPlaybackChanged" />
+        </activationVolumeConfig>
+    </activationVolumeConfigs>
+    <mirroringDevices>
+        <mirroringDevice address="mirror_bus_device_1"/>
+        <mirroringDevice address="mirror_bus_device_2"/>
+    </mirroringDevices>
+    <zones>
+        <zone name="primary zone" isPrimary="true" audioZoneId="0" occupantZoneId="0">
+            <inputDevices>
+                <inputDevice address="fm_tuner" type="AUDIO_DEVICE_IN_FM_TUNER" />
+                <inputDevice address="built_in_mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" />
+                <inputDevice address="in_bus_device" type="AUDIO_DEVICE_IN_BUS" />
+            </inputDevices>
+            <zoneConfigs>
+                <zoneConfig name="primary zone config 0" isDefault="true">
+                    <volumeGroups>
+                        <group name="entertainment" activationConfig="on_boot_config">
+                            <device address="BUS00_MEDIA">
+                                <context context="oem_music"/>
+                            </device>
+                        </group>
+                        <group name="navvoicecommand" activationConfig="on_source_changed_config">
+                            <device address="BUS02_NAV_GUIDANCE">
+                                <context context="oem_voice_command"/>
+                            </device>
+                        </group>
+                        <group name="telringvol" activationConfig="on_playback_changed_config">
+                            <device address="BUS03_PHONE">
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                            </device>
+                        </group>
+                        <group name="systemalarm" activationConfig="on_source_changed_config">
+                            <device address="BUS01_SYS_NOTIFICATION">
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="relaxed fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="aggressive fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+                                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                                <usage value="AUDIO_USAGE_SAFETY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+                <zoneConfig name="primary zone BT media">
+                    <volumeGroups>
+                        <group name="entertainment" activationConfig="on_boot_config">
+                            <device type="TYPE_BLUETOOTH_A2DP" address="temp">
+                                <context context="oem_music"/>
+                            </device>
+                        </group>
+                        <group name="navvoicecommand" activationConfig="on_source_changed_config">
+                            <device address="BUS02_NAV_GUIDANCE">
+                                <context context="oem_voice_command"/>
+                            </device>
+                        </group>
+                        <group name="telringvol" activationConfig="on_playback_changed_config">
+                            <device address="BUS03_PHONE">
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                            </device>
+                        </group>
+                        <group name="systemalarm" activationConfig="on_source_changed_config">
+                            <device address="BUS01_SYS_NOTIFICATION">
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="dynamic fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="aggressive fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+                                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                                <usage value="AUDIO_USAGE_SAFETY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+                <zoneConfig name="primary zone USB media">
+                    <volumeGroups>
+                        <group name="entertainment" activationConfig="on_boot_config">
+                            <device type="TYPE_USB_HEADSET">
+                                <context context="oem_music"/>
+                            </device>
+                        </group>
+                        <group name="navvoicecommand" activationConfig="on_source_changed_config">
+                            <device address="BUS02_NAV_GUIDANCE">
+                                <context context="oem_voice_command"/>
+                            </device>
+                        </group>
+                        <group name="telringvol" activationConfig="on_playback_changed_config">
+                            <device address="BUS03_PHONE">
+                                <context context="oem_call"/>
+                                <context context="oem_call_ring"/>
+                            </device>
+                        </group>
+                        <group name="systemalarm" activationConfig="on_source_changed_config">
+                            <device address="BUS01_SYS_NOTIFICATION">
+                                <context context="oem_alarm"/>
+                                <context context="oem_system_sound"/>
+                                <context context="oem_notification"/>
+                            </device>
+                        </group>
+                    </volumeGroups>
+                    <applyFadeConfigs>
+                        <fadeConfig name="dynamic fading" isDefault="true">
+                        </fadeConfig>
+                        <fadeConfig name="aggressive fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_VOICE_COMMUNICATION" />
+                                <usage value="AUDIO_USAGE_ANNOUNCEMENT" />
+                                <usage value="AUDIO_USAGE_VEHICLE_STATUS" />
+                                <usage value="AUDIO_USAGE_SAFETY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                        <fadeConfig name="disabled fading">
+                            <audioAttributes>
+                                <usage value="AUDIO_USAGE_EMERGENCY" />
+                            </audioAttributes>
+                        </fadeConfig>
+                    </applyFadeConfigs>
+                </zoneConfig>
+            </zoneConfigs>
+        </zone>
+    </zones>
+</carAudioConfiguration>
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/Android.bp b/automotive/audiocontrol/aidl/default/loaders/config/Android.bp
new file mode 100644
index 0000000..0d5eb81
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+    name: "car_audio_configuration_xsd",
+    srcs: ["car_audio_configuration.xsd"],
+    package_name: "android.hardware.automotive.audiocontrol",
+    nullability: true,
+}
+
+cc_defaults {
+    name: "car.audio.configuration.xsd.default",
+    static_libs: [
+        "libxml2",
+    ],
+    generated_sources: [
+        "car_audio_configuration_xsd",
+    ],
+    generated_headers: [
+        "car_audio_configuration_xsd",
+    ],
+    header_libs: [
+        "libxsdc-utils",
+    ],
+}
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/api/current.txt b/automotive/audiocontrol/aidl/default/loaders/config/api/current.txt
new file mode 100644
index 0000000..c87b8c6
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/api/current.txt
@@ -0,0 +1,331 @@
+// Signature format: 2.0
+package android.hardware.automotive.audiocontrol {
+
+  public enum ActivationType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.hardware.automotive.audiocontrol.ActivationType onBoot;
+    enum_constant public static final android.hardware.automotive.audiocontrol.ActivationType onPlaybackChanged;
+    enum_constant public static final android.hardware.automotive.audiocontrol.ActivationType onSourceChanged;
+  }
+
+  public class ActivationVolumeConfigEntryType {
+    ctor public ActivationVolumeConfigEntryType();
+    method @Nullable public android.hardware.automotive.audiocontrol.ActivationType getInvocationType();
+    method @Nullable public String getMaxActivationVolumePercentage();
+    method @Nullable public String getMinActivationVolumePercentage();
+    method public void setInvocationType(@Nullable android.hardware.automotive.audiocontrol.ActivationType);
+    method public void setMaxActivationVolumePercentage(@Nullable String);
+    method public void setMinActivationVolumePercentage(@Nullable String);
+  }
+
+  public class ActivationVolumeConfigType {
+    ctor public ActivationVolumeConfigType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ActivationVolumeConfigEntryType> getActivationVolumeConfigEntry();
+    method @Nullable public String getName();
+    method public void setName(@Nullable String);
+  }
+
+  public class ActivationVolumeConfigsType {
+    ctor public ActivationVolumeConfigsType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ActivationVolumeConfigType> getActivationVolumeConfig();
+  }
+
+  public class ApplyFadeConfigType {
+    ctor public ApplyFadeConfigType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.AudioAttributeUsagesType> getAudioAttributes();
+    method @Nullable public boolean getIsDefault();
+    method @Nullable public String getName();
+    method public void setIsDefault(@Nullable boolean);
+    method public void setName(@Nullable String);
+  }
+
+  public class ApplyFadeConfigsType {
+    ctor public ApplyFadeConfigsType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ApplyFadeConfigType> getFadeConfig();
+  }
+
+  public class AttributesType {
+    ctor public AttributesType();
+    method @Nullable public android.hardware.automotive.audiocontrol.ContentTypeEnum getContentType();
+    method @Nullable public String getTags();
+    method @Nullable public android.hardware.automotive.audiocontrol.UsageEnumType getUsage();
+    method public void setContentType(@Nullable android.hardware.automotive.audiocontrol.ContentTypeEnum);
+    method public void setTags(@Nullable String);
+    method public void setUsage(@Nullable android.hardware.automotive.audiocontrol.UsageEnumType);
+  }
+
+  public class AudioAttributeUsagesType {
+    ctor public AudioAttributeUsagesType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.UsageType> getUsage();
+  }
+
+  public class AudioAttributesUsagesType {
+    ctor public AudioAttributesUsagesType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.AttributesType> getAudioAttribute_optional();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.UsageType> getUsage_optional();
+  }
+
+  public class CarAudioConfigurationType {
+    ctor public CarAudioConfigurationType();
+    method @Nullable public android.hardware.automotive.audiocontrol.ActivationVolumeConfigsType getActivationVolumeConfigs();
+    method @Nullable public android.hardware.automotive.audiocontrol.DeviceConfigurationsType getDeviceConfigurations();
+    method @Nullable public android.hardware.automotive.audiocontrol.MirroringDevicesType getMirroringDevices();
+    method @Nullable public android.hardware.automotive.audiocontrol.OemContextsType getOemContexts();
+    method @Nullable public String getVersion();
+    method @Nullable public android.hardware.automotive.audiocontrol.ZonesType getZones();
+    method public void setActivationVolumeConfigs(@Nullable android.hardware.automotive.audiocontrol.ActivationVolumeConfigsType);
+    method public void setDeviceConfigurations(@Nullable android.hardware.automotive.audiocontrol.DeviceConfigurationsType);
+    method public void setMirroringDevices(@Nullable android.hardware.automotive.audiocontrol.MirroringDevicesType);
+    method public void setOemContexts(@Nullable android.hardware.automotive.audiocontrol.OemContextsType);
+    method public void setVersion(@Nullable String);
+    method public void setZones(@Nullable android.hardware.automotive.audiocontrol.ZonesType);
+  }
+
+  public class ContentType {
+    ctor public ContentType();
+    method @Nullable public android.hardware.automotive.audiocontrol.ContentTypeEnum getValue();
+    method public void setValue(@Nullable android.hardware.automotive.audiocontrol.ContentTypeEnum);
+  }
+
+  public enum ContentTypeEnum {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_MOVIE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_MUSIC;
+    enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_SONIFICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_SPEECH;
+    enum_constant public static final android.hardware.automotive.audiocontrol.ContentTypeEnum AUDIO_CONTENT_TYPE_UNKNOWN;
+  }
+
+  public class ContextNameType {
+    ctor public ContextNameType();
+    method @Nullable public String getContext();
+    method public void setContext(@Nullable String);
+  }
+
+  public class DeviceConfigurationType {
+    ctor public DeviceConfigurationType();
+    method @Nullable public String getName();
+    method @Nullable public String getValue();
+    method public void setName(@Nullable String);
+    method public void setValue(@Nullable String);
+  }
+
+  public class DeviceConfigurationsType {
+    ctor public DeviceConfigurationsType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.DeviceConfigurationType> getDeviceConfiguration();
+  }
+
+  public class DeviceRoutesType {
+    ctor public DeviceRoutesType();
+    method @Nullable public String getAddress();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ContextNameType> getContext();
+    method @Nullable public android.hardware.automotive.audiocontrol.OutDeviceType getType();
+    method public void setAddress(@Nullable String);
+    method public void setType(@Nullable android.hardware.automotive.audiocontrol.OutDeviceType);
+  }
+
+  public enum InDeviceType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_AMBIENT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_AUX_DIGITAL;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BACK_MIC;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BLUETOOTH_BLE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BUILTIN_MIC;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_BUS;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_COMMUNICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_DEFAULT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_ECHO_REFERENCE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_FM_TUNER;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_HDMI;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_HDMI_ARC;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_IP;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_LINE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_LOOPBACK;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_PROXY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_SPDIF;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_STUB;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_TELEPHONY_RX;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_TV_TUNER;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_USB_ACCESSORY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_USB_DEVICE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_USB_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_VOICE_CALL;
+    enum_constant public static final android.hardware.automotive.audiocontrol.InDeviceType AUDIO_DEVICE_IN_WIRED_HEADSET;
+  }
+
+  public class InputDeviceType {
+    ctor public InputDeviceType();
+    method @Nullable public String getAddress();
+    method @Nullable public android.hardware.automotive.audiocontrol.InDeviceType getType();
+    method public void setAddress(@Nullable String);
+    method public void setType(@Nullable android.hardware.automotive.audiocontrol.InDeviceType);
+  }
+
+  public class InputDevicesType {
+    ctor public InputDevicesType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.InputDeviceType> getInputDevice();
+  }
+
+  public class MirroringDevice {
+    ctor public MirroringDevice();
+    method @Nullable public String getAddress();
+    method public void setAddress(@Nullable String);
+  }
+
+  public class MirroringDevicesType {
+    ctor public MirroringDevicesType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.MirroringDevice> getMirroringDevice();
+  }
+
+  public class OemContextType {
+    ctor public OemContextType();
+    method @Nullable public android.hardware.automotive.audiocontrol.AudioAttributesUsagesType getAudioAttributes();
+    method @Nullable public String getId();
+    method @Nullable public String getName();
+    method public void setAudioAttributes(@Nullable android.hardware.automotive.audiocontrol.AudioAttributesUsagesType);
+    method public void setId(@Nullable String);
+    method public void setName(@Nullable String);
+  }
+
+  public class OemContextsType {
+    ctor public OemContextsType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.OemContextType> getOemContext();
+  }
+
+  public enum OutDeviceType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_AUX_DIGITAL;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_AUX_LINE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLE_BROADCAST;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLE_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLE_SPEAKER;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_BUS;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_DEFAULT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_HDMI;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_HDMI_ARC;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_HDMI_EARC;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_LINE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_SPEAKER;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_SPEAKER_SAFE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_USB_ACCESSORY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_USB_DEVICE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_USB_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType AUDIO_DEVICE_OUT_WIRED_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_AUX_LINE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BLE_BROADCAST;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BLE_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BLE_SPEAKER;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BLUETOOTH_A2DP;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BUILTIN_SPEAKER;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_BUS;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_HDMI;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_USB_ACCESSORY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_USB_DEVICE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_USB_HEADSET;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_WIRED_HEADPHONES;
+    enum_constant public static final android.hardware.automotive.audiocontrol.OutDeviceType TYPE_WIRED_HEADSET;
+  }
+
+  public enum UsageEnumType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ALARM;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ANNOUNCEMENT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_ASSISTANT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_CALL_ASSISTANT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_EMERGENCY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_GAME;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_MEDIA;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_EVENT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_SAFETY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_UNKNOWN;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_VEHICLE_STATUS;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_VIRTUAL_SOURCE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+  }
+
+  public class UsageType {
+    ctor public UsageType();
+    method @Nullable public android.hardware.automotive.audiocontrol.UsageEnumType getValue();
+    method public void setValue(@Nullable android.hardware.automotive.audiocontrol.UsageEnumType);
+  }
+
+  public class VolumeGroupType {
+    ctor public VolumeGroupType();
+    method @Nullable public String getActivationConfig();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.DeviceRoutesType> getDevice();
+    method @Nullable public String getName();
+    method public void setActivationConfig(@Nullable String);
+    method public void setName(@Nullable String);
+  }
+
+  public class VolumeGroupsType {
+    ctor public VolumeGroupsType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.VolumeGroupType> getGroup();
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method @Nullable public static android.hardware.automotive.audiocontrol.CarAudioConfigurationType read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+  public class ZoneConfigType {
+    ctor public ZoneConfigType();
+    method @Nullable public android.hardware.automotive.audiocontrol.ApplyFadeConfigsType getApplyFadeConfigs();
+    method @Nullable public boolean getIsDefault();
+    method @Nullable public String getName();
+    method @Nullable public android.hardware.automotive.audiocontrol.VolumeGroupsType getVolumeGroups();
+    method public void setApplyFadeConfigs(@Nullable android.hardware.automotive.audiocontrol.ApplyFadeConfigsType);
+    method public void setIsDefault(@Nullable boolean);
+    method public void setName(@Nullable String);
+    method public void setVolumeGroups(@Nullable android.hardware.automotive.audiocontrol.VolumeGroupsType);
+  }
+
+  public class ZoneConfigsType {
+    ctor public ZoneConfigsType();
+    method @Nullable public android.hardware.automotive.audiocontrol.ZoneConfigType getZoneConfig();
+    method public void setZoneConfig(@Nullable android.hardware.automotive.audiocontrol.ZoneConfigType);
+  }
+
+  public class ZoneType {
+    ctor public ZoneType();
+    method @Nullable public String getAudioZoneId();
+    method @Nullable public android.hardware.automotive.audiocontrol.InputDevicesType getInputDevices();
+    method @Nullable public boolean getIsPrimary();
+    method @Nullable public String getName();
+    method @Nullable public String getOccupantZoneId();
+    method @Nullable public android.hardware.automotive.audiocontrol.ZoneConfigsType getZoneConfigs();
+    method public void setAudioZoneId(@Nullable String);
+    method public void setInputDevices(@Nullable android.hardware.automotive.audiocontrol.InputDevicesType);
+    method public void setIsPrimary(@Nullable boolean);
+    method public void setName(@Nullable String);
+    method public void setOccupantZoneId(@Nullable String);
+    method public void setZoneConfigs(@Nullable android.hardware.automotive.audiocontrol.ZoneConfigsType);
+  }
+
+  public class ZonesType {
+    ctor public ZonesType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.ZoneType> getZone();
+  }
+
+}
+
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/api/last_current.txt b/automotive/audiocontrol/aidl/default/loaders/config/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/api/last_current.txt
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/api/last_removed.txt b/automotive/audiocontrol/aidl/default/loaders/config/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/api/last_removed.txt
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/api/removed.txt b/automotive/audiocontrol/aidl/default/loaders/config/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/automotive/audiocontrol/aidl/default/loaders/config/car_audio_configuration.xsd b/automotive/audiocontrol/aidl/default/loaders/config/car_audio_configuration.xsd
new file mode 100644
index 0000000..634aeda
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/config/car_audio_configuration.xsd
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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.
+-->
+<xs:schema version="2.0" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="carAudioConfiguration" type="CarAudioConfigurationType" minOccurs="1" maxOccurs="1" />
+    <xs:complexType name="CarAudioConfigurationType">
+        <xs:attribute name="version" type="xs:string" use="required" />
+        <xs:sequence>
+            <xs:element name="mirroringDevices" type="MirroringDevicesType" minOccurs="0" />
+            <xs:element name="deviceConfigurations" type="DeviceConfigurationsType" minOccurs="0" />
+            <xs:element name="oemContexts" type="OemContextsType" />
+            <xs:element name="activationVolumeConfigs" type="ActivationVolumeConfigsType" minOccurs="0" />
+            <xs:element name="zones" type="ZonesType" />
+        </xs:sequence>
+    </xs:complexType>
+    <xs:complexType name="ZonesType">
+        <xs:element name="zone" type="ZoneType" minOccurs="1" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="ActivationVolumeConfigsType">
+        <xs:element name="activationVolumeConfig" type="ActivationVolumeConfigType" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="OemContextsType">
+        <xs:element name="oemContext" type="OemContextType" minOccurs="1" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="DeviceConfigurationsType">
+        <xs:element name="deviceConfiguration" type="DeviceConfigurationType" minOccurs="0" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="ZoneType">
+        <xs:attribute name="name" type="xs:string" />
+        <xs:attribute name="audioZoneId" type="xs:string" use="required" />
+        <xs:attribute name="isPrimary" type="xs:boolean" />
+        <xs:attribute name="occupantZoneId" type="xs:string" />
+        <xs:element name="inputDevices" type="InputDevicesType" />
+        <xs:element name="zoneConfigs" type="ZoneConfigsType" />
+    </xs:complexType>
+    <xs:complexType name="ZoneConfigsType">
+        <xs:element name="zoneConfig" type="ZoneConfigType"/>
+    </xs:complexType>
+    <xs:complexType name="ZoneConfigType">
+        <xs:attribute name="name" type="xs:string" />
+        <xs:attribute name="isDefault" type="xs:boolean" />
+        <xs:element name="volumeGroups" type="VolumeGroupsType" />
+        <xs:element name="applyFadeConfigs" type="ApplyFadeConfigsType" />
+    </xs:complexType>
+    <xs:complexType name="ApplyFadeConfigsType">
+        <xs:element name="fadeConfig" type="ApplyFadeConfigType" minOccurs="0" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="ApplyFadeConfigType">
+        <xs:attribute name="name" type="xs:string" />
+        <xs:attribute name="isDefault" type="xs:boolean" />
+        <xs:element name="audioAttributes" type="AudioAttributeUsagesType" minOccurs="0" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="AudioAttributeUsagesType">
+        <xs:element name="usage" type="UsageType" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="VolumeGroupsType">
+        <xs:element name="group"  type="VolumeGroupType" minOccurs="1" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="VolumeGroupType">
+        <xs:attribute name="name" type="xs:string" />
+        <xs:attribute name="activationConfig" type="xs:string" />
+        <xs:element name="device" type="DeviceRoutesType" minOccurts="1" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="DeviceRoutesType" >
+        <xs:attribute name="address" type="xs:string" />
+        <xs:attribute name="type" type="OutDeviceType" />
+        <xs:element name="context" type="ContextNameType" mixOccurs="1" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="ContextNameType">
+        <xs:attribute name="context" type="xs:string"/>
+    </xs:complexType>
+    <xs:complexType name="OemContextType">
+        <xs:attribute name="name" type="xs:string" />
+        <xs:attribute name="id" type="xs:string" />
+        <xs:element name="audioAttributes" type="AudioAttributesUsagesType" minOccurs="1" maxOccurs="1" />
+    </xs:complexType>
+    <xs:complexType name="AudioAttributesUsagesType" >
+        <xs:choice minOccurs="0" maxOccurs="unbounded" >
+            <xs:element name="audioAttribute" type="AttributesType" />
+            <xs:element name="usage" type="UsageType" />
+        </xs:choice>
+    </xs:complexType>
+    <xs:complexType name="AttributesType">
+        <xs:attribute name="contentType" type="contentTypeEnum" />
+        <xs:attribute name="usage" type="usageEnumType" />
+        <xs:attribute name="tags" type="xs:string" />
+    </xs:complexType>
+    <xs:complexType name="DeviceConfigurationType">
+        <xs:attribute name="name" type="xs:string" />
+        <xs:attribute name="value" type="xs:string" />
+    </xs:complexType>
+    <xs:complexType name="ContentType" >
+        <xs:attribute name="value" type="contentTypeEnum" use="required" />
+    </xs:complexType>
+    <xs:complexType name="UsageType">
+        <xs:attribute name="value" type="usageEnumType" use="required" />
+    </xs:complexType>
+    <xs:simpleType name="contentTypeEnum">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="usageEnumType">
+      <xs:restriction base="xs:string">
+          <xs:enumeration value="AUDIO_USAGE_UNKNOWN"/>
+          <xs:enumeration value="AUDIO_USAGE_MEDIA"/>
+          <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION"/>
+          <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
+          <xs:enumeration value="AUDIO_USAGE_ALARM"/>
+          <xs:enumeration value="AUDIO_USAGE_NOTIFICATION"/>
+          <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+          <!-- Note: the following 3 values were deprecated in Android T (13) SDK -->
+          <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
+          <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
+          <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
+          <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT"/>
+          <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
+          <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+          <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+          <xs:enumeration value="AUDIO_USAGE_GAME"/>
+          <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE"/>
+          <xs:enumeration value="AUDIO_USAGE_ASSISTANT"/>
+          <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT"/>
+          <xs:enumeration value="AUDIO_USAGE_EMERGENCY" />
+          <xs:enumeration value="AUDIO_USAGE_SAFETY" />
+          <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
+          <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+      </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="ActivationVolumeConfigType">
+        <xs:attribute name="name" type="xs:string" />
+        <xs:element name="activationVolumeConfigEntry" type="ActivationVolumeConfigEntryType" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="ActivationVolumeConfigEntryType">
+          <xs:attribute name="maxActivationVolumePercentage" type="xs:string" />
+          <xs:attribute name="minActivationVolumePercentage" type="xs:string" />
+          <xs:attribute name="invocationType" type="ActivationType" />
+    </xs:complexType>
+    <xs:simpleType name="ActivationType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="onBoot"/>
+            <xs:enumeration value="onSourceChanged"/>
+            <xs:enumeration value="onPlaybackChanged"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:simpleType name="OutDeviceType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_WIRED_HEADPHONE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_EARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_DIGITAL"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_ACCESSORY"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_DEVICE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_HDMI_ARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_AUX_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_SPEAKER_SAFE"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BUS"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_USB_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_SPEAKER"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_BLE_BROADCAST"/>
+            <xs:enumeration value="AUDIO_DEVICE_OUT_DEFAULT"/>
+            <!-- Added to support legacy files -->
+            <xs:enumeration value="TYPE_BUILTIN_SPEAKER"/>
+            <xs:enumeration value="TYPE_WIRED_HEADSET"/>
+            <xs:enumeration value="TYPE_WIRED_HEADPHONES"/>
+            <xs:enumeration value="TYPE_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="TYPE_HDMI"/>
+            <xs:enumeration value="TYPE_USB_ACCESSORY"/>
+            <xs:enumeration value="TYPE_USB_DEVICE"/>
+            <xs:enumeration value="TYPE_USB_HEADSET"/>
+            <xs:enumeration value="TYPE_AUX_LINE"/>
+            <xs:enumeration value="TYPE_BUS"/>
+            <xs:enumeration value="TYPE_BLE_HEADSET"/>
+            <xs:enumeration value="TYPE_BLE_SPEAKER"/>
+            <xs:enumeration value="TYPE_BLE_BROADCAST"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="MirroringDevicesType">
+        <xs:element name="mirroringDevice" type="MirroringDevice" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="MirroringDevice">
+        <xs:attribute name="address" type="xs:string" />
+    </xs:complexType>
+    <xs:complexType name="InputDevicesType">
+        <xs:element name="inputDevice" type="InputDeviceType" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="InputDeviceType">
+        <xs:attribute name="address" type="xs:string" />
+        <xs:attribute name="type" type="InDeviceType" />
+    </xs:complexType>
+    <xs:simpleType name="InDeviceType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_DEVICE_IN_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_AMBIENT"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BUILTIN_MIC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_WIRED_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_AUX_DIGITAL"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_VOICE_CALL"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_TELEPHONY_RX"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BACK_MIC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_REMOTE_SUBMIX"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_ACCESSORY"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_DEVICE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_FM_TUNER"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_TV_TUNER"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_LINE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_SPDIF"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_A2DP"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_LOOPBACK"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_IP"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BUS"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_PROXY"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_USB_HEADSET"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_BLUETOOTH_BLE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_HDMI_ARC"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_ECHO_REFERENCE"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_DEFAULT"/>
+            <xs:enumeration value="AUDIO_DEVICE_IN_STUB"/>
+        </xs:restriction>
+    </xs:simpleType>
+</xs:schema>
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/Android.bp b/automotive/audiocontrol/aidl/default/loaders/fade/Android.bp
new file mode 100644
index 0000000..3dbc2f1
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+xsd_config {
+    name: "car_fade_audio_configuration_xsd",
+    srcs: ["car_fade_audio_configuration.xsd"],
+    package_name: "android.hardware.automotive.audiocontrol.fade",
+    nullability: true,
+}
+
+cc_defaults {
+    name: "car.fade.configuration.xsd.default",
+    static_libs: [
+        "libxml2",
+    ],
+    generated_sources: [
+        "car_fade_audio_configuration_xsd",
+    ],
+    generated_headers: [
+        "car_fade_audio_configuration_xsd",
+    ],
+    header_libs: [
+        "libxsdc-utils",
+    ],
+}
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/api/current.txt b/automotive/audiocontrol/aidl/default/loaders/fade/api/current.txt
new file mode 100644
index 0000000..f40f1be
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/api/current.txt
@@ -0,0 +1,160 @@
+// Signature format: 2.0
+package android.hardware.automotive.audiocontrol.fade {
+
+  public class AttributesType {
+    ctor public AttributesType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.ContentTypeEnum getContentType();
+    method @Nullable public String getTags();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.UsageEnumType getUsage();
+    method public void setContentType(@Nullable android.hardware.automotive.audiocontrol.fade.ContentTypeEnum);
+    method public void setTags(@Nullable String);
+    method public void setUsage(@Nullable android.hardware.automotive.audiocontrol.fade.UsageEnumType);
+  }
+
+  public class AudioAttributesUsagesType {
+    ctor public AudioAttributesUsagesType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.AttributesType> getAudioAttribute_optional();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.UsageType> getUsage_optional();
+  }
+
+  public class CarAudioFadeConfigurationType {
+    ctor public CarAudioFadeConfigurationType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeConfigurationConfigs getConfigs();
+    method public void setConfigs(@Nullable android.hardware.automotive.audiocontrol.fade.FadeConfigurationConfigs);
+  }
+
+  public class ContentType {
+    ctor public ContentType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.ContentTypeEnum getValue();
+    method public void setValue(@Nullable android.hardware.automotive.audiocontrol.fade.ContentTypeEnum);
+  }
+
+  public enum ContentTypeEnum {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_MOVIE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_MUSIC;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_SONIFICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_SPEECH;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.ContentTypeEnum AUDIO_CONTENT_TYPE_UNKNOWN;
+  }
+
+  public class FadeConfigurationConfig {
+    ctor public FadeConfigurationConfig();
+    method @Nullable public String getDefaultFadeInDelayForOffenders();
+    method @Nullable public String getDefaultFadeInDurationInMillis();
+    method @Nullable public String getDefaultFadeOutDurationInMillis();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeInConfigurationsType getFadeInConfigurations();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeOutConfigurationsType getFadeOutConfigurations();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeStateType getFadeState();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeableUsagesType getFadeableUsages();
+    method @Nullable public String getName();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.UnfadeableAudioAttributesType getUnfadeableAudioAttributes();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.UnfadeableContentTypesType getUnfadeableContentTypes();
+    method public void setDefaultFadeInDelayForOffenders(@Nullable String);
+    method public void setDefaultFadeInDurationInMillis(@Nullable String);
+    method public void setDefaultFadeOutDurationInMillis(@Nullable String);
+    method public void setFadeInConfigurations(@Nullable android.hardware.automotive.audiocontrol.fade.FadeInConfigurationsType);
+    method public void setFadeOutConfigurations(@Nullable android.hardware.automotive.audiocontrol.fade.FadeOutConfigurationsType);
+    method public void setFadeState(@Nullable android.hardware.automotive.audiocontrol.fade.FadeStateType);
+    method public void setFadeableUsages(@Nullable android.hardware.automotive.audiocontrol.fade.FadeableUsagesType);
+    method public void setName(@Nullable String);
+    method public void setUnfadeableAudioAttributes(@Nullable android.hardware.automotive.audiocontrol.fade.UnfadeableAudioAttributesType);
+    method public void setUnfadeableContentTypes(@Nullable android.hardware.automotive.audiocontrol.fade.UnfadeableContentTypesType);
+  }
+
+  public class FadeConfigurationConfigs {
+    ctor public FadeConfigurationConfigs();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.FadeConfigurationConfig> getConfig();
+  }
+
+  public class FadeConfigurationType {
+    ctor public FadeConfigurationType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.AudioAttributesUsagesType getAudioAttributes();
+    method @Nullable public String getFadeDurationMillis();
+    method public void setAudioAttributes(@Nullable android.hardware.automotive.audiocontrol.fade.AudioAttributesUsagesType);
+    method public void setFadeDurationMillis(@Nullable String);
+  }
+
+  public class FadeInConfigurationsType {
+    ctor public FadeInConfigurationsType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeConfigurationType getFadeConfiguration();
+    method public void setFadeConfiguration(@Nullable android.hardware.automotive.audiocontrol.fade.FadeConfigurationType);
+  }
+
+  public class FadeOutConfigurationsType {
+    ctor public FadeOutConfigurationsType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeConfigurationType getFadeConfiguration();
+    method public void setFadeConfiguration(@Nullable android.hardware.automotive.audiocontrol.fade.FadeConfigurationType);
+  }
+
+  public enum FadeStateEnumType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.FadeStateEnumType FADE_STATE_DISABLED;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.FadeStateEnumType FADE_STATE_ENABLED_DEFAULT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.FadeStateEnumType _0;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.FadeStateEnumType _1;
+  }
+
+  public class FadeStateType {
+    ctor public FadeStateType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.FadeStateEnumType getValue();
+    method public void setValue(@Nullable android.hardware.automotive.audiocontrol.fade.FadeStateEnumType);
+  }
+
+  public class FadeableUsagesType {
+    ctor public FadeableUsagesType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.UsageType> getUsage();
+  }
+
+  public class UnfadeableAudioAttributesType {
+    ctor public UnfadeableAudioAttributesType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.AudioAttributesUsagesType getAudioAttributes();
+    method public void setAudioAttributes(@Nullable android.hardware.automotive.audiocontrol.fade.AudioAttributesUsagesType);
+  }
+
+  public class UnfadeableContentTypesType {
+    ctor public UnfadeableContentTypesType();
+    method @Nullable public java.util.List<android.hardware.automotive.audiocontrol.fade.ContentType> getContentType();
+  }
+
+  public enum UsageEnumType {
+    method @NonNull public String getRawName();
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ALARM;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ANNOUNCEMENT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ASSISTANCE_SONIFICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_ASSISTANT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_CALL_ASSISTANT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_EMERGENCY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_GAME;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_MEDIA;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_EVENT;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_SAFETY;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_UNKNOWN;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_VEHICLE_STATUS;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_VIRTUAL_SOURCE;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION;
+    enum_constant public static final android.hardware.automotive.audiocontrol.fade.UsageEnumType AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING;
+  }
+
+  public class UsageType {
+    ctor public UsageType();
+    method @Nullable public android.hardware.automotive.audiocontrol.fade.UsageEnumType getValue();
+    method public void setValue(@Nullable android.hardware.automotive.audiocontrol.fade.UsageEnumType);
+  }
+
+  public class XmlParser {
+    ctor public XmlParser();
+    method @Nullable public static android.hardware.automotive.audiocontrol.fade.CarAudioFadeConfigurationType read(@NonNull java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method @Nullable public static String readText(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public static void skip(@NonNull org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+  }
+
+}
+
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/api/last_current.txt b/automotive/audiocontrol/aidl/default/loaders/fade/api/last_current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/api/last_current.txt
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/api/last_removed.txt b/automotive/audiocontrol/aidl/default/loaders/fade/api/last_removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/api/last_removed.txt
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/api/removed.txt b/automotive/audiocontrol/aidl/default/loaders/fade/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/automotive/audiocontrol/aidl/default/loaders/fade/car_fade_audio_configuration.xsd b/automotive/audiocontrol/aidl/default/loaders/fade/car_fade_audio_configuration.xsd
new file mode 100644
index 0000000..051be7e
--- /dev/null
+++ b/automotive/audiocontrol/aidl/default/loaders/fade/car_fade_audio_configuration.xsd
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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.
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" version="2.0">
+    <xs:element name="carAudioFadeConfiguration" type="CarAudioFadeConfigurationType" />
+    <xs:complexType name="CarAudioFadeConfigurationType">
+        <xs:element name="configs" type="FadeConfigurationConfigs" />
+    </xs:complexType>
+    <xs:complexType name="FadeConfigurationConfigs">
+        <xs:element name="config" type="FadeConfigurationConfig" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="FadeConfigurationConfig">
+        <xs:attribute name="name" type="xs:string" />
+        <xs:attribute name="defaultFadeOutDurationInMillis" type="xs:string" />
+        <xs:attribute name="defaultFadeInDurationInMillis" type="xs:string" />
+        <xs:attribute name="defaultFadeInDelayForOffenders" type="xs:string" />
+        <xs:element name="fadeState" type="FadeStateType" />
+        <xs:element name="fadeableUsages" type="FadeableUsagesType" />
+        <xs:element name="unfadeableContentTypes" type="UnfadeableContentTypesType" />
+        <xs:element name="unfadeableAudioAttributes" type="UnfadeableAudioAttributesType" />
+        <xs:element name="fadeOutConfigurations" type="FadeOutConfigurationsType" />
+        <xs:element name="fadeInConfigurations" type="FadeInConfigurationsType" />
+    </xs:complexType>
+    <xs:complexType name="FadeStateType">
+        <xs:attribute name="value" type="fadeStateEnumType" />
+    </xs:complexType>
+    <xs:simpleType name="fadeStateEnumType" >
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="0" />
+            <xs:enumeration value="1" />
+            <xs:enumeration value="FADE_STATE_DISABLED" />
+            <xs:enumeration value="FADE_STATE_ENABLED_DEFAULT" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="FadeableUsagesType">
+        <xs:element name="usage" type="UsageType" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="UsageType">
+        <xs:attribute name="value" type="usageEnumType" />
+    </xs:complexType>
+    <xs:simpleType name="usageEnumType">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_USAGE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_USAGE_MEDIA"/>
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING"/>
+            <xs:enumeration value="AUDIO_USAGE_ALARM"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED"/>
+            <xs:enumeration value="AUDIO_USAGE_NOTIFICATION_EVENT"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANCE_SONIFICATION"/>
+            <xs:enumeration value="AUDIO_USAGE_GAME"/>
+            <xs:enumeration value="AUDIO_USAGE_VIRTUAL_SOURCE"/>
+            <xs:enumeration value="AUDIO_USAGE_ASSISTANT"/>
+            <xs:enumeration value="AUDIO_USAGE_CALL_ASSISTANT"/>
+            <xs:enumeration value="AUDIO_USAGE_EMERGENCY" />
+            <xs:enumeration value="AUDIO_USAGE_SAFETY" />
+            <xs:enumeration value="AUDIO_USAGE_VEHICLE_STATUS" />
+            <xs:enumeration value="AUDIO_USAGE_ANNOUNCEMENT" />
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="UnfadeableContentTypesType">
+        <xs:element name="contentType" type="ContentType" maxOccurs="unbounded" />
+    </xs:complexType>
+    <xs:complexType name="ContentType">
+        <xs:attribute name="value" type="contentTypeEnum" />
+    </xs:complexType>
+    <xs:simpleType name="contentTypeEnum">
+        <xs:restriction base="xs:string">
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_UNKNOWN"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SPEECH"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MUSIC"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_MOVIE"/>
+            <xs:enumeration value="AUDIO_CONTENT_TYPE_SONIFICATION"/>
+        </xs:restriction>
+    </xs:simpleType>
+    <xs:complexType name="UnfadeableAudioAttributesType">
+        <xs:element name="audioAttributes" type="AudioAttributesUsagesType" />
+    </xs:complexType>
+    <xs:complexType name="AudioAttributesUsagesType" >
+        <xs:choice minOccurs="0" maxOccurs="unbounded" >
+            <xs:element name="audioAttribute" type="AttributesType" />
+            <xs:element name="usage" type="UsageType" />
+        </xs:choice>
+    </xs:complexType>
+    <xs:complexType name="AttributesType">
+        <xs:attribute name="contentType" type="contentTypeEnum" />
+        <xs:attribute name="usage" type="usageEnumType" />
+        <xs:attribute name="tags" type="xs:string" />
+    </xs:complexType>
+    <xs:complexType name="FadeOutConfigurationsType">
+        <xs:element name="fadeConfiguration" type="FadeConfigurationType" />
+    </xs:complexType>
+    <xs:complexType name="FadeConfigurationType">
+        <xs:attribute name="fadeDurationMillis" type="xs:string" />
+        <xs:element name="audioAttributes" type="AudioAttributesUsagesType" />
+    </xs:complexType>
+    <xs:complexType name="FadeInConfigurationsType">
+        <xs:element name="fadeConfiguration" type="FadeConfigurationType" />
+    </xs:complexType>
+</xs:schema>
diff --git a/automotive/audiocontrol/aidl/rust_impl/Android.bp b/automotive/audiocontrol/aidl/rust_impl/Android.bp
index 062d989..f9d07b2 100644
--- a/automotive/audiocontrol/aidl/rust_impl/Android.bp
+++ b/automotive/audiocontrol/aidl/rust_impl/Android.bp
@@ -15,7 +15,7 @@
  */
 
 rust_binary {
-    name: "android.hardware.automotive.audiocontrol-V4-rust-service",
+    name: "android.hardware.automotive.audiocontrol-rust-service",
     relative_install_path: "hw",
     vendor: true,
     srcs: ["src/*.rs"],
@@ -23,6 +23,7 @@
     defaults: [
         "latest_android_hardware_automotive_audiocontrol_rust",
         "latest_android_hardware_audio_common_rust",
+        "latest_android_media_audio_common_types_rust",
     ],
     vintf_fragments: ["audiocontrol-rust-service.xml"],
     init_rc: ["audiocontrol-rust-service.rc"],
diff --git a/automotive/audiocontrol/aidl/rust_impl/README.md b/automotive/audiocontrol/aidl/rust_impl/README.md
index ed22356..b68daf3 100644
--- a/automotive/audiocontrol/aidl/rust_impl/README.md
+++ b/automotive/audiocontrol/aidl/rust_impl/README.md
@@ -6,7 +6,7 @@
 This folder contains a skeleton audio control HAL implementation in Rust to
 demonstrate  how vendor may implement a Rust audio control HAL. To run this
 audio control HAL, include
-`android.hardware.automotive.audiocontrol-V4-rust-service` in your image.
+`android.hardware.automotive.audiocontrol-rust-service` in your image.
 
 This implementation returns `StatusCode::UNKNOWN_ERROR` for all operations
 and does not pass VTS/CTS. Vendor must replace the logic in
diff --git a/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs b/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
index ba0ca23..8184c43 100644
--- a/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
+++ b/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
@@ -23,8 +23,15 @@
     IModuleChangeCallback::IModuleChangeCallback,
     MutingInfo::MutingInfo,
     Reasons::Reasons,
+    AudioDeviceConfiguration::AudioDeviceConfiguration,
+    AudioZone::AudioZone
 };
-use android_hardware_audio_common::aidl::android::hardware::audio::common::PlaybackTrackMetadata::PlaybackTrackMetadata;
+use android_hardware_audio_common::aidl::android::hardware::audio::common::{
+    PlaybackTrackMetadata::PlaybackTrackMetadata,
+};
+use android_media_audio_common_types::aidl::android::media::audio::common::{
+    AudioPort::AudioPort,
+};
 use binder::{Interface, Result as BinderResult, StatusCode, Strong};
 
 /// This struct is defined to implement IAudioControl AIDL interface.
@@ -81,4 +88,16 @@
     fn clearModuleChangeCallback(&self) -> BinderResult<()> {
         Err(StatusCode::UNKNOWN_ERROR.into())
     }
+
+    fn getAudioDeviceConfiguration(&self) -> std::result::Result<AudioDeviceConfiguration, binder::Status> {
+        Err(binder::StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getOutputMirroringDevices(&self) -> std::result::Result<std::vec::Vec<AudioPort>, binder::Status> {
+        Err(binder::StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getCarAudioZones(&self) -> std::result::Result<std::vec::Vec<AudioZone>, binder::Status> {
+        Err(binder::StatusCode::UNKNOWN_ERROR.into())
+    }
 }
diff --git a/automotive/audiocontrol/aidl/vts/Android.bp b/automotive/audiocontrol/aidl/vts/Android.bp
index d94ad55..57c6ae4 100644
--- a/automotive/audiocontrol/aidl/vts/Android.bp
+++ b/automotive/audiocontrol/aidl/vts/Android.bp
@@ -22,6 +22,25 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+cc_library {
+    name: "AudioControlHalTestUtils",
+    srcs: [
+        "src/AudioControlTestUtils.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    defaults: [
+        "latest_android_hardware_audio_common_cpp_static",
+        "latest_android_hardware_automotive_audiocontrol_cpp_static",
+        "latest_android_media_audio_common_types_cpp_static",
+    ],
+    shared_libs: [
+        "libbase",
+        "libutils",
+    ],
+}
+
 cc_test {
     name: "VtsAidlHalAudioControlTest",
     defaults: [
@@ -39,9 +58,11 @@
         "libbinder",
         "libbase",
         "libxml2",
+        "libutils",
     ],
     static_libs: [
         "libgmock",
+        "AudioControlHalTestUtils",
     ],
     test_suites: [
         "general-tests",
diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
index 4e7e963..f01f04d 100644
--- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
+++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
@@ -18,32 +18,62 @@
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <gmock/gmock.h>
+#include <utils/String16.h>
+#include <set>
 
 #include <android/hardware/automotive/audiocontrol/BnAudioGainCallback.h>
 #include <android/hardware/automotive/audiocontrol/BnFocusListener.h>
 #include <android/hardware/automotive/audiocontrol/BnModuleChangeCallback.h>
 #include <android/hardware/automotive/audiocontrol/IAudioControl.h>
 #include <android/log.h>
+#include <android/media/audio/common/AudioHalProductStrategy.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
+#include <include/AudioControlTestUtils.h>
 
 using android::ProcessState;
 using android::sp;
 using android::String16;
 using android::binder::Status;
+using android::hardware::automotive::audiocontrol::AudioDeviceConfiguration;
+using android::hardware::automotive::audiocontrol::AudioFadeConfiguration;
 using android::hardware::automotive::audiocontrol::AudioFocusChange;
 using android::hardware::automotive::audiocontrol::AudioGainConfigInfo;
+using android::hardware::automotive::audiocontrol::AudioZone;
+using android::hardware::automotive::audiocontrol::AudioZoneConfig;
+using android::hardware::automotive::audiocontrol::AudioZoneContextInfo;
+using android::hardware::automotive::audiocontrol::AudioZoneFadeConfiguration;
 using android::hardware::automotive::audiocontrol::BnAudioGainCallback;
 using android::hardware::automotive::audiocontrol::BnFocusListener;
 using android::hardware::automotive::audiocontrol::BnModuleChangeCallback;
+using android::hardware::automotive::audiocontrol::DeviceToContextEntry;
 using android::hardware::automotive::audiocontrol::DuckingInfo;
+using android::hardware::automotive::audiocontrol::FadeConfiguration;
 using android::hardware::automotive::audiocontrol::IAudioControl;
 using android::hardware::automotive::audiocontrol::IModuleChangeCallback;
 using android::hardware::automotive::audiocontrol::MutingInfo;
 using android::hardware::automotive::audiocontrol::Reasons;
+using android::hardware::automotive::audiocontrol::VolumeActivationConfiguration;
+using android::hardware::automotive::audiocontrol::VolumeActivationConfigurationEntry;
+using android::hardware::automotive::audiocontrol::VolumeGroupConfig;
+using android::hardware::automotive::audiocontrol::RoutingDeviceConfiguration::
+        CONFIGURABLE_AUDIO_ENGINE_ROUTING;
+using android::hardware::automotive::audiocontrol::RoutingDeviceConfiguration::
+        DEFAULT_AUDIO_ROUTING;
+using android::hardware::automotive::audiocontrol::VolumeActivationConfigurationEntry::
+        DEFAULT_MAX_ACTIVATION_VALUE;
+using android::hardware::automotive::audiocontrol::VolumeActivationConfigurationEntry::
+        DEFAULT_MIN_ACTIVATION_VALUE;
+using android::media::audio::common::AudioHalProductStrategy;
+
 using ::testing::AnyOf;
 using ::testing::Eq;
 
+using ::testing::Not;
+using ::testing::UnorderedElementsAreArray;
+
+using android::internal::ToString;
+
 #include "android_audio_policy_configuration_V7_0.h"
 
 namespace xsd {
@@ -52,11 +82,231 @@
 
 namespace audiohalcommon = android::hardware::audio::common;
 namespace audiomediacommon = android::media::audio::common;
+namespace testutils = android::hardware::audiocontrol::testutils;
 
 namespace {
 constexpr int32_t kAidlVersionThree = 3;
+constexpr int32_t kAidlVersionFive = 5;
+
+bool hasValidVolumeGroupActivation(const VolumeActivationConfiguration& activation,
+                                   std::string& message) {
+    if (activation.volumeActivationEntries.empty()) {
+        message = "Volume group activation must have at least one volume activation entry";
+        return false;
+    }
+    for (const auto& entry : activation.volumeActivationEntries) {
+        int32_t max = entry.maxActivationVolumePercentage;
+        int32_t min = entry.minActivationVolumePercentage;
+        if (min > DEFAULT_MAX_ACTIVATION_VALUE || min < DEFAULT_MIN_ACTIVATION_VALUE) {
+            message = "Invalid minActivationVolumePercentage, must be between " +
+                      std::to_string(DEFAULT_MIN_ACTIVATION_VALUE) + " and " +
+                      std::to_string(DEFAULT_MAX_ACTIVATION_VALUE);
+            return false;
+        }
+        if (max > DEFAULT_MAX_ACTIVATION_VALUE || max < DEFAULT_MIN_ACTIVATION_VALUE) {
+            message = "Invalid maxActivationVolumePercentage, must be between " +
+                      std::to_string(DEFAULT_MIN_ACTIVATION_VALUE) + " and " +
+                      std::to_string(DEFAULT_MAX_ACTIVATION_VALUE);
+            return false;
+        }
+        if (min >= max) {
+            message =
+                    "Invalid maxActivationVolumePercentage and minActivationVolumePercentage "
+                    "combination, minActivationVolumePercentage must be less than "
+                    "maxActivationVolumePercentage";
+            return false;
+        }
+    }
+    return true;
 }
 
+bool hasValidAudioRoute(const DeviceToContextEntry& entry, std::string& message,
+                        std::set<std::string>& groupDevices) {
+    if (entry.contextNames.empty()) {
+        message = " Contexts can not be empty for DeviceToContextEntry";
+        return false;
+    }
+    std::set<std::string> contextInRoute;
+    for (const auto& context : entry.contextNames) {
+        std::string contextString = ToString(context);
+        if (contextInRoute.contains(contextString)) {
+            message = " Context " + contextString + " repeats for DeviceToContextEntry";
+            return false;
+        }
+        groupDevices.insert(contextString);
+    }
+    audiomediacommon::AudioDeviceDescription description;
+    if (!testutils::getAudioPortDeviceDescriptor(entry.device, description)) {
+        message = " DeviceToContextEntry must have a valid device port";
+        return false;
+    }
+    // BUS type also has empty connection
+    // Note: OUT_BUS is also mapped to OUT_DEVICE
+    if (description.type != audiomediacommon::AudioDeviceType::OUT_BUS &&
+        !description.connection.empty()) {
+        return true;
+    }
+    std::string address;
+    if (!testutils::getAddressForAudioPort(entry.device, address) || address.empty()) {
+        message = " Address can not be empty for BUS devices";
+        return false;
+    }
+    if (groupDevices.contains(address)) {
+        message =
+                " Audio device address can not repeat in the same volume group or within audio"
+                " zone configuration if not using configurable audio policy engine";
+        return false;
+    }
+    groupDevices.insert(address);
+    return true;
+}
+
+inline bool hasValidTimeout(int64_t timeout) {
+    return timeout > 0;
+}
+bool hasValidFadeConfiguration(const FadeConfiguration& fadeConfiguration,
+                               const std::string& prefix, std::string& message) {
+    if (!hasValidTimeout(fadeConfiguration.fadeDurationMillis)) {
+        message = prefix + " duration must be greater than 0";
+        return false;
+    }
+    return true;
+}
+bool hadValidAudioFadeConfiguration(const AudioFadeConfiguration& fadeConfiguration,
+                                    std::string& message) {
+    if (!hasValidTimeout(fadeConfiguration.fadeInDurationMs)) {
+        message = "Fade-in duration must be greater than 0";
+        return false;
+    }
+    if (!hasValidTimeout(fadeConfiguration.fadeOutDurationMs)) {
+        message = "Fade-out duration must be greater than 0";
+        return false;
+    }
+    if (!hasValidTimeout(fadeConfiguration.fadeInDelayedForOffendersMs)) {
+        message = "Fade-in delayed for offenders duration must be greater than 0";
+        return false;
+    }
+    for (const auto& fadeOutConfig : fadeConfiguration.fadeOutConfigurations) {
+        if (!hasValidFadeConfiguration(fadeOutConfig, "Fade-out", message)) {
+            return false;
+        }
+    }
+    for (const auto& fadeOutConfig : fadeConfiguration.fadeInConfigurations) {
+        if (!hasValidFadeConfiguration(fadeOutConfig, "Fade-in", message)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void validateVolumeGroupInfo(const AudioZoneConfig& audioZoneConfig,
+                             const VolumeGroupConfig& volumeGroupConfig,
+                             const AudioDeviceConfiguration& deviceConfig,
+                             std::set<std::string>& groupDevices, std::set<int>& groupIds) {
+    std::string zoneConfigName = testutils::toAlphaNumeric(ToString(audioZoneConfig.name));
+    std::string volumeGroupName = testutils::toAlphaNumeric(ToString(volumeGroupConfig.name));
+    std::string volumeGroupInfo =
+            "Audio zone config " + zoneConfigName + " volume group " + volumeGroupName;
+    ALOGI("%s test", volumeGroupInfo.c_str());
+
+    EXPECT_FALSE(volumeGroupConfig.carAudioRoutes.empty())
+            << volumeGroupInfo << " must have at least one audio route";
+    if (deviceConfig.routingConfig == CONFIGURABLE_AUDIO_ENGINE_ROUTING) {
+        EXPECT_FALSE(volumeGroupConfig.name.empty())
+                << volumeGroupInfo << " must have a non-empty volume name";
+    }
+    if (volumeGroupConfig.id != VolumeGroupConfig::UNASSIGNED_ID) {
+        EXPECT_TRUE(groupIds.insert(volumeGroupConfig.id).second)
+                << volumeGroupInfo << " repeats volume group id " << volumeGroupConfig.id;
+    }
+    for (const auto& audioRoute : volumeGroupConfig.carAudioRoutes) {
+        std::string routeMessage;
+        EXPECT_TRUE(hasValidAudioRoute(audioRoute, routeMessage, groupDevices))
+                << volumeGroupInfo << " Volume route message: " << routeMessage;
+    }
+    if (volumeGroupConfig.activationConfiguration.has_value()) {
+        std::string activationMessage;
+        EXPECT_TRUE(hasValidVolumeGroupActivation(volumeGroupConfig.activationConfiguration.value(),
+                                                  activationMessage))
+                << volumeGroupInfo << " Activation message: " << activationMessage;
+    }
+}
+
+void validateAudioZoneFadeConfiguration(const AudioZoneFadeConfiguration& fadeConfiguration) {
+    ALOGI("Fade configuration test");
+    std::set<audiomediacommon::AudioUsage> usages;
+    std::string defaultValidationMessage;
+    EXPECT_TRUE(hadValidAudioFadeConfiguration(fadeConfiguration.defaultConfiguration,
+                                               defaultValidationMessage))
+            << "Default configuration validation failed: " << defaultValidationMessage;
+    for (const auto& entry : fadeConfiguration.transientConfiguration) {
+        ALOGI("Transient fade configuration test");
+        std::string transientFadeConfigurationMessage;
+        EXPECT_TRUE(hadValidAudioFadeConfiguration(entry.transientFadeConfiguration,
+                                                   transientFadeConfigurationMessage))
+                << "Transient fade configuration validation failed: "
+                << transientFadeConfigurationMessage;
+        EXPECT_FALSE(entry.transientUsages.empty())
+                << "Transient fade configuration must have at least one audio usage";
+        for (const auto& usage : entry.transientUsages) {
+            EXPECT_FALSE(usages.contains(usage)) << "Audio usages " << ToString(usage)
+                                                 << " repeat in transient fade configuration";
+        }
+    }
+}
+
+void validateAudioZoneConfiguration(const AudioZone& carAudioZone,
+                                    const AudioZoneConfig& audioZoneConfig,
+                                    const AudioDeviceConfiguration& deviceConfig) {
+    std::string zoneConfigName = testutils::toAlphaNumeric(ToString(audioZoneConfig.name));
+    ALOGI("Zone config name %s test", zoneConfigName.c_str());
+    std::set<std::string> contextInfoNames;
+    EXPECT_FALSE(audioZoneConfig.volumeGroups.empty())
+            << "Volume groups for zone config " << zoneConfigName.c_str();
+    std::set<std::string> groupDevices;
+    std::set<int> groupIds;
+    for (const auto& volumeGroup : audioZoneConfig.volumeGroups) {
+        ALOGI("Zone config name %s volume group test %s", zoneConfigName.c_str(),
+              ToString(volumeGroup.name).c_str());
+        std::vector<std::string> groupContexts =
+                testutils::getContextInfoNamesForVolumeGroup(volumeGroup);
+        for (const auto& context : groupContexts) {
+            EXPECT_FALSE(contextInfoNames.contains(context))
+                    << "Context " << context << " repeats in zone config " << zoneConfigName;
+            contextInfoNames.insert(context);
+        }
+        // Configurable audio policy engine can share devices among volume groups
+        if (deviceConfig.routingConfig == CONFIGURABLE_AUDIO_ENGINE_ROUTING) {
+            groupDevices.clear();
+        }
+        validateVolumeGroupInfo(audioZoneConfig, volumeGroup, deviceConfig, groupDevices, groupIds);
+    }
+    const auto& audioZoneContexts = carAudioZone.audioZoneContext.audioContextInfos;
+    std::map<std::string, AudioZoneContextInfo> infoNameToInfo;
+    std::transform(audioZoneContexts.begin(), audioZoneContexts.end(),
+                   std::inserter(infoNameToInfo, infoNameToInfo.end()),
+                   [&](const AudioZoneContextInfo& context) {
+                       return std::make_pair(ToString(context.name), context);
+                   });
+    std::vector<AudioZoneContextInfo> configContextInfos;
+    for (const auto& contextName : contextInfoNames) {
+        const auto& pair = infoNameToInfo.find(contextName);
+        if (pair == infoNameToInfo.end()) {
+            continue;
+        }
+        configContextInfos.push_back(pair->second);
+    }
+    std::string message;
+    EXPECT_TRUE(testutils::contextInfosContainAllAudioAttributeUsages(configContextInfos, message))
+            << "Config " << zoneConfigName << " message: " << message;
+
+    if (audioZoneConfig.fadeConfiguration.has_value()) {
+        validateAudioZoneFadeConfiguration(audioZoneConfig.fadeConfiguration.value());
+    }
+}
+
+}  // namespace
+
 class AudioControlAidl : public testing::TestWithParam<std::string> {
   public:
     virtual void SetUp() override {
@@ -292,12 +542,193 @@
                 AnyOf(Eq(Status::EX_ILLEGAL_ARGUMENT), Eq(Status::EX_UNSUPPORTED_OPERATION)));
 }
 
+class AudioControlVersionFiveAndAbove : public AudioControlAidl {
+  public:
+    virtual void SetUp() override {
+        AudioControlAidl::SetUp();
+        if (isAidlVersionAtleast(kAidlVersionFive)) {
+            return;
+        }
+        GTEST_SKIP() << " Version is lower than " << std::to_string(kAidlVersionFive);
+    }
+};
+
+class AudioControlWithAudioConfiguration : public AudioControlVersionFiveAndAbove {
+  public:
+    virtual void SetUp() override {
+        AudioControlVersionFiveAndAbove::SetUp();
+
+        if (IsSkipped()) {
+            return;
+        }
+
+        const auto& configStatus =
+                audioControl->getAudioDeviceConfiguration(&audioDeviceConfiguration);
+
+        EXPECT_THAT(configStatus.exceptionCode(),
+                    AnyOf(Eq(Status::EX_NONE), Eq(Status::EX_UNSUPPORTED_OPERATION)));
+        if (!configStatus.isOk()) {
+            GTEST_SKIP() << "Device does not support audio configurations APIs";
+        }
+        ALOGD("Audio device info: %s", audioDeviceConfiguration.toString().c_str());
+    }
+
+    AudioDeviceConfiguration audioDeviceConfiguration;
+};
+
+TEST_P(AudioControlWithAudioConfiguration, DefaultAudioRoutingConfiguration) {
+    if (audioDeviceConfiguration.routingConfig != DEFAULT_AUDIO_ROUTING) {
+        GTEST_SKIP() << "Default audio routing not supported";
+    }
+    std::vector<AudioZone> zones;
+
+    const auto& zoneStatus = audioControl->getCarAudioZones(&zones);
+
+    EXPECT_THAT(zoneStatus.exceptionCode(),
+                AnyOf(Eq(Status::EX_NONE), Eq(Status::EX_UNSUPPORTED_OPERATION)))
+            << "Default routing can be implemented or unsupported";
+    if (!zoneStatus.isOk()) return;
+    EXPECT_TRUE(zones.empty()) << "Zones must be empty for default routing";
+}
+
+class AudioControlWithDynamicConfiguration : public AudioControlWithAudioConfiguration {
+  public:
+    virtual void SetUp() override {
+        AudioControlWithAudioConfiguration::SetUp();
+        if (IsSkipped()) {
+            return;
+        }
+        if (audioDeviceConfiguration.routingConfig == DEFAULT_AUDIO_ROUTING) {
+            GTEST_SKIP() << "Dynamic/core audio routing not supported";
+        }
+        const auto& zoneStatus = audioControl->getCarAudioZones(&audioZones);
+        EXPECT_EQ(zoneStatus.exceptionCode(), Status::EX_NONE)
+                << "Zones API must be supported for core/dynamic routing";
+    }
+
+    std::vector<AudioZone> audioZones;
+};
+
+TEST_P(AudioControlWithDynamicConfiguration, DynamicAudioRoutingConfiguration) {
+    EXPECT_FALSE(audioZones.empty()) << "Zones must not be empty for core/dynamic routing";
+}
+
+class AudioControlWithAudioZoneInfo : public AudioControlWithDynamicConfiguration {
+  public:
+    virtual void SetUp() override {
+        AudioControlWithDynamicConfiguration::SetUp();
+        if (IsSkipped()) {
+            return;
+        }
+        EXPECT_TRUE(!audioZones.empty()) << "Zones must exist for core/dynamic routing";
+    }
+};
+
+TEST_P(AudioControlWithAudioZoneInfo, AudioZonesRequirements) {
+    bool primaryZoneFound = false;
+    std::set<int> zoneIds;
+    std::set<int> occupantIds;
+    std::set<android::String16> zoneNames;
+    std::set<std::string> deviceAddresses;
+    for (const auto& zone : audioZones) {
+        if (zone.id == static_cast<int>(AudioHalProductStrategy::ZoneId::DEFAULT)) {
+            EXPECT_FALSE(primaryZoneFound) << "There can only be one primary zone";
+            primaryZoneFound = true;
+        }
+        EXPECT_FALSE(zoneIds.contains(zone.id)) << "Zone " << std::to_string(zone.id) << " repeats";
+        zoneIds.insert(zone.id);
+        if (!zone.name.empty()) {
+            EXPECT_FALSE(zoneNames.contains(zone.name)) << "Zone " << zone.name << " repeats";
+            zoneNames.insert(zone.name);
+        }
+        if (zone.occupantZoneId != AudioZone::UNASSIGNED_OCCUPANT) {
+            EXPECT_FALSE(occupantIds.contains(zone.occupantZoneId))
+                    << "Occupant zone id " << zone.occupantZoneId << " repeats";
+            occupantIds.insert(zone.occupantZoneId);
+        }
+        const auto& zoneAddresses = testutils::getDeviceAddressesForZone(zone);
+        for (const auto& address : zoneAddresses) {
+            EXPECT_FALSE(deviceAddresses.contains(address))
+                    << "Device address " << address << " in zone " << zone.name << " repeats";
+        }
+        // Add after zone comparison is done since devices may repeat within a zone for different
+        // configurations
+        deviceAddresses.insert(zoneAddresses.begin(), zoneAddresses.end());
+    }
+    EXPECT_TRUE(primaryZoneFound) << "Primary zone must exist";
+}
+
+TEST_P(AudioControlWithAudioZoneInfo, AudioZoneInfoRequirements) {
+    for (const auto& carAudioZone : audioZones) {
+        ALOGI("Zone id %d test", carAudioZone.id);
+        std::string missingContextMessage;
+        EXPECT_TRUE(testutils::contextContainsAllAudioAttributeUsages(carAudioZone.audioZoneContext,
+                                                                      missingContextMessage))
+                << "Audio zone context for zone id " << std::to_string(carAudioZone.id)
+                << missingContextMessage;
+        EXPECT_FALSE(carAudioZone.audioZoneConfigs.empty())
+                << "Audio zone zone id " << std::to_string(carAudioZone.id)
+                << " missing zone configs";
+        std::set<android::String16> configNames;
+        bool defaultConfigFound = false;
+        for (const auto& config : carAudioZone.audioZoneConfigs) {
+            ALOGI("Zone id %d config name %s test", carAudioZone.id, ToString(config.name).c_str());
+            if (config.isDefault) {
+                EXPECT_FALSE(defaultConfigFound)
+                        << "Config name " << config.name
+                        << " repeats default config value in zone id " << carAudioZone.id;
+                defaultConfigFound = true;
+            }
+            EXPECT_FALSE(configNames.contains(config.name))
+                    << "Config name " << config.name << " repeats in " << carAudioZone.id;
+        }
+        EXPECT_TRUE(defaultConfigFound)
+                << "Audio zone " << carAudioZone.id << " must contain default config";
+        std::set<audiomediacommon::AudioPort> inputPorts;
+        ALOGI("Zone id %d input devices test", carAudioZone.id);
+        for (const auto& audioPort : carAudioZone.inputAudioDevices) {
+            std::string address;
+            const auto hasAddress = testutils::getAddressForAudioPort(audioPort, address);
+            EXPECT_FALSE(inputPorts.contains(audioPort))
+                    << "Repeating input device for " << carAudioZone.id << ", device address "
+                    << (hasAddress ? address : "empty address");
+            inputPorts.insert(audioPort);
+        }
+    }
+}
+
+TEST_P(AudioControlWithAudioZoneInfo, AudioZoneConfigInfoRequirements) {
+    for (const auto& carAudioZone : audioZones) {
+        for (const auto& audioZoneConfig : carAudioZone.audioZoneConfigs) {
+            validateAudioZoneConfiguration(carAudioZone, audioZoneConfig, audioDeviceConfiguration);
+        }
+    }
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlAidl);
 INSTANTIATE_TEST_SUITE_P(
         Audiocontrol, AudioControlAidl,
         testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
         android::PrintInstanceNameToString);
 
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlWithAudioConfiguration);
+INSTANTIATE_TEST_SUITE_P(
+        Audiocontrol, AudioControlWithAudioConfiguration,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlWithDynamicConfiguration);
+INSTANTIATE_TEST_SUITE_P(
+        Audiocontrol, AudioControlWithDynamicConfiguration,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
+        android::PrintInstanceNameToString);
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AudioControlWithAudioZoneInfo);
+INSTANTIATE_TEST_SUITE_P(
+        Audiocontrol, AudioControlWithAudioZoneInfo,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IAudioControl::descriptor)),
+        android::PrintInstanceNameToString);
+
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     ProcessState::self()->setThreadPoolMaxThreadCount(1);
diff --git a/automotive/audiocontrol/aidl/vts/include/AudioControlTestUtils.h b/automotive/audiocontrol/aidl/vts/include/AudioControlTestUtils.h
new file mode 100644
index 0000000..46fdce2
--- /dev/null
+++ b/automotive/audiocontrol/aidl/vts/include/AudioControlTestUtils.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#ifndef MAIN8_AUDIOCONTROLTESTUTILS_H
+#define MAIN8_AUDIOCONTROLTESTUTILS_H
+
+#include <android/hardware/automotive/audiocontrol/IAudioControl.h>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace testutils {
+
+std::string toAlphaNumeric(const std::string& info);
+
+bool getAudioPortDeviceDescriptor(
+        const android::media::audio::common::AudioPort& audioPort,
+        android::media::audio::common::AudioDeviceDescription& description);
+
+bool getAddressForAudioPort(const android::media::audio::common::AudioPort& audioPort,
+                            std::string& address);
+
+bool getAddressForAudioDevice(
+        const android::hardware::automotive::audiocontrol::DeviceToContextEntry& device,
+        std::string& address);
+
+std::vector<std::string> getDeviceAddressesForVolumeGroup(
+        const android::hardware::automotive::audiocontrol::VolumeGroupConfig& config);
+
+std::vector<std::string> getDeviceAddressesForZoneConfig(
+        const android::hardware::automotive::audiocontrol::AudioZoneConfig& config);
+
+std::vector<std::string> getDeviceAddressesForZone(
+        const android::hardware::automotive::audiocontrol::AudioZone& config);
+
+bool contextInfosContainAllAudioAttributeUsages(
+        const std::vector<android::hardware::automotive::audiocontrol::AudioZoneContextInfo>& infos,
+        std::string& message);
+
+bool contextContainsAllAudioAttributeUsages(
+        const android::hardware::automotive::audiocontrol::AudioZoneContext& context,
+        std::string& message);
+
+std::vector<std::string> getContextInfoNamesForVolumeGroup(
+        const android::hardware::automotive::audiocontrol::VolumeGroupConfig& group);
+
+}  // namespace testutils
+}  // namespace audiocontrol
+}  // namespace hardware
+}  // namespace android
+
+#endif  // MAIN8_AUDIOCONTROLTESTUTILS_H
diff --git a/automotive/audiocontrol/aidl/vts/src/AudioControlTestUtils.cpp b/automotive/audiocontrol/aidl/vts/src/AudioControlTestUtils.cpp
new file mode 100644
index 0000000..7b7c896
--- /dev/null
+++ b/automotive/audiocontrol/aidl/vts/src/AudioControlTestUtils.cpp
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+#include "../include/AudioControlTestUtils.h"
+
+#include <set>
+
+using android::hardware::automotive::audiocontrol::AudioZone;
+using android::hardware::automotive::audiocontrol::AudioZoneConfig;
+using android::hardware::automotive::audiocontrol::AudioZoneContext;
+using android::hardware::automotive::audiocontrol::AudioZoneContextInfo;
+using android::hardware::automotive::audiocontrol::DeviceToContextEntry;
+using android::hardware::automotive::audiocontrol::VolumeGroupConfig;
+
+namespace audiomediacommon = android::media::audio::common;
+
+namespace android {
+namespace hardware {
+namespace audiocontrol {
+namespace testutils {
+
+std::string toAlphaNumeric(const std::string& info) {
+    std::string name = info;
+    for (size_t i = 0; i < name.size(); i++) {
+        // gtest test names must only contain alphanumeric characters
+        if (!std::isalnum(name[i])) name[i] = '_';
+    }
+
+    return name;
+}
+
+bool getAudioPortDeviceDescriptor(const audiomediacommon::AudioPort& audioPort,
+                                  audiomediacommon::AudioDeviceDescription& description) {
+    if (audioPort.ext.getTag() != audiomediacommon::AudioPortExt::Tag::device) {
+        return false;
+    }
+    const auto& audioDevice =
+            audioPort.ext.get<audiomediacommon::AudioPortExt::Tag::device>().device;
+    description = audioDevice.type;
+    return true;
+}
+
+bool getAddressForAudioPort(const android::media::audio::common::AudioPort& audioPort,
+                            std::string& address) {
+    if (audioPort.ext.getTag() != audiomediacommon::AudioPortExt::Tag::device) {
+        return false;
+    }
+    const auto& audioDevice =
+            audioPort.ext.get<audiomediacommon::AudioPortExt::Tag::device>().device;
+
+    switch (audioDevice.address.getTag()) {
+        case audiomediacommon::AudioDeviceAddress::Tag::id:
+            address = audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::id>();
+            return true;
+        case audiomediacommon::AudioDeviceAddress::Tag::alsa:
+            address = android::internal::ToString(
+                    audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::alsa>());
+            return true;
+        case audiomediacommon::AudioDeviceAddress::Tag::mac:
+            address = android::internal::ToString(
+                    audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::mac>());
+            return true;
+        case audiomediacommon::AudioDeviceAddress::Tag::ipv4:
+            address = android::internal::ToString(
+                    audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::ipv4>());
+            return true;
+        case audiomediacommon::AudioDeviceAddress::Tag::ipv6:
+            address = android::internal::ToString(
+                    audioDevice.address.get<audiomediacommon::AudioDeviceAddress::Tag::ipv6>());
+            return true;
+        default:
+            address = audioDevice.address.toString();
+            return true;
+    }
+}
+
+bool getAddressForAudioDevice(const DeviceToContextEntry& device, std::string& address) {
+    if (device.device.flags.getTag() == audiomediacommon::AudioIoFlags::input ||
+        device.device.ext.getTag() != audiomediacommon::AudioPortExt::Tag::device) {
+        return false;
+    }
+    return getAddressForAudioPort(device.device, address);
+}
+
+std::vector<std::string> getDeviceAddressesForVolumeGroup(const VolumeGroupConfig& config) {
+    std::vector<std::string> addresses;
+    for (const auto& route : config.carAudioRoutes) {
+        std::string address;
+        if (!getAddressForAudioDevice(route, address)) {
+            continue;
+        }
+        addresses.push_back(address);
+    }
+    return addresses;
+}
+
+std::vector<std::string> getDeviceAddressesForZoneConfig(const AudioZoneConfig& config) {
+    std::vector<std::string> addresses;
+    for (const auto& volumeGroup : config.volumeGroups) {
+        const auto groupAddresses = getDeviceAddressesForVolumeGroup(volumeGroup);
+        addresses.insert(addresses.begin(), groupAddresses.begin(), groupAddresses.end());
+    }
+    return addresses;
+}
+
+std::vector<std::string> getDeviceAddressesForZone(const AudioZone& config) {
+    std::vector<std::string> addresses;
+    for (const auto& zoneConfig : config.audioZoneConfigs) {
+        const auto groupAddresses = getDeviceAddressesForZoneConfig(zoneConfig);
+        addresses.insert(addresses.begin(), groupAddresses.begin(), groupAddresses.end());
+    }
+    return addresses;
+}
+
+static void addContextUsages(const AudioZoneContextInfo& info,
+                             std::set<audiomediacommon::AudioUsage>& contextUsages) {
+    for (const auto& audioAttribute : info.audioAttributes) {
+        contextUsages.insert(audioAttribute.usage);
+    }
+}
+
+bool contextInfosContainAllAudioAttributeUsages(const std::vector<AudioZoneContextInfo>& infos,
+                                                std::string& message) {
+    static const std::vector<audiomediacommon::AudioUsage> audioUsages{
+            audiomediacommon::AudioUsage::UNKNOWN,
+            audiomediacommon::AudioUsage::MEDIA,
+            audiomediacommon::AudioUsage::VOICE_COMMUNICATION,
+            audiomediacommon::AudioUsage::VOICE_COMMUNICATION_SIGNALLING,
+            audiomediacommon::AudioUsage::ALARM,
+            audiomediacommon::AudioUsage::NOTIFICATION,
+            audiomediacommon::AudioUsage::NOTIFICATION_TELEPHONY_RINGTONE,
+            audiomediacommon::AudioUsage::NOTIFICATION_EVENT,
+            audiomediacommon::AudioUsage::ASSISTANCE_ACCESSIBILITY,
+            audiomediacommon::AudioUsage::ASSISTANCE_NAVIGATION_GUIDANCE,
+            audiomediacommon::AudioUsage::ASSISTANCE_SONIFICATION,
+            audiomediacommon::AudioUsage::GAME,
+            audiomediacommon::AudioUsage::ASSISTANT,
+            audiomediacommon::AudioUsage::CALL_ASSISTANT,
+            audiomediacommon::AudioUsage::EMERGENCY,
+            audiomediacommon::AudioUsage::SAFETY,
+            audiomediacommon::AudioUsage::VEHICLE_STATUS,
+            audiomediacommon::AudioUsage::ANNOUNCEMENT,
+    };
+
+    std::set<audiomediacommon::AudioUsage> contextUsages;
+    for (const auto& contextInfo : infos) {
+        addContextUsages(contextInfo, contextUsages);
+    }
+
+    bool allUsagesPresent = true;
+    for (const auto& usage : audioUsages) {
+        if (contextUsages.contains(usage)) {
+            continue;
+        }
+        if (message.empty()) {
+            message = " Missing usage(s): ";
+        }
+        message += audiomediacommon::toString(usage) + ", ";
+        allUsagesPresent = false;
+    }
+    return allUsagesPresent;
+}
+
+bool contextContainsAllAudioAttributeUsages(const AudioZoneContext& context, std::string& message) {
+    return contextInfosContainAllAudioAttributeUsages(context.audioContextInfos, message);
+}
+
+std::vector<std::string> getContextInfoNamesForAudioRoute(const DeviceToContextEntry& route) {
+    std::vector<std::string> contextInfoNames;
+    contextInfoNames.reserve(route.contextNames.size());
+    for (const auto& contextName : route.contextNames) {
+        contextInfoNames.push_back(android::internal::ToString(contextName));
+    }
+    return contextInfoNames;
+}
+
+std::vector<std::string> getContextInfoNamesForVolumeGroup(const VolumeGroupConfig& group) {
+    std::vector<std::string> contextInfoNames;
+    for (const auto& route : group.carAudioRoutes) {
+        std::vector<std::string> routeContexts = getContextInfoNamesForAudioRoute(route);
+        contextInfoNames.insert(contextInfoNames.begin(), routeContexts.begin(),
+                                routeContexts.end());
+    }
+    return contextInfoNames;
+}
+
+}  // namespace testutils
+}  // namespace audiocontrol
+}  // namespace hardware
+}  // namespace android
\ No newline at end of file
diff --git a/automotive/can/1.0/default/libnetdevice/Android.bp b/automotive/can/1.0/default/libnetdevice/Android.bp
index b42893e..4131a65 100644
--- a/automotive/can/1.0/default/libnetdevice/Android.bp
+++ b/automotive/can/1.0/default/libnetdevice/Android.bp
@@ -25,6 +25,7 @@
 
 cc_defaults {
     name: "libnetdevice-common",
+    host_supported: true,
     vendor_available: true,
     cflags: [
         "-Wall",
diff --git a/automotive/can/1.0/default/libnetdevice/can.cpp b/automotive/can/1.0/default/libnetdevice/can.cpp
index 2a0545a..9cf0253 100644
--- a/automotive/can/1.0/default/libnetdevice/can.cpp
+++ b/automotive/can/1.0/default/libnetdevice/can.cpp
@@ -33,7 +33,7 @@
 
 static constexpr can_err_mask_t kErrMask = CAN_ERR_MASK;
 
-base::unique_fd socket(const std::string& ifname) {
+base::unique_fd socket(std::string_view ifname) {
     sockaddr_can addr = {};
     addr.can_family = AF_CAN;
     addr.can_ifindex = nametoindex(ifname);
@@ -66,11 +66,11 @@
     return sock;
 }
 
-bool setBitrate(std::string ifname, uint32_t bitrate) {
+bool setBitrate(std::string_view ifname, uint32_t bitrate) {
     can_bittiming bt = {};
     bt.bitrate = bitrate;
 
-    nl::MessageFactory<ifinfomsg> req(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_ACK);
+    nl::MessageFactory<ifinfomsg> req(RTM_NEWLINK);
 
     req->ifi_index = nametoindex(ifname);
     if (req->ifi_index == 0) {
diff --git a/automotive/can/1.0/default/libnetdevice/common.cpp b/automotive/can/1.0/default/libnetdevice/common.cpp
index 28e50af..22add65 100644
--- a/automotive/can/1.0/default/libnetdevice/common.cpp
+++ b/automotive/can/1.0/default/libnetdevice/common.cpp
@@ -22,8 +22,8 @@
 
 namespace android::netdevice {
 
-unsigned int nametoindex(const std::string& ifname) {
-    const auto ifidx = if_nametoindex(ifname.c_str());
+unsigned int nametoindex(std::string_view ifname) {
+    const auto ifidx = if_nametoindex(std::string(ifname).c_str());
     if (ifidx != 0) return ifidx;
 
     if (errno != ENODEV) {
diff --git a/automotive/can/1.0/default/libnetdevice/common.h b/automotive/can/1.0/default/libnetdevice/common.h
index 661e3f8..e73c581 100644
--- a/automotive/can/1.0/default/libnetdevice/common.h
+++ b/automotive/can/1.0/default/libnetdevice/common.h
@@ -32,6 +32,6 @@
  * \param ifname Interface to check
  * \return Interface index, or 0 if the interface doesn't exist
  */
-unsigned int nametoindex(const std::string& ifname);
+unsigned int nametoindex(std::string_view ifname);
 
 }  // namespace android::netdevice
diff --git a/automotive/can/1.0/default/libnetdevice/ethtool.cpp b/automotive/can/1.0/default/libnetdevice/ethtool.cpp
index 762ef5c..b0f88c7 100644
--- a/automotive/can/1.0/default/libnetdevice/ethtool.cpp
+++ b/automotive/can/1.0/default/libnetdevice/ethtool.cpp
@@ -19,27 +19,28 @@
 #include "ifreqs.h"
 
 #include <linux/ethtool.h>
+#include <linux/sockios.h>
 
 namespace android::netdevice::ethtool {
 
-std::optional<uint32_t> getValue(const std::string& ifname, uint32_t command) {
+std::optional<uint32_t> getValue(std::string_view ifname, uint32_t command) {
     struct ethtool_value valueop = {};
     valueop.cmd = command;
 
     auto ifr = ifreqs::fromName(ifname);
-    ifr.ifr_data = &valueop;
+    ifr.ifr_data = reinterpret_cast<caddr_t>(&valueop);
 
     if (!ifreqs::send(SIOCETHTOOL, ifr)) return std::nullopt;
     return valueop.data;
 }
 
-bool setValue(const std::string& ifname, uint32_t command, uint32_t value) {
+bool setValue(std::string_view ifname, uint32_t command, uint32_t value) {
     struct ethtool_value valueop = {};
     valueop.cmd = command;
     valueop.data = value;
 
     auto ifr = ifreqs::fromName(ifname);
-    ifr.ifr_data = &valueop;
+    ifr.ifr_data = reinterpret_cast<caddr_t>(&valueop);
 
     return ifreqs::send(SIOCETHTOOL, ifr);
 }
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
index 8471173..2e6ad41 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.cpp
@@ -21,6 +21,8 @@
 #include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 
+#include <sys/ioctl.h>
+
 #include <map>
 
 namespace android::netdevice::ifreqs {
@@ -68,9 +70,11 @@
     return true;
 }
 
-struct ifreq fromName(const std::string& ifname) {
+struct ifreq fromName(std::string_view ifname) {
     struct ifreq ifr = {};
-    strlcpy(ifr.ifr_name, ifname.c_str(), IF_NAMESIZE);
+    // memcpy: last \0 initialized with ifreq above
+    memcpy(ifr.ifr_name, ifname.data(),
+           std::min(ifname.size(), static_cast<size_t>(IF_NAMESIZE - 1)));
     return ifr;
 }
 
diff --git a/automotive/can/1.0/default/libnetdevice/ifreqs.h b/automotive/can/1.0/default/libnetdevice/ifreqs.h
index aa7030b..f9d8d3b 100644
--- a/automotive/can/1.0/default/libnetdevice/ifreqs.h
+++ b/automotive/can/1.0/default/libnetdevice/ifreqs.h
@@ -52,6 +52,6 @@
  * \param ifname Interface to initialize request with
  * \return Interface request with ifr_name field set to ifname
  */
-struct ifreq fromName(const std::string& ifname);
+struct ifreq fromName(std::string_view ifname);
 
 }  // namespace android::netdevice::ifreqs
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
index 3886acf..6045733 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/can.h
@@ -28,7 +28,7 @@
  * \param ifname Interface to open a socket against
  * \return Socket's FD or -1 in case of failure
  */
-base::unique_fd socket(const std::string& ifname);
+base::unique_fd socket(std::string_view ifname);
 
 /**
  * Sets CAN interface bitrate.
@@ -36,6 +36,6 @@
  * \param ifname Interface for which the bitrate is to be set
  * \return true on success, false on failure
  */
-bool setBitrate(std::string ifname, uint32_t bitrate);
+bool setBitrate(std::string_view ifname, uint32_t bitrate);
 
 }  // namespace android::netdevice::can
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/ethtool.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/ethtool.h
index 26bfdce..416108f 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/ethtool.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/ethtool.h
@@ -29,7 +29,7 @@
  * \param command Fetch command (ETHTOOL_G*)
  * \return value, or nullopt if fetch failed
  */
-std::optional<uint32_t> getValue(const std::string& ifname, uint32_t command);
+std::optional<uint32_t> getValue(std::string_view ifname, uint32_t command);
 
 /**
  * Set a single value with ethtool_value.
@@ -40,6 +40,6 @@
  * \param value New value
  * \return true if succeeded, false otherwise
  */
-bool setValue(const std::string& ifname, uint32_t command, uint32_t value);
+bool setValue(std::string_view ifname, uint32_t command, uint32_t value);
 
 }  // namespace android::netdevice::ethtool
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
index 657f9b2..15ff491 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/libnetdevice.h
@@ -43,7 +43,7 @@
  * \param ifname Interface to check
  * \return true if it exists, false otherwise
  */
-bool exists(std::string ifname);
+bool exists(std::string_view ifname);
 
 /**
  * Checks if network interface is up.
@@ -51,7 +51,7 @@
  * \param ifname Interface to check
  * \return true/false if the check succeeded, nullopt otherwise
  */
-std::optional<bool> isUp(std::string ifname);
+std::optional<bool> isUp(std::string_view ifname);
 
 /**
  * Interface condition to wait for.
@@ -101,7 +101,7 @@
  * \param ifname Interface to bring up
  * \return true in case of success, false otherwise
  */
-bool up(std::string ifname);
+bool up(std::string_view ifname);
 
 /**
  * Brings network interface down.
@@ -109,7 +109,39 @@
  * \param ifname Interface to bring down
  * \return true in case of success, false otherwise
  */
-bool down(std::string ifname);
+bool down(std::string_view ifname);
+
+/**
+ * Retrieves all IPv4 addresses of a given interface.
+ *
+ * \param ifname Interface to query
+ * \return list of IPv4 addresses of this interface
+ */
+std::set<std::string> getAllAddr4(std::string_view ifname);
+
+/**
+ * Set IPv4 address on a given interface.
+ *
+ * This function will overwrite any other existing IPv4 addresses.
+ *
+ * \param ifname Interface to modify
+ * \param addr IPv4 address to set
+ * \return true in case of success, false otherwise
+ */
+bool setAddr4(std::string_view ifname, std::string_view addr,
+              std::optional<uint8_t> prefixlen = std::nullopt);
+
+/**
+ * Add new IPv4 address to a given interface.
+ *
+ * Please note this doesn't remove existing IPv4 addresses.
+ *
+ * \param ifname Interface to modify
+ * \param addr IPv4 address to add
+ * \param prefixlen IPv4 netmask length
+ * \return true in case of success, false otherwise
+ */
+bool addAddr4(std::string_view ifname, std::string_view addr, uint8_t prefixlen = 24);
 
 /**
  * Adds virtual link.
@@ -118,7 +150,7 @@
  * \param type the type of the new device
  * \return true in case of success, false otherwise
  */
-bool add(std::string dev, std::string type);
+bool add(std::string_view dev, std::string_view type);
 
 /**
  * Deletes virtual link.
@@ -126,7 +158,7 @@
  * \param dev the name of the device to remove
  * \return true in case of success, false otherwise
  */
-bool del(std::string dev);
+bool del(std::string_view dev);
 
 /**
  * Fetches interface's hardware address.
@@ -134,7 +166,7 @@
  * \param ifname Interface name
  * \return Hardware address (MAC address) or nullopt if the lookup failed
  */
-std::optional<hwaddr_t> getHwAddr(const std::string& ifname);
+std::optional<hwaddr_t> getHwAddr(std::string_view ifname);
 
 /**
  * Changes interface's hardware address.
@@ -142,7 +174,7 @@
  * \param ifname Interface name
  * \param hwaddr New hardware address to set
  */
-bool setHwAddr(const std::string& ifname, hwaddr_t hwaddr);
+bool setHwAddr(std::string_view ifname, hwaddr_t hwaddr);
 
 }  // namespace android::netdevice
 
diff --git a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/vlan.h b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/vlan.h
index 3e1b736..884b704 100644
--- a/automotive/can/1.0/default/libnetdevice/include/libnetdevice/vlan.h
+++ b/automotive/can/1.0/default/libnetdevice/include/libnetdevice/vlan.h
@@ -20,6 +20,6 @@
 
 namespace android::netdevice::vlan {
 
-bool add(const std::string& eth, const std::string& vlan, uint16_t id);
+bool add(std::string_view eth, std::string_view vlan, uint16_t id);
 
 }  // namespace android::netdevice::vlan
diff --git a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
index 413b4b1..9bb1a57 100644
--- a/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
+++ b/automotive/can/1.0/default/libnetdevice/libnetdevice.cpp
@@ -23,9 +23,13 @@
 #include <libnl++/MessageFactory.h>
 #include <libnl++/Socket.h>
 
+#include <arpa/inet.h>
+#include <ifaddrs.h>
 #include <linux/can.h>
 #include <linux/rtnetlink.h>
 #include <net/if.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
 
 #include <algorithm>
 #include <iterator>
@@ -37,27 +41,102 @@
     ifreqs::socketDomain = domain;
 }
 
-bool exists(std::string ifname) {
+bool exists(std::string_view ifname) {
     return nametoindex(ifname) != 0;
 }
 
-bool up(std::string ifname) {
+bool up(std::string_view ifname) {
     auto ifr = ifreqs::fromName(ifname);
     if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return false;
+    if (ifr.ifr_flags & IFF_UP) return true;
     ifr.ifr_flags |= IFF_UP;
     return ifreqs::send(SIOCSIFFLAGS, ifr);
 }
 
-bool down(std::string ifname) {
+bool down(std::string_view ifname) {
     auto ifr = ifreqs::fromName(ifname);
     if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return false;
+    if (!(ifr.ifr_flags & IFF_UP)) return true;
     ifr.ifr_flags &= ~IFF_UP;
     return ifreqs::send(SIOCSIFFLAGS, ifr);
 }
 
-bool add(std::string dev, std::string type) {
-    nl::MessageFactory<ifinfomsg> req(RTM_NEWLINK,
-                                      NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK);
+static std::string toString(const sockaddr* addr) {
+    char host[NI_MAXHOST];
+    socklen_t addrlen = (addr->sa_family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
+    auto res = getnameinfo(addr, addrlen, host, sizeof(host), nullptr, 0, NI_NUMERICHOST);
+    CHECK(res == 0) << "getnameinfo failed: " << gai_strerror(res);
+    return host;
+}
+
+static std::unique_ptr<ifaddrs, decltype(&freeifaddrs)> getifaddrs() {
+    ifaddrs* addrs = nullptr;
+    CHECK(getifaddrs(&addrs) == 0) << "getifaddrs failed: " << strerror(errno);
+    return {addrs, freeifaddrs};
+}
+
+std::set<std::string> getAllAddr4(std::string_view ifname) {
+    std::set<std::string> addresses;
+    auto addrs = getifaddrs();
+    for (ifaddrs* addr = addrs.get(); addr != nullptr; addr = addr->ifa_next) {
+        if (ifname != addr->ifa_name) continue;
+        if (addr->ifa_addr == nullptr) continue;
+        if (addr->ifa_addr->sa_family != AF_INET) continue;
+        addresses.insert(toString(addr->ifa_addr));
+    }
+    return addresses;
+}
+
+static in_addr_t inetAddr(std::string_view addr) {
+    auto addrn = inet_addr(std::string(addr).c_str());
+    CHECK(addrn != INADDR_NONE) << "Invalid address " << addr;
+    return addrn;
+}
+
+static in_addr_t prefixLengthToIpv4Netmask(uint8_t prefixlen) {
+    in_addr_t zero = 0;
+    return htonl(~zero << (32 - prefixlen));
+}
+
+bool setAddr4(std::string_view ifname, std::string_view addr, std::optional<uint8_t> prefixlen) {
+    auto ifr = ifreqs::fromName(ifname);
+    auto ifrAddr = reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr);
+    ifrAddr->sin_family = AF_INET;
+    ifrAddr->sin_addr.s_addr = inetAddr(addr);
+    if (!ifreqs::send(SIOCSIFADDR, ifr)) return false;
+
+    if (prefixlen.has_value()) {
+        if (*prefixlen < 0 || *prefixlen > 32) {
+            LOG(ERROR) << "Invalid prefix length: " << *prefixlen;
+            return false;
+        }
+        ifr = ifreqs::fromName(ifname);
+        auto ifrNetmask = reinterpret_cast<sockaddr_in*>(&ifr.ifr_netmask);
+        ifrNetmask->sin_family = AF_INET;
+        ifrNetmask->sin_addr.s_addr = prefixLengthToIpv4Netmask(*prefixlen);
+        if (!ifreqs::send(SIOCSIFNETMASK, ifr)) return false;
+    }
+
+    return true;
+}
+
+bool addAddr4(std::string_view ifname, std::string_view addr, uint8_t prefixlen) {
+    nl::MessageFactory<ifaddrmsg> req(RTM_NEWADDR, nl::kCreateFlags);
+    req->ifa_family = AF_INET;
+    req->ifa_prefixlen = prefixlen;
+    req->ifa_flags = IFA_F_SECONDARY;
+    req->ifa_index = nametoindex(ifname);
+
+    auto addrn = inetAddr(addr);
+    req.add(IFLA_ADDRESS, addrn);
+    req.add(IFLA_BROADCAST, addrn);
+
+    nl::Socket sock(NETLINK_ROUTE);
+    return sock.send(req) && sock.receiveAck(req);
+}
+
+bool add(std::string_view dev, std::string_view type) {
+    nl::MessageFactory<ifinfomsg> req(RTM_NEWLINK, nl::kCreateFlags);
     req.add(IFLA_IFNAME, dev);
 
     {
@@ -69,15 +148,15 @@
     return sock.send(req) && sock.receiveAck(req);
 }
 
-bool del(std::string dev) {
-    nl::MessageFactory<ifinfomsg> req(RTM_DELLINK, NLM_F_REQUEST | NLM_F_ACK);
+bool del(std::string_view dev) {
+    nl::MessageFactory<ifinfomsg> req(RTM_DELLINK);
     req.add(IFLA_IFNAME, dev);
 
     nl::Socket sock(NETLINK_ROUTE);
     return sock.send(req) && sock.receiveAck(req);
 }
 
-std::optional<hwaddr_t> getHwAddr(const std::string& ifname) {
+std::optional<hwaddr_t> getHwAddr(std::string_view ifname) {
     auto ifr = ifreqs::fromName(ifname);
     if (!ifreqs::send(SIOCGIFHWADDR, ifr)) return std::nullopt;
 
@@ -86,7 +165,7 @@
     return hwaddr;
 }
 
-bool setHwAddr(const std::string& ifname, hwaddr_t hwaddr) {
+bool setHwAddr(std::string_view ifname, hwaddr_t hwaddr) {
     auto ifr = ifreqs::fromName(ifname);
 
     // fetch sa_family
@@ -96,13 +175,13 @@
     return ifreqs::send(SIOCSIFHWADDR, ifr);
 }
 
-std::optional<bool> isUp(std::string ifname) {
+std::optional<bool> isUp(std::string_view ifname) {
     auto ifr = ifreqs::fromName(ifname);
     if (!ifreqs::send(SIOCGIFFLAGS, ifr)) return std::nullopt;
     return ifr.ifr_flags & IFF_UP;
 }
 
-static bool hasIpv4(std::string ifname) {
+static bool hasIpv4(std::string_view ifname) {
     auto ifr = ifreqs::fromName(ifname);
     switch (ifreqs::trySend(SIOCGIFADDR, ifr)) {
         case 0:
diff --git a/automotive/can/1.0/default/libnetdevice/vlan.cpp b/automotive/can/1.0/default/libnetdevice/vlan.cpp
index 35b21b8..e5b5a61 100644
--- a/automotive/can/1.0/default/libnetdevice/vlan.cpp
+++ b/automotive/can/1.0/default/libnetdevice/vlan.cpp
@@ -26,15 +26,14 @@
 
 namespace android::netdevice::vlan {
 
-bool add(const std::string& eth, const std::string& vlan, uint16_t id) {
+bool add(std::string_view eth, std::string_view vlan, uint16_t id) {
     const auto ethidx = nametoindex(eth);
     if (ethidx == 0) {
         LOG(ERROR) << "Ethernet interface " << eth << " doesn't exist";
         return false;
     }
 
-    nl::MessageFactory<ifinfomsg> req(RTM_NEWLINK,
-                                      NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK);
+    nl::MessageFactory<ifinfomsg> req(RTM_NEWLINK, nl::kCreateFlags);
     req.add(IFLA_IFNAME, vlan);
     req.add<uint32_t>(IFLA_LINK, ethidx);
 
diff --git a/automotive/can/1.0/default/libnl++/Android.bp b/automotive/can/1.0/default/libnl++/Android.bp
index d929d84..ade4ae0 100644
--- a/automotive/can/1.0/default/libnl++/Android.bp
+++ b/automotive/can/1.0/default/libnl++/Android.bp
@@ -25,6 +25,7 @@
 
 cc_library_static {
     name: "libnl++",
+    host_supported: true,
     vendor_available: true,
     cflags: [
         "-Wall",
diff --git a/automotive/can/1.0/default/libnl++/Socket.cpp b/automotive/can/1.0/default/libnl++/Socket.cpp
index 221063d..a5a782c 100644
--- a/automotive/can/1.0/default/libnl++/Socket.cpp
+++ b/automotive/can/1.0/default/libnl++/Socket.cpp
@@ -20,6 +20,9 @@
 
 #include <android-base/logging.h>
 
+// Should be in sys/socket.h or linux/socket.h
+#define SOL_NETLINK 270
+
 namespace android::nl {
 
 /**
diff --git a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
index a5a425e..f65f055 100644
--- a/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
+++ b/automotive/can/1.0/default/libnl++/include/libnl++/MessageFactory.h
@@ -26,6 +26,9 @@
 
 namespace android::nl {
 
+static constexpr uint16_t kDefaultFlags = NLM_F_REQUEST | NLM_F_ACK;
+static constexpr uint16_t kCreateFlags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK;
+
 class MessageFactoryBase {
   protected:
     static nlattr* add(nlmsghdr* msg, size_t maxLen, nlattrtype_t type, const void* data,
@@ -54,7 +57,7 @@
      * \param type Message type (such as RTM_NEWLINK).
      * \param flags Message flags (such as NLM_F_REQUEST).
      */
-    MessageFactory(nlmsgtype_t type, uint16_t flags)
+    MessageFactory(nlmsgtype_t type, uint16_t flags = kDefaultFlags)
         : header(mMessage.header), data(mMessage.data) {
         mMessage.header.nlmsg_len = offsetof(Message, attributesBuffer);
         mMessage.header.nlmsg_type = type;
diff --git a/automotive/can/1.0/default/libnl++/printer.cpp b/automotive/can/1.0/default/libnl++/printer.cpp
index d540482..8c7c476 100644
--- a/automotive/can/1.0/default/libnl++/printer.cpp
+++ b/automotive/can/1.0/default/libnl++/printer.cpp
@@ -26,6 +26,12 @@
 #include <iomanip>
 #include <sstream>
 
+// should be in linux/netlink.h
+#define NLM_F_DUMP_FILTERED 0x20
+#define NLM_F_NONREC 0x100
+#define NLM_F_CAPPED 0x100
+#define NLM_F_ACK_TLVS 0x200
+
 namespace android::nl {
 
 static void flagsToStream(std::stringstream& ss, __u16 nlmsg_flags, protocols::MessageGenre genre) {
diff --git a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp
index 77451ed..277f19d 100644
--- a/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/common/Error.cpp
@@ -22,6 +22,17 @@
 
 #include <map>
 
+#include <linux/netlink.h>
+#ifndef _UAPI__LINUX_NETLINK_H
+// linux_glibc (host) includes source headers instead of uapi headers
+enum nlmsgerr_attrs {
+    NLMSGERR_ATTR_UNUSED,
+    NLMSGERR_ATTR_MSG,
+    NLMSGERR_ATTR_OFFS,
+    NLMSGERR_ATTR_COOKIE,
+};
+#endif
+
 namespace android::nl::protocols::base {
 
 using DataType = AttributeDefinition::DataType;
diff --git a/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp b/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
index 3ad101e..eebd1f1 100644
--- a/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/generic/FamilyTracker.cpp
@@ -18,6 +18,9 @@
 
 #include <android-base/logging.h>
 
+// should be in linux/genetlink.h
+#define GENL_START_ALLOC (NLMSG_MIN_TYPE + 3)
+
 namespace android::nl::generic {
 
 bool FamilyTracker::track(const Buffer<nlmsghdr>& buffer) {
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp b/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp
index 024d389..5bd6262 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/Addr.cpp
@@ -20,6 +20,12 @@
 #include "attributes.h"
 #include "structs.h"
 
+// should be in linux/if_addr.h
+#define IFA_F_MANAGETEMPADDR 0x100
+#define IFA_F_NOPREFIXROUTE 0x200
+#define IFA_F_MCAUTOJOIN 0x400
+#define IFA_F_STABLE_PRIVACY 0x800
+
 namespace android::nl::protocols::route {
 
 using DataType = AttributeDefinition::DataType;
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp b/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp
index 69d9b81..c81ee27 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp
+++ b/automotive/can/1.0/default/libnl++/protocols/route/attributes.cpp
@@ -22,6 +22,54 @@
 #include <linux/rtnetlink.h>
 #include <net/if.h>
 
+#include <linux/if_link.h>
+#ifndef _UAPI_LINUX_IF_LINK_H
+enum {
+    IFLA_INFO_SLAVE_KIND = IFLA_INFO_XSTATS + 1,
+    IFLA_INFO_SLAVE_DATA,
+};
+enum {
+    IFLA_INET6_TOKEN = IFLA_INET6_ICMP6STATS + 1,
+    IFLA_INET6_ADDR_GEN_MODE,
+    IFLA_INET6_RA_MTU,
+};
+enum {
+    IFLA_CARRIER = IFLA_NUM_RX_QUEUES + 1,
+    IFLA_PHYS_PORT_ID,
+    IFLA_CARRIER_CHANGES,
+    IFLA_PHYS_SWITCH_ID,
+    IFLA_LINK_NETNSID,
+    IFLA_PHYS_PORT_NAME,
+    IFLA_PROTO_DOWN,
+    IFLA_GSO_MAX_SEGS,
+    IFLA_GSO_MAX_SIZE,
+    IFLA_PAD,
+    IFLA_XDP,
+    IFLA_EVENT,
+    IFLA_NEW_NETNSID,
+    IFLA_TARGET_NETNSID,
+    IFLA_CARRIER_UP_COUNT,
+    IFLA_CARRIER_DOWN_COUNT,
+    IFLA_NEW_IFINDEX,
+    IFLA_MIN_MTU,
+    IFLA_MAX_MTU,
+    IFLA_PROP_LIST,
+    IFLA_ALT_IFNAME,
+    IFLA_PERM_ADDRESS,
+    IFLA_PROTO_DOWN_REASON,
+    IFLA_PARENT_DEV_NAME,
+    IFLA_PARENT_DEV_BUS_NAME,
+    IFLA_GRO_MAX_SIZE,
+    IFLA_TSO_MAX_SIZE,
+    IFLA_TSO_MAX_SEGS,
+    IFLA_ALLMULTI,
+    IFLA_DEVLINK_PORT,
+    IFLA_GSO_IPV4_MAX_SIZE,
+    IFLA_GRO_IPV4_MAX_SIZE,
+    IFLA_DPLL_PIN,
+};
+#endif
+
 namespace android::nl::protocols::route {
 
 using DataType = AttributeDefinition::DataType;
diff --git a/automotive/can/1.0/default/libnl++/protocols/route/structs.h b/automotive/can/1.0/default/libnl++/protocols/route/structs.h
index c969a6c..410c42e 100644
--- a/automotive/can/1.0/default/libnl++/protocols/route/structs.h
+++ b/automotive/can/1.0/default/libnl++/protocols/route/structs.h
@@ -64,8 +64,8 @@
        << data.tx_heartbeat_errors << ','  //
        << data.tx_window_errors << ','     //
        << data.rx_compressed << ','        //
-       << data.tx_compressed << ','        //
-       << data.rx_nohandler << '}';
+       << data.tx_compressed << '}';
+    // Not printed (due to portability): rx_nohandler, rx_otherhost_dropped
 }
 
 }  // namespace android::nl::protocols::route
diff --git a/automotive/evs/aidl/impl/default/include/ConfigManager.h b/automotive/evs/aidl/impl/default/include/ConfigManager.h
index 37a17dc..f6ba2f2 100644
--- a/automotive/evs/aidl/impl/default/include/ConfigManager.h
+++ b/automotive/evs/aidl/impl/default/include/ConfigManager.h
@@ -50,6 +50,7 @@
 class ConfigManager final {
   public:
     static std::unique_ptr<ConfigManager> Create();
+    static std::unique_ptr<ConfigManager> Create(const std::string path);
     ConfigManager(const ConfigManager&) = delete;
     ConfigManager& operator=(const ConfigManager&) = delete;
 
@@ -65,6 +66,15 @@
             UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(),
         };
 
+        enum class PixelFormat : std::int32_t {
+            NV12 = 0,
+            NV21 = 1,
+            YV12 = 2,
+            I420 = 3,
+
+            UNKNOWN = std::numeric_limits<std::underlying_type_t<DeviceType>>::max(),
+        };
+
         CameraInfo() : characteristics(nullptr) {}
 
         virtual ~CameraInfo();
@@ -82,6 +92,8 @@
 
         static DeviceType deviceTypeFromSV(const std::string_view sv);
 
+        static PixelFormat pixelFormatFromSV(const std::string_view sv);
+
         DeviceType deviceType{DeviceType::NONE};
 
         /*
@@ -105,6 +117,11 @@
 
         /* Camera module characteristics */
         camera_metadata_t* characteristics;
+
+        /* Format of media in a given media container. This field is effective
+         * only for DeviceType::VIDEO.
+         */
+        PixelFormat format;
     };
 
     class CameraGroupInfo : public CameraInfo {
@@ -272,7 +289,7 @@
      * @return bool
      *         True if it completes parsing a file successfully.
      */
-    bool readConfigDataFromXML() noexcept;
+    bool readConfigDataFromXML(const std::string path) noexcept;
 
     /*
      * read the information of the vehicle
diff --git a/automotive/evs/aidl/impl/default/include/EvsCameraBase.h b/automotive/evs/aidl/impl/default/include/EvsCameraBase.h
index c3e9dfc..d9180e8 100644
--- a/automotive/evs/aidl/impl/default/include/EvsCameraBase.h
+++ b/automotive/evs/aidl/impl/default/include/EvsCameraBase.h
@@ -30,6 +30,7 @@
 
     ~EvsCameraBase() override = default;
 
+    virtual std::string getId() = 0;
     virtual void shutdown() = 0;
 
   protected:
diff --git a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
index cd68532..67de8dc 100644
--- a/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
+++ b/automotive/evs/aidl/impl/default/include/EvsMockCamera.h
@@ -65,7 +65,9 @@
     ndk::ScopedAStatus setPrimaryClient() override;
     ndk::ScopedAStatus unsetPrimaryClient() override;
 
-    const evs::CameraDesc& getDesc() { return mDescription; }
+    std::string getId() override { return mDescription.id; }
+
+    const CameraDesc& getDesc() { return mDescription; }
 
     static std::shared_ptr<EvsMockCamera> Create(const char* deviceName);
     static std::shared_ptr<EvsMockCamera> Create(
diff --git a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
index 9d1610a..dc70a43 100644
--- a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
+++ b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
@@ -27,7 +27,6 @@
 #include <aidl/android/hardware/automotive/evs/ParameterRange.h>
 #include <aidl/android/hardware/automotive/evs/Stream.h>
 #include <media/NdkMediaExtractor.h>
-
 #include <ui/GraphicBuffer.h>
 
 #include <cstdint>
@@ -70,6 +69,8 @@
     // Methods from EvsCameraBase follow.
     void shutdown() override;
 
+    std::string getId() override { return mDescription.id; }
+
     const evs::CameraDesc& getDesc() { return mDescription; }
 
     static std::shared_ptr<EvsVideoEmulatedCamera> Create(const char* deviceName);
@@ -117,6 +118,10 @@
     bool postVideoStreamStop_locked(ndk::ScopedAStatus& status,
                                     std::unique_lock<std::mutex>& lck) override;
 
+    int (*mFillBuffer)(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u,
+                       int src_stride_u, const uint8_t* src_v, int src_stride_v, uint8_t* dst_argb,
+                       int dst_stride_argb, int width, int height);
+
     // The properties of this camera.
     CameraDesc mDescription = {};
 
@@ -149,6 +154,10 @@
     uint64_t mUsage = 0;
     // Bytes per line in the buffers
     uint32_t mStride = 0;
+    // Bytes per line in the output buffer
+    uint32_t mDstStride = 0;
+    // Bytes per line of U/V plane
+    uint32_t mUvStride = 0;
 
     // Camera parameters.
     std::unordered_map<CameraParam, std::shared_ptr<CameraParameterDesc>> mParams;
diff --git a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
index d8961d0..eea80f4 100644
--- a/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
+++ b/automotive/evs/aidl/impl/default/src/ConfigManager.cpp
@@ -52,6 +52,25 @@
     return search == nameToType.end() ? DeviceType::UNKNOWN : search->second;
 }
 
+ConfigManager::CameraInfo::PixelFormat ConfigManager::CameraInfo::pixelFormatFromSV(
+        const std::string_view sv) {
+    using namespace std::string_view_literals;
+    static const std::unordered_map<std::string_view, PixelFormat> nameToFormat = {
+            // Full resolution Y plane followed by 2x2 subsampled U/V
+            // interleaved plane.
+            {"NV12"sv, PixelFormat::NV12},
+            // Full resolution Y plane followed by 2x2 subsampled V/U
+            // interleaved plane.
+            {"NV21"sv, PixelFormat::NV21},
+            // Full resolution Y plane followed by 2x2 subsampled V plane and then U plane.
+            {"YV12"sv, PixelFormat::YV12},
+            // Full resolution Y plane followed by 2x2 subsampled U plane and then V plane.
+            {"I420"sv, PixelFormat::I420},
+    };
+    const auto search = nameToFormat.find(sv);
+    return search == nameToFormat.end() ? PixelFormat::UNKNOWN : search->second;
+}
+
 void ConfigManager::printElementNames(const XMLElement* rootElem, const std::string& prefix) const {
     const XMLElement* curElem = rootElem;
 
@@ -144,6 +163,10 @@
         aCamera->deviceType = CameraInfo::deviceTypeFromSV(typeAttr->Value());
     }
 
+    if (const auto formatAttr = aDeviceElem->FindAttribute("format")) {
+        aCamera->format = CameraInfo::pixelFormatFromSV(formatAttr->Value());
+    }
+
     /* size information to allocate camera_metadata_t */
     size_t totalEntries = 0;
     size_t totalDataSize = 0;
@@ -474,19 +497,16 @@
     return;
 }
 
-bool ConfigManager::readConfigDataFromXML() noexcept {
+bool ConfigManager::readConfigDataFromXML(const std::string path) noexcept {
     XMLDocument xmlDoc;
 
     const int64_t parsingStart = android::elapsedRealtimeNano();
 
     /* load and parse a configuration file */
-    xmlDoc.LoadFile(sConfigOverridePath.data());
+    xmlDoc.LoadFile(path.c_str());
     if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
-        xmlDoc.LoadFile(sConfigDefaultPath.data());
-        if (xmlDoc.ErrorID() != tinyxml2::XML_SUCCESS) {
-            LOG(ERROR) << "Failed to load and/or parse a configuration file, " << xmlDoc.ErrorStr();
-            return false;
-        }
+        LOG(ERROR) << "Failed to load and/or parse a configuration file, " << xmlDoc.ErrorStr();
+        return false;
     }
 
     /* retrieve the root element */
@@ -644,8 +664,7 @@
                     p += count * sizeof(camera_metadata_rational_t);
                     break;
                 default:
-                    LOG(WARNING) << "Type " << type << " is unknown; "
-                                 << "data may be corrupted.";
+                    LOG(WARNING) << "Type " << type << " is unknown; " << "data may be corrupted.";
                     break;
             }
         }
@@ -746,8 +765,7 @@
                     p += count * sizeof(camera_metadata_rational_t);
                     break;
                 default:
-                    LOG(WARNING) << "Type " << type << " is unknown; "
-                                 << "data may be corrupted.";
+                    LOG(WARNING) << "Type " << type << " is unknown; " << "data may be corrupted.";
                     break;
             }
         }
@@ -958,6 +976,16 @@
 }
 
 std::unique_ptr<ConfigManager> ConfigManager::Create() {
+    std::unique_ptr<ConfigManager> mgr = Create(std::string(sConfigOverridePath));
+    if (!mgr) {
+        LOG(DEBUG) << "A configuration override file does not exist. Use a default file instead.";
+        mgr = Create(std::string((sConfigDefaultPath)));
+    }
+
+    return mgr;
+}
+
+std::unique_ptr<ConfigManager> ConfigManager::Create(const std::string path) {
     std::unique_ptr<ConfigManager> cfgMgr(new ConfigManager());
 
     /*
@@ -968,7 +996,7 @@
      * to the filesystem and construct CameraInfo instead; this was
      * evaluated as 10x faster.
      */
-    if (!cfgMgr->readConfigDataFromXML()) {
+    if (!cfgMgr->readConfigDataFromXML(path)) {
         return nullptr;
     } else {
         return cfgMgr;
diff --git a/automotive/evs/aidl/impl/default/src/EvsCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
index 005c71f..c28f86f 100644
--- a/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
@@ -205,7 +205,8 @@
         }
 
         if ((!preVideoStreamStop_locked(status, lck) || !stopVideoStreamImpl_locked(status, lck) ||
-             !postVideoStreamStop_locked(status, lck)) && !status.isOk()) {
+             !postVideoStreamStop_locked(status, lck)) &&
+            !status.isOk()) {
             needShutdown = true;
         }
     }
diff --git a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
index 480c28d..7574a34 100644
--- a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
@@ -26,6 +26,7 @@
 #include <utils/SystemClock.h>
 
 #include <fcntl.h>
+#include <libyuv.h>
 #include <sys/types.h>
 #include <unistd.h>
 
@@ -35,12 +36,45 @@
 #include <tuple>
 #include <utility>
 
+// Uncomment below line to dump decoded frames.
+// #define DUMP_FRAMES (1)
+
 namespace aidl::android::hardware::automotive::evs::implementation {
 
 namespace {
+
 struct FormatDeleter {
     void operator()(AMediaFormat* format) const { AMediaFormat_delete(format); }
 };
+
+int fillRGBAFromNv12(const uint8_t* src_y, int src_stride_y, const uint8_t* src_uv,
+                     int src_stride_uv, const uint8_t*, int, uint8_t* dst_abgr, int dst_stride_abgr,
+                     int width, int height) {
+    return libyuv::NV12ToABGR(src_y, src_stride_y, src_uv, src_stride_uv, dst_abgr, dst_stride_abgr,
+                              width, height);
+}
+
+int fillRGBAFromNv21(const uint8_t* src_y, int src_stride_y, const uint8_t* src_vu,
+                     int src_stride_vu, const uint8_t*, int, uint8_t* dst_abgr, int dst_stride_abgr,
+                     int width, int height) {
+    return libyuv::NV21ToABGR(src_y, src_stride_y, src_vu, src_stride_vu, dst_abgr, dst_stride_abgr,
+                              width, height);
+}
+
+int fillRGBAFromYv12(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
+                     const uint8_t* src_v, int src_stride_v, uint8_t* dst_abgr, int dst_stride_abgr,
+                     int width, int height) {
+    return libyuv::I420ToABGR(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
+                              dst_abgr, dst_stride_abgr, width, height);
+}
+
+int fillRGBAFromI420(const uint8_t* src_y, int src_stride_y, const uint8_t* src_u, int src_stride_u,
+                     const uint8_t* src_v, int src_stride_v, uint8_t* dst_abgr, int dst_stride_abgr,
+                     int width, int height) {
+    return libyuv::I420ToABGR(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
+                              dst_abgr, dst_stride_abgr, width, height);
+}
+
 }  // namespace
 
 EvsVideoEmulatedCamera::EvsVideoEmulatedCamera(Sigil, const char* deviceName,
@@ -123,7 +157,7 @@
     mDescription.vendorFlags = 0xFFFFFFFF;  // Arbitrary test value
     mUsage = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_CAMERA_WRITE |
              GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY;
-    mFormat = HAL_PIXEL_FORMAT_YCBCR_420_888;
+    mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
     AMediaFormat_setInt32(format.get(), AMEDIAFORMAT_KEY_COLOR_FORMAT, COLOR_FormatYUV420Flexible);
     {
         const media_status_t status =
@@ -137,6 +171,30 @@
     format.reset(AMediaCodec_getOutputFormat(mVideoCodec.get()));
     AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_WIDTH, &mWidth);
     AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_HEIGHT, &mHeight);
+
+    switch (mCameraInfo->format) {
+        default:
+        case ConfigManager::CameraInfo::PixelFormat::NV12:
+            mFillBuffer = fillRGBAFromNv12;
+            mUvStride = mWidth;
+            mDstStride = mWidth * 4;
+            break;
+        case ConfigManager::CameraInfo::PixelFormat::NV21:
+            mFillBuffer = fillRGBAFromNv21;
+            mUvStride = mWidth;
+            mDstStride = mWidth * 4;
+            break;
+        case ConfigManager::CameraInfo::PixelFormat::YV12:
+            mFillBuffer = fillRGBAFromYv12;
+            mUvStride = mWidth / 2;
+            mDstStride = mWidth * 4;
+            break;
+        case ConfigManager::CameraInfo::PixelFormat::I420:
+            mFillBuffer = fillRGBAFromI420;
+            mUvStride = mWidth / 2;
+            mDstStride = mWidth * 4;
+            break;
+    }
     return true;
 }
 
@@ -190,6 +248,28 @@
     uint8_t* const codecOutputBuffer =
             AMediaCodec_getOutputBuffer(mVideoCodec.get(), index, &decodedOutSize) + info.offset;
 
+    int color_format = 0;
+    const auto outFormat = AMediaCodec_getOutputFormat(mVideoCodec.get());
+    if (!AMediaFormat_getInt32(outFormat, AMEDIAFORMAT_KEY_COLOR_FORMAT, &color_format)) {
+        LOG(ERROR) << "Failed to get the color format.";
+        return;
+    }
+
+    int stride = 0;
+    if (!AMediaFormat_getInt32(outFormat, AMEDIAFORMAT_KEY_STRIDE, &stride)) {
+        LOG(WARNING) << "Cannot find stride in format. Set as frame width.";
+        stride = mWidth;
+    }
+
+    int slice_height = 0;
+    if (!AMediaFormat_getInt32(outFormat, AMEDIAFORMAT_KEY_SLICE_HEIGHT, &slice_height)) {
+        LOG(WARNING) << "Cannot find slice-height in format. Set as frame height.";
+        slice_height = mHeight;
+    }
+
+    LOG(DEBUG) << "COLOR FORMAT: " << color_format << " stride: " << stride
+               << " height: " << slice_height;
+
     std::size_t renderBufferId = static_cast<std::size_t>(-1);
     buffer_handle_t renderBufferHandle = nullptr;
     {
@@ -200,7 +280,7 @@
         std::tie(renderBufferId, renderBufferHandle) = useBuffer_unsafe();
     }
     if (!renderBufferHandle) {
-        LOG(ERROR) << __func__ << ": Camera failed to get an available render buffer.";
+        LOG(DEBUG) << __func__ << ": Camera failed to get an available render buffer.";
         return;
     }
     std::vector<BufferDesc> renderBufferDescs;
@@ -236,19 +316,51 @@
         return;
     }
 
-    std::size_t ySize = mHeight * mStride;
+    // Decoded output is in YUV4:2:0.
+    std::size_t ySize = mHeight * mWidth;
     std::size_t uvSize = ySize / 4;
 
-    std::memcpy(pixels, codecOutputBuffer, ySize);
-    pixels += ySize;
-
     uint8_t* u_head = codecOutputBuffer + ySize;
     uint8_t* v_head = u_head + uvSize;
 
-    for (size_t i = 0; i < uvSize; ++i) {
-        *(pixels++) = *(u_head++);
-        *(pixels++) = *(v_head++);
+#if DUMP_FRAMES
+    // TODO: We may want to keep this "dump" option.
+    static int dumpCount = 0;
+    static bool dumpData = ++dumpCount < 10;
+    if (dumpData) {
+        std::string path = "/data/vendor/dump/";
+        path += "dump_" + std::to_string(dumpCount) + ".bin";
+
+        ::android::base::unique_fd fd(
+                open(path.data(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP));
+        if (fd < 0) {
+            LOG(ERROR) << "Failed to open " << path;
+        } else {
+            auto len = write(fd.get(), codecOutputBuffer, info.size);
+            LOG(ERROR) << "Write " << len << " to " << path;
+        }
     }
+#endif
+    if (auto result = mFillBuffer(codecOutputBuffer, mWidth, u_head, mUvStride, v_head, mUvStride,
+                                  pixels, mDstStride, mWidth, mHeight);
+        result != 0) {
+        LOG(ERROR) << "Failed to convert I420 to BGRA";
+    }
+#if DUMP_FRAMES
+    else if (dumpData) {
+        std::string path = "/data/vendor/dump/";
+        path += "dump_" + std::to_string(dumpCount) + "_rgba.bin";
+
+        ::android::base::unique_fd fd(
+                open(path.data(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP));
+        if (fd < 0) {
+            LOG(ERROR) << "Failed to open " << path;
+        } else {
+            auto len = write(fd.get(), pixels, mStride * mHeight * 4);
+            LOG(ERROR) << "Write " << len << " to " << path;
+        }
+    }
+#endif
 
     // Release our output buffer
     mapper.unlock(renderBufferHandle);
@@ -332,8 +444,8 @@
 ::android::status_t EvsVideoEmulatedCamera::allocateOneFrame(buffer_handle_t* handle) {
     static auto& alloc = ::android::GraphicBufferAllocator::get();
     unsigned pixelsPerLine = 0;
-    const auto result = alloc.allocate(mWidth, mHeight, mFormat, 1, mUsage, handle, &pixelsPerLine,
-                                       0, "EvsVideoEmulatedCamera");
+    const auto result = alloc.allocate(mWidth, mHeight, HAL_PIXEL_FORMAT_RGBA_8888, 1, mUsage,
+                                       handle, &pixelsPerLine, 0, "EvsVideoEmulatedCamera");
     if (mStride == 0) {
         // Gralloc defines stride in terms of pixels per line
         mStride = pixelsPerLine;
@@ -350,7 +462,7 @@
 
     if (auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
         LOG(INFO) << __func__ << ": Received error in starting decoder. "
-                     << "Trying again after resetting this emulated device.";
+                  << "Trying again after resetting this emulated device.";
 
         if (!initializeMediaCodec()) {
             LOG(ERROR) << __func__ << ": Failed to re-configure the media codec.";
@@ -361,7 +473,7 @@
                                AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC);
         AMediaCodec_flush(mVideoCodec.get());
 
-        if(auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
+        if (auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
             LOG(ERROR) << __func__ << ": Received error again in starting decoder. "
                        << "Error code: " << status;
             return false;
@@ -389,7 +501,9 @@
         return false;
     }
 
-    EvsEventDesc event = { .aType = EvsEventType::STREAM_STOPPED, };
+    EvsEventDesc event = {
+            .aType = EvsEventType::STREAM_STOPPED,
+    };
     if (auto result = mStream->notify(event); !result.isOk()) {
         LOG(WARNING) << "Failed to notify the end of the stream.";
     }
diff --git a/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp b/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp
index 8b4676e..ce0e776 100644
--- a/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp
+++ b/automotive/evs/aidl/impl/default/tests/EvsCameraBufferTest.cpp
@@ -92,6 +92,7 @@
                 (override));
     MOCK_METHOD(bool, stopVideoStreamImpl_locked,
                 (ndk::ScopedAStatus & status, std::unique_lock<std::mutex>& lck), (override));
+    MOCK_METHOD(std::string, getId, (), (override));
 };
 
 TEST(EvsCameraBufferTest, ChangeBufferPoolSize) {
diff --git a/automotive/evs/aidl/impl/default/tests/EvsCameraStateTest.cpp b/automotive/evs/aidl/impl/default/tests/EvsCameraStateTest.cpp
index 1925c79..c517e34 100644
--- a/automotive/evs/aidl/impl/default/tests/EvsCameraStateTest.cpp
+++ b/automotive/evs/aidl/impl/default/tests/EvsCameraStateTest.cpp
@@ -141,6 +141,7 @@
                 (override));
     MOCK_METHOD(::ndk::ScopedAStatus, setPrimaryClient, (), (override));
     MOCK_METHOD(::ndk::ScopedAStatus, unsetPrimaryClient, (), (override));
+    MOCK_METHOD(std::string, getId, (), (override));
 
     bool mStreamStarted = false;
     bool mStreamStopped = false;
@@ -160,7 +161,7 @@
     MOCK_METHOD(::ndk::ScopedAStatus, notify,
                 (const ::aidl::android::hardware::automotive::evs::EvsEventDesc& in_event),
                 (override));
-    MOCK_METHOD(::ndk::ScopedAStatus, getInterfaceVersion, (int32_t * _aidl_return), (override));
+    MOCK_METHOD(::ndk::ScopedAStatus, getInterfaceVersion, (int32_t* _aidl_return), (override));
     MOCK_METHOD(::ndk::ScopedAStatus, getInterfaceHash, (std::string * _aidl_return), (override));
 };
 
diff --git a/automotive/vehicle/Android.bp b/automotive/vehicle/Android.bp
index 606e108..d549a82 100644
--- a/automotive/vehicle/Android.bp
+++ b/automotive/vehicle/Android.bp
@@ -19,13 +19,21 @@
 }
 
 cc_defaults {
-    name: "VehicleHalInterfaceDefaults",
+    name: "VehicleHalInterfaceDefaults-V3",
     static_libs: [
         "android.hardware.automotive.vehicle-V3-ndk",
         "android.hardware.automotive.vehicle.property-V4-ndk",
     ],
 }
 
+cc_defaults {
+    name: "VehicleHalInterfaceDefaults",
+    static_libs: [
+        "android.hardware.automotive.vehicle-V4-ndk",
+        "android.hardware.automotive.vehicle.property-V4-ndk",
+    ],
+}
+
 rust_defaults {
     name: "VehicleHalInterfaceRustDefaults",
     rustlibs: [
@@ -37,7 +45,7 @@
 aidl_interface_defaults {
     name: "android.hardware.automotive.vehicle-latest-defaults",
     imports: [
-        "android.hardware.automotive.vehicle-V3",
+        "android.hardware.automotive.vehicle-V4",
         "android.hardware.automotive.vehicle.property-V4",
     ],
 }
diff --git a/automotive/vehicle/TEST_MAPPING b/automotive/vehicle/TEST_MAPPING
index d848774..56bc047 100644
--- a/automotive/vehicle/TEST_MAPPING
+++ b/automotive/vehicle/TEST_MAPPING
@@ -48,12 +48,7 @@
       "name": "GRPCVehicleHardwareUnitTest"
     },
     {
-      "name": "CarServiceUnitTest",
-      "options" : [
-        {
-          "include-filter": "com.android.car.hal.fakevhal.FakeVehicleStubUnitTest"
-        }
-      ]
+      "name": "CarServiceHalUnitTest"
     },
     {
       "name": "VehicleHalProtoMessageConverterTest"
diff --git a/automotive/vehicle/aidl/Android.bp b/automotive/vehicle/aidl/Android.bp
index ce9e7a1..4b2d2b8 100644
--- a/automotive/vehicle/aidl/Android.bp
+++ b/automotive/vehicle/aidl/Android.bp
@@ -27,7 +27,7 @@
     srcs: [
         "android/hardware/automotive/vehicle/*.aidl",
     ],
-    frozen: true,
+    frozen: false,
     stability: "vintf",
     backend: {
         cpp: {
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/HasSupportedValueInfo.aidl
similarity index 86%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/HasSupportedValueInfo.aidl
index a5eda52..e9633cc 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/HasSupportedValueInfo.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
+parcelable HasSupportedValueInfo {
+  boolean hasMinSupportedValue;
+  boolean hasMaxSupportedValue;
+  boolean hasSupportedValuesList;
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/IVehicle.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/IVehicle.aidl
index b5f62aa..ee58416 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/IVehicle.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/IVehicle.aidl
@@ -41,6 +41,10 @@
   void subscribe(in android.hardware.automotive.vehicle.IVehicleCallback callback, in android.hardware.automotive.vehicle.SubscribeOptions[] options, int maxSharedMemoryFileCount);
   void unsubscribe(in android.hardware.automotive.vehicle.IVehicleCallback callback, in int[] propIds);
   void returnSharedMemory(in android.hardware.automotive.vehicle.IVehicleCallback callback, long sharedMemoryId);
+  android.hardware.automotive.vehicle.SupportedValuesListResults getSupportedValuesLists(in List<android.hardware.automotive.vehicle.PropIdAreaId> propIdAreaIds);
+  android.hardware.automotive.vehicle.MinMaxSupportedValueResults getMinMaxSupportedValue(in List<android.hardware.automotive.vehicle.PropIdAreaId> propIdAreaIds);
+  void registerSupportedValueChangeCallback(in android.hardware.automotive.vehicle.IVehicleCallback callback, in List<android.hardware.automotive.vehicle.PropIdAreaId> propIdAreaIds);
+  void unregisterSupportedValueChangeCallback(in android.hardware.automotive.vehicle.IVehicleCallback callback, in List<android.hardware.automotive.vehicle.PropIdAreaId> propIdAreaIds);
   const long INVALID_MEMORY_ID = 0;
   const int MAX_SHARED_MEMORY_FILES_PER_CLIENT = 3;
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/IVehicleCallback.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/IVehicleCallback.aidl
index 2c5a333..50a8e76 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/IVehicleCallback.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/IVehicleCallback.aidl
@@ -38,4 +38,5 @@
   oneway void onSetValues(in android.hardware.automotive.vehicle.SetValueResults responses);
   oneway void onPropertyEvent(in android.hardware.automotive.vehicle.VehiclePropValues propValues, int sharedMemoryFileCount);
   oneway void onPropertySetError(in android.hardware.automotive.vehicle.VehiclePropErrors errors);
+  oneway void onSupportedValueChange(in List<android.hardware.automotive.vehicle.PropIdAreaId> propIdAreaIds);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl
similarity index 79%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl
index a5eda52..a004b79 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
+parcelable MinMaxSupportedValueResult {
+  android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
+  @nullable android.hardware.automotive.vehicle.RawPropValues minSupportedValue;
+  @nullable android.hardware.automotive.vehicle.RawPropValues maxSupportedValue;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/MinMaxSupportedValueResults.aidl
similarity index 85%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/MinMaxSupportedValueResults.aidl
index a5eda52..914d9c6 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/MinMaxSupportedValueResults.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable MinMaxSupportedValueResults {
+  android.hardware.automotive.vehicle.MinMaxSupportedValueResult[] payloads;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/PropIdAreaId.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/PropIdAreaId.aidl
index a5eda52..83e9c15 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/PropIdAreaId.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
+parcelable PropIdAreaId {
+  int propId;
+  int areaId;
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
index f7e8c5a..8651c30 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/StatusCode.aidl
@@ -45,4 +45,5 @@
   NOT_AVAILABLE_SPEED_HIGH = 8,
   NOT_AVAILABLE_POOR_VISIBILITY = 9,
   NOT_AVAILABLE_SAFETY = 10,
+  NOT_AVAILABLE_SUBSYSTEM_NOT_CONNECTED = 11,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl
similarity index 82%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl
index a5eda52..f348dcb 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
+parcelable SupportedValuesListResult {
+  android.hardware.automotive.vehicle.StatusCode status = android.hardware.automotive.vehicle.StatusCode.OK;
+  @nullable List<android.hardware.automotive.vehicle.RawPropValues> supportedValuesList;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SupportedValuesListResults.aidl
similarity index 85%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SupportedValuesListResults.aidl
index a5eda52..08af47c 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/SupportedValuesListResults.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.vehicle;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SupportedValuesListResults {
+  android.hardware.automotive.vehicle.SupportedValuesListResult[] payloads;
+  @nullable ParcelFileDescriptor sharedMemoryFd;
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index eb3028e..e3f8605 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -35,13 +35,35 @@
 @JavaDerive(equals=true, toString=true) @RustDerive(Clone=true) @VintfStability
 parcelable VehicleAreaConfig {
   int areaId;
+  /**
+   * @deprecated client should use {@code getMinMaxSupportedValue} instead. Only applicable for {@code INT32} type property. Ignored for other types. The optional minimum value at boot time. For backward compatibility, if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true}, and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true}, this must be equal to the min supported value ({@code MinMaxSupportedValueResult.minSupportedValue}) at boot time. If no minimum or maximum value is available at boot time, both {@code minInt32Value} and {@code maxInt32Value} must be set to 0. If either one is not 0, then we assume min and max both take effect.
+   */
   int minInt32Value;
+  /**
+   * @deprecated client should use {@code getMinMaxSupportedValue} instead. Only applicable for {@code INT32} type property. Ignored for other types. The optional maximum value at boot time. For backward compatibility, if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true}, and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true}, this must be equal to the max supported value ({@code MinMaxSupportedValueResult.maxSupportedValue}) at boot time. If no minimum or maximum value is available at boot time, both {@code minInt32Value} and {@code maxInt32Value} must be set to 0. If either one is not 0, then we assume min and max both take effect.
+   */
   int maxInt32Value;
+  /**
+   * @deprecated client should use {@code getMinMaxSupportedValue} instead. Only applicable for {@code INT64} type property. Ignored for other types. The optional minimum value at boot time. For backward compatibility, if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true}, and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true}, this must be equal to the min supported value ({@code MinMaxSupportedValueResult.minSupportedValue}) at boot time. If no minimum or maximum value is available at boot time, both {@code minInt64Value} and {@code maxInt64Value} must be set to 0. If either one is not 0, then we assume min and max both take effect.
+   */
   long minInt64Value;
+  /**
+   * @deprecated client should use {@code getMinMaxSupportedValue} instead. Only applicable for {@code INT64} type property. Ignored for other types. The optional maximum value at boot time. For backward compatibility, if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true}, and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true}, this must be equal to the max supported value ({@code MinMaxSupportedValueResult.maxSupportedValue}) at boot time. If no minimum or maximum value is available at boot time, both {@code minInt64Value} and {@code maxInt64Value} must be set to 0. If either one is not 0, then we assume min and max both take effect.
+   */
   long maxInt64Value;
+  /**
+   * @deprecated client should use {@code getMinMaxSupportedValue} instead. Only applicable for {@code FLOAT} type property. Ignored for other types. The optional minimum value at boot time. For backward compatibility, if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true}, and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true}, this must be equal to the min supported value ({@code MinMaxSupportedValueResult.minSupportedValue}) at boot time. If no minimum or maximum value is available at boot time, both {@code minFloatValue} and {@code maxFloatValue} must be set to 0. If either one is not 0, then we assume min and max both take effect.
+   */
   float minFloatValue;
+  /**
+   * @deprecated client should use {@code getMinMaxSupportedValue} instead. Only applicable for {@code FLOAT} type property. Ignored for other types. The optional maximum value at boot time. For backward compatibility, if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true}, and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true}, this must be equal to the max supported value ({@code MinMaxSupportedValueResult.maxSupportedValue}) at boot time. If no minimum or maximum value is available at boot time, both {@code minFloatValue} and {@code maxFloatValue} must be set to 0. If either one is not 0, then we assume min and max both take effect.
+   */
   float maxFloatValue;
+  /**
+   * @deprecated client should use {@code getMinMaxSupportedValue} instead. Only applicable for property with {@code @data_enum} annotation. Ignored for other properties. Optional supported subset of supported values at boot time. If the property has a @data_enum and supportedEnumValues is {@code null}, then it is assumed all @data_enum values are supported unless specified through another mechanism. For backward compatibility, if {@code HasSupportedValueInfo.hasSupportedValuesList} is {@code true} and this property has {@code data_enum} annotation, this must be set to the same as {@code SupportedValuesListResult.supportedValuesList} at boot time.
+   */
   @nullable long[] supportedEnumValues;
   android.hardware.automotive.vehicle.VehiclePropertyAccess access = android.hardware.automotive.vehicle.VehiclePropertyAccess.NONE;
   boolean supportVariableUpdateRate;
+  @nullable android.hardware.automotive.vehicle.HasSupportedValueInfo hasSupportedValueInfo;
 }
diff --git a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
index 642ce83..cc88e70 100644
--- a/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
+++ b/automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
@@ -36,5 +36,12 @@
 enum VehiclePropertyStatus {
   AVAILABLE = 0x00,
   UNAVAILABLE = 0x01,
+  NOT_AVAILABLE_GENERAL = 0x01,
   ERROR = 0x02,
+  NOT_AVAILABLE_DISABLED = (0x1000 | 0x01) /* 4097 */,
+  NOT_AVAILABLE_SPEED_LOW = (0x1000 | 0x02) /* 4098 */,
+  NOT_AVAILABLE_SPEED_HIGH = (0x1000 | 0x03) /* 4099 */,
+  NOT_AVAILABLE_POOR_VISIBILITY = (0x1000 | 0x04) /* 4100 */,
+  NOT_AVAILABLE_SAFETY = (0x1000 | 0x05) /* 4101 */,
+  NOT_AVAILABLE_SUBSYSTEM_NOT_CONNECTED = (0x1000 | 0x06) /* 4102 */,
 }
diff --git a/automotive/vehicle/aidl/aidl_test/Android.bp b/automotive/vehicle/aidl/aidl_test/Android.bp
index 1e43070..8edd636 100644
--- a/automotive/vehicle/aidl/aidl_test/Android.bp
+++ b/automotive/vehicle/aidl/aidl_test/Android.bp
@@ -52,7 +52,7 @@
         ":IVehicleGeneratedJavaFiles-V4",
     ],
     static_libs: [
-        "android.hardware.automotive.vehicle-V3-java",
+        "android.hardware.automotive.vehicle-V4-java",
         "android.hardware.automotive.vehicle.property-V4-java",
         "androidx.test.runner",
         "truth",
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/HasSupportedValueInfo.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/HasSupportedValueInfo.aidl
new file mode 100644
index 0000000..991631b
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/HasSupportedValueInfo.aidl
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Whether the [propId, areaId] has min/max supported value or supported values
+ * list specified.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
+parcelable HasSupportedValueInfo {
+    /**
+     * Whether [propId, areaId] has min supported value specified.
+     *
+     * If this is {@code true}, the hardware specifies a min supported value.
+     * If {@code MinMaxSupportedValueResult}'s {@code status} is
+     * {@code StatusCode.OK}, its {@code minSupportedValue} must not be
+     * {@code null}.
+     *
+     * If this is {@code false}, {@code minSupportedValue} must be {@code null}.
+     *
+     * Unless otherwise specified, this field is set to {@code false} for any
+     * properties whose type is not int32, int64 or float.
+     *
+     * For certain properties, e.g. {@code EV_BRAKE_REGENERATION_LEVEL}, this
+     * must always be {@code true}. Check {@code VehicleProperty}
+     * documentation.
+     */
+    boolean hasMinSupportedValue;
+
+    /**
+     * Whether [propId, areaId] has max supported value specified.
+     *
+     * If this is {@code true}, the hardware specifies a max supported value.
+     * If {@code MinMaxSupportedValueResult}'s {@code status} is
+     * {@code StatusCode.OK}, its {@code maxSupportedValue} must not be
+     * {@code null}.
+     *
+     * If this is {@code false}, {@code maxSupportedValue} must be {@code null}.
+     *
+     * Unless otherwise specified, this field is set to {@code false} for any
+     * properties whose type is not int32, int64 or float.
+     *
+     * For certain properties, e.g. {@code EV_BRAKE_REGENERATION_LEVEL}, this
+     * must always be {@code true}. Check {@code VehicleProperty}
+     * documentation.
+     */
+    boolean hasMaxSupportedValue;
+
+    /**
+     * Whether [propId, areaId] has supported values list specified.
+     *
+     * If this is {@code true}, it means the hardware specifies supported
+     * values for this property.
+     * If {@code SupportedValueListResult}'s {@code status} is
+     * {@code StatusCode.OK}, its {@code supportedValuesList} must not be
+     * {@code null}.
+     *
+     * If this is {@code false}, {@code supportedValuesList} must always be
+     * {@code null}.
+     *
+     * The supported value is the superset for both the input value for writable
+     * property and the output value for readable property.
+     *
+     * For certain properties, e.g. {@code GEAR_SELECTION}, this must always be
+     * {@code true}. Check {@code VehicleProperty} documentation.
+     */
+    boolean hasSupportedValuesList;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
index c896d14..220b1da 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicle.aidl
@@ -18,8 +18,11 @@
 
 import android.hardware.automotive.vehicle.GetValueRequests;
 import android.hardware.automotive.vehicle.IVehicleCallback;
+import android.hardware.automotive.vehicle.MinMaxSupportedValueResults;
+import android.hardware.automotive.vehicle.PropIdAreaId;
 import android.hardware.automotive.vehicle.SetValueRequests;
 import android.hardware.automotive.vehicle.SubscribeOptions;
+import android.hardware.automotive.vehicle.SupportedValuesListResults;
 import android.hardware.automotive.vehicle.VehiclePropConfigs;
 
 // Vehicle HAL interface.
@@ -260,4 +263,106 @@
      *    the used shared memory file to return.
      */
     void returnSharedMemory(in IVehicleCallback callback, long sharedMemoryId);
+
+    /**
+     * Gets the supported values lists for [propId, areaId]s.
+     *
+     * For a specific [propId, areaId], if the hardware currently specifies
+     * a list of supported values for it, then it is returned through the
+     * {@code supportedValuesList} field inside
+     * {@code SupportedValuesListResult}. If the hardware does not specify
+     * a list of supported values for it (indicated by
+     * {@code HasSupportedValueInfo.hasSupportedValuesList} being
+     * {@code false}), then {@code supportedValuesList} field will be
+     * {@code null}.
+     *
+     * The supported value list applies for both read/write operations. if
+     * it differs for read/write, this is the super-set.
+     *
+     * Must return a list of results, one for each requested [propId, areaId].
+     *
+     * The returned supported values list represents the currently supported
+     * values and may change dynamically. Caller should use
+     * {@code registerSupportedValueChangeCallback} to register for supported
+     * value range change.
+     *
+     * If unable to determine the supported values for some [propId, areaId] due
+     * to error cases, for example, unable to determine EV_CHARGE_PERCENT_LIMIT
+     * supported values due to battery in an error state,
+     * {@code SupportedValuesListResult.status} for that should be set to
+     * a non-okay {@code StatusCode}.
+     *
+     * If one of the [propId, areaId] is not supported,
+     * {@code SupportedValuesListResult.status} for that should be set to
+     * {@code StatusCode.INVALID_ARG}.
+     *
+     * This function should only return non-okay {@code StatusCode} if the whole
+     * operation failed and unable to get any results.
+     */
+    SupportedValuesListResults getSupportedValuesLists(in List<PropIdAreaId> propIdAreaIds);
+
+    /**
+     * Gets the min/max supported values for [propId, areaId]s.
+     *
+     * For a specific [propId, areaId], if the hardware currently specifies
+     * min/max supported value for it, then it is returned through the
+     * {@code minSupportedValue} or {@code maxSupportedValue} field inside
+     * {@code MinMaxSupportedValueResult}. If the hardware does not specify
+     * min/max supported value for it (indicated by
+     * {@code HasSupportedValueInfo.hasMinSupportedValue} or
+     * {@code HasSupportedValueInfo.hasMaxSupportedValue} being
+     * {@code false}), then {@code minSupportedValue} or
+     * {@code maxSupportedValue} is {@code null}.
+     *
+     * The min/max supported values apply for both read/write operations. if
+     * they differs for read/write, they are from the super-set.
+     *
+     * Must return a list of results, one for each requested [propId, areaId].
+     *
+     * The returned min/max supported values represent the currently supported
+     * values and may change dynamically. Caller should use
+     * {@code registerSupportedValueChangeCallback} to register for supported
+     * value range change.
+     *
+     * If unable to determine the supported values for some [propId, areaId] due
+     * to error cases, for example, unable to determine HVAC_FAN_SPEED
+     * max supported value due to HVAC in an error state,
+     * {@code MinMaxSupportedValueResult.status} for that should be set to
+     * a non-okay {@code StatusCode}.
+     *
+     * If one of the [propId, areaId] is not supported,
+     * {@code MinMaxSupportedValueResult.status} for that should be set to
+     * {@code StatusCode.INVALID_ARG}.
+     *
+     * This function should only return non-okay {@code StatusCode} if the whole
+     * operation failed and unable to get any results.
+     */
+    MinMaxSupportedValueResults getMinMaxSupportedValue(in List<PropIdAreaId> propIdAreaIds);
+
+    /**
+     * Registers the supported value change callback.
+     *
+     * For the specified [propId, areaId]s,
+     * {@code callback.onSupportedValueChange} must be invoked if change
+     * happens.
+     *
+     * This always registers a new callback for the specified [propId, areaId]s
+     * if the same callback was not previously registered for them.
+     *
+     * The list of [propId, areaId]s to register must not be empty.
+     *
+     * @param callback The callback for supported value change.
+     * @param propIdAreaIds A list of [propId, areaId]s to register.
+     */
+    void registerSupportedValueChangeCallback(
+            in IVehicleCallback callback, in List<PropIdAreaId> propIdAreaIds);
+
+    /**
+     * Unregisters the supported value change callback.
+     *
+     * @param callback The callback to unregister.
+     * @param propIdAreaIds A list of [propId, areaId]s to unregister.
+     */
+    void unregisterSupportedValueChangeCallback(
+            in IVehicleCallback callback, in List<PropIdAreaId> propIdAreaIds);
 }
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicleCallback.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicleCallback.aidl
index 2b50321..7230d09 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicleCallback.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/IVehicleCallback.aidl
@@ -17,6 +17,7 @@
 package android.hardware.automotive.vehicle;
 
 import android.hardware.automotive.vehicle.GetValueResults;
+import android.hardware.automotive.vehicle.PropIdAreaId;
 import android.hardware.automotive.vehicle.SetValueResults;
 import android.hardware.automotive.vehicle.StatusCode;
 import android.hardware.automotive.vehicle.VehiclePropErrors;
@@ -96,4 +97,16 @@
      *     does not batch the errors, this may only contain one error.
      */
     oneway void onPropertySetError(in VehiclePropErrors errors);
+
+    /**
+     * Called when the min/max supported value or supported value list for
+     * the registered [propId, areaId]s changes.
+     *
+     * The caller is supposed to call {@code getMinMaxSupportedValue} or
+     * {@code getSupportedValuesLists} to get the new supported value range.
+     *
+     * @param propIdAreaIds The list of [propId, areaId]s whose supported
+     *    value range changes.
+     */
+    oneway void onSupportedValueChange(in List<PropIdAreaId> propIdAreaIds);
 }
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl
new file mode 100644
index 0000000..f85ad3a
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResult.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.RawPropValues;
+import android.hardware.automotive.vehicle.StatusCode;
+
+/**
+ * One result returned from {@code getMinMaxSupportedValue} for one request.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
+parcelable MinMaxSupportedValueResult {
+    /**
+     * The status for result. If this is not OK, the operation failed for this
+     * [propId, areaId].
+     */
+    StatusCode status = StatusCode.OK;
+    /**
+     * The min supported value.
+     *
+     * If the [propId, areaId] does not specify a min supported value, this
+     * is {@code null}.
+     */
+    @nullable RawPropValues minSupportedValue;
+    /**
+     * The max supported value.
+     *
+     * If the [propId, areaId] does not specify a max supported value, this
+     * is {@code null}.
+     */
+    @nullable RawPropValues maxSupportedValue;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResults.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResults.aidl
new file mode 100644
index 0000000..3579979
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/MinMaxSupportedValueResults.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.MinMaxSupportedValueResult;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * The result structure for {@code getMinMaxSupportedValue}.
+ *
+ * Contains a list of results, one for each [propId, areaId] request. The
+ * list must contain the same number of result as the {@code propIdAreaIds}.
+ * The result must be in the same order, e.g. the first result is for the first
+ * [propId, areaId].
+ *
+ * Java Client should use
+ * {@link LargeParcelable.reconstructStableAIDLParcelable} to convert this back
+ * to a regular parcelable and then use the converted parcelable's
+ * {@code payloads} field.
+ *
+ * Native client should use
+ * {@link LargeParcelable::stableLargeParcelableToParcelable}.
+ *
+ * VHAL implementation must store the results into {@link payloads} field and
+ * use {@link LargeParcelable::parcelableToStableLargeParcelable} before
+ * sending the converted large parcelable through binder.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable MinMaxSupportedValueResults {
+    /**
+     * The list of responses if they fit the binder memory limitation.
+     */
+    MinMaxSupportedValueResult[] payloads;
+    /**
+     * Shared memory file to store responses if they exceed binder memory
+     * limitation. Created by VHAL, readable only for the client.
+     * The client must close it after reading.
+     */
+    @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/PropIdAreaId.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/PropIdAreaId.aidl
new file mode 100644
index 0000000..ea47350
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/PropIdAreaId.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.RawPropValues;
+
+/**
+ * A structure containing one propertyId and one areaId.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
+parcelable PropIdAreaId {
+    /** The property Id. */
+    int propId;
+    /** The area Id. */
+    int areaId;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
index fd4b199..3fb4532 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/StatusCode.aidl
@@ -96,4 +96,11 @@
      * operation such as closing a trunk door, etc.
      */
     NOT_AVAILABLE_SAFETY = 10,
+    /**
+     * The feature cannot be accessed because the sub-system for the feature is
+     * not connected.
+     *
+     * E.g. trailer light state is not available when the trailer is detached.
+     */
+    NOT_AVAILABLE_SUBSYSTEM_NOT_CONNECTED = 11,
 }
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl
new file mode 100644
index 0000000..4524f4f
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResult.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.RawPropValues;
+import android.hardware.automotive.vehicle.StatusCode;
+
+/**
+ * One result returned from {@code getSupportedValuesLists} for one request.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+@RustDerive(Clone=true)
+parcelable SupportedValuesListResult {
+    /**
+     * The status for result. If this is not OK, the operation failed for this
+     * [propId, areaId].
+     */
+    StatusCode status = StatusCode.OK;
+    /**
+     * The supported values list.
+     *
+     * If the [propId, areaId] does not specify a supported values list, this
+     * is {@code null}.
+     */
+    @nullable List<RawPropValues> supportedValuesList;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResults.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResults.aidl
new file mode 100644
index 0000000..da84871
--- /dev/null
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SupportedValuesListResults.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+import android.hardware.automotive.vehicle.SupportedValuesListResult;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * The result structure for {@code getSupportedValuesLists}.
+ *
+ * Contains a list of results, one for each [propId, areaId] request. The
+ * list must contain the same number of result as the {@code propIdAreaIds}.
+ * The result must be in the same order, e.g. the first result is for the first
+ * [propId, areaId].
+ *
+ * Java Client should use
+ * {@link LargeParcelable.reconstructStableAIDLParcelable} to convert this back
+ * to a regular parcelable and then use the converted parcelable's
+ * {@code payloads} field.
+ *
+ * Native client should use
+ * {@link LargeParcelable::stableLargeParcelableToParcelable}.
+ *
+ * VHAL implementation must store the results into {@link payloads} field and
+ * use {@link LargeParcelable::parcelableToStableLargeParcelable} before
+ * sending the converted large parcelable through binder.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable SupportedValuesListResults {
+    /**
+     * The list of responses if they fit the binder memory limitation.
+     */
+    SupportedValuesListResult[] payloads;
+    /**
+     * Shared memory file to store responses if they exceed binder memory
+     * limitation. Created by VHAL, readable only for the client.
+     * The client must close it after reading.
+     */
+    @nullable ParcelFileDescriptor sharedMemoryFd;
+}
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 9387965..62d7e21 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.automotive.vehicle;
 
+import android.hardware.automotive.vehicle.HasSupportedValueInfo;
 import android.hardware.automotive.vehicle.VehiclePropertyAccess;
 
 @VintfStability
@@ -28,26 +29,142 @@
     int areaId;
 
     /**
-     * If the property has @data_enum, leave the range to zero.
+     * @deprecated client should use {@code getMinMaxSupportedValue} instead.
      *
-     * Range will be ignored in the following cases:
-     *    - The VehiclePropertyType is not INT32, INT64 or FLOAT.
-     *    - Both of min value and max value are zero.
+     * Only applicable for {@code INT32} type property. Ignored for other types.
+     *
+     * The optional minimum value at boot time.
+     *
+     * For backward compatibility,
+     * if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true},
+     * and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true},
+     * this must be equal to the min supported value
+     * ({@code MinMaxSupportedValueResult.minSupportedValue}) at boot time.
+     *
+     * If no minimum or maximum value is available at boot time, both
+     * {@code minInt32Value} and {@code maxInt32Value} must be set to 0.
+     *
+     * If either one is not 0, then we assume min and max both take effect.
      */
-
     int minInt32Value;
+
+    /**
+     * @deprecated client should use {@code getMinMaxSupportedValue} instead.
+     *
+     * Only applicable for {@code INT32} type property. Ignored for other types.
+     *
+     * The optional maximum value at boot time.
+     *
+     * For backward compatibility,
+     * if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true},
+     * and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true},
+     * this must be equal to the max supported value
+     * ({@code MinMaxSupportedValueResult.maxSupportedValue}) at boot time.
+     *
+     * If no minimum or maximum value is available at boot time, both
+     * {@code minInt32Value} and {@code maxInt32Value} must be set to 0.
+     *
+     * If either one is not 0, then we assume min and max both take effect.
+     */
     int maxInt32Value;
 
+    /**
+     * @deprecated client should use {@code getMinMaxSupportedValue} instead.
+     *
+     * Only applicable for {@code INT64} type property. Ignored for other types.
+     *
+     * The optional minimum value at boot time.
+     *
+     * For backward compatibility,
+     * if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true},
+     * and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true},
+     * this must be equal to the min supported value
+     * ({@code MinMaxSupportedValueResult.minSupportedValue}) at boot time.
+     *
+     * If no minimum or maximum value is available at boot time, both
+     * {@code minInt64Value} and {@code maxInt64Value} must be set to 0.
+     *
+     * If either one is not 0, then we assume min and max both take effect.
+     */
     long minInt64Value;
+
+    /**
+     * @deprecated client should use {@code getMinMaxSupportedValue} instead.
+     *
+     * Only applicable for {@code INT64} type property. Ignored for other types.
+     *
+     * The optional maximum value at boot time.
+     *
+     * For backward compatibility,
+     * if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true},
+     * and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true},
+     * this must be equal to the max supported value
+     * ({@code MinMaxSupportedValueResult.maxSupportedValue}) at boot time.
+     *
+     * If no minimum or maximum value is available at boot time, both
+     * {@code minInt64Value} and {@code maxInt64Value} must be set to 0.
+     *
+     * If either one is not 0, then we assume min and max both take effect.
+     */
     long maxInt64Value;
 
+    /**
+     * @deprecated client should use {@code getMinMaxSupportedValue} instead.
+     *
+     * Only applicable for {@code FLOAT} type property. Ignored for other types.
+     *
+     * The optional minimum value at boot time.
+     *
+     * For backward compatibility,
+     * if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true},
+     * and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true},
+     * this must be equal to the min supported value
+     * ({@code MinMaxSupportedValueResult.minSupportedValue}) at boot time.
+     *
+     * If no minimum or maximum value is available at boot time, both
+     * {@code minFloatValue} and {@code maxFloatValue} must be set to 0.
+     *
+     * If either one is not 0, then we assume min and max both take effect.
+     */
     float minFloatValue;
+
+    /**
+     * @deprecated client should use {@code getMinMaxSupportedValue} instead.
+     *
+     * Only applicable for {@code FLOAT} type property. Ignored for other types.
+     *
+     * The optional maximum value at boot time.
+     *
+     * For backward compatibility,
+     * if {@code HasSupportedValueInfo.hasMinSupportedValue} is {@code true},
+     * and {@code HasSupportedValueInfo.hasMaxSupportedValue} is {@code true},
+     * this must be equal to the max supported value
+     * ({@code MinMaxSupportedValueResult.maxSupportedValue}) at boot time.
+     *
+     * If no minimum or maximum value is available at boot time, both
+     * {@code minFloatValue} and {@code maxFloatValue} must be set to 0.
+     *
+     * If either one is not 0, then we assume min and max both take effect.
+     */
     float maxFloatValue;
 
     /**
-     * If the property has a @data_enum, then it is possible to specify a supported subset of the
-     * @data_enum. If the property has a @data_enum and supportedEnumValues is null, then it is
-     * assumed all @data_enum values are supported unless specified through another mechanism.
+     * @deprecated client should use {@code getMinMaxSupportedValue} instead.
+     *
+     * Only applicable for property with {@code @data_enum} annotation. Ignored
+     * for other properties.
+     *
+     * Optional supported subset of supported values at boot time.
+     *
+     * If the property has a @data_enum and supportedEnumValues is {@code null},
+     * then it is assumed all @data_enum values are supported unless specified
+     * through another mechanism.
+     *
+     * For backward compatibility, if
+     * {@code HasSupportedValueInfo.hasSupportedValuesList} is {@code true}
+     * and this property has {@code data_enum} annotation,
+     * this must be set to the same as
+     * {@code SupportedValuesListResult.supportedValuesList} at boot time.
      */
     @nullable long[] supportedEnumValues;
 
@@ -83,6 +200,8 @@
     /**
      * Whether variable update rate is supported.
      *
+     * This is always {@code false} for VHAL implementation < V3.
+     *
      * This applies for continuous property only.
      *
      * It is HIGHLY RECOMMENDED to support variable update rate for all non-heartbeat continuous
@@ -109,4 +228,12 @@
      * so this should be false if the property is large (e.g. a byte array of 1k in size).
      */
     boolean supportVariableUpdateRate;
+
+    /**
+     * For VHAL implementation >= V4, this must not be {@code null}. This specifies whether
+     * this property may have min/max supported value or supported values list.
+     *
+     * For VHAL implementation < V4, this is always {@code null} and is not accessed.
+     */
+    @nullable HasSupportedValueInfo hasSupportedValueInfo;
 }
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
index 400e256..4b1dcdb 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropertyStatus.aidl
@@ -22,9 +22,15 @@
 @VintfStability
 @Backing(type="int")
 enum VehiclePropertyStatus {
-    /** Property is available and behaving normally */
+    /**
+     * Property is available and behaving normally
+     */
     AVAILABLE = 0x00,
     /**
+     * Same as {@link #NOT_AVAILABLE_GENERAL}.
+     */
+    UNAVAILABLE = 0x01,
+    /**
      * A property in this state is not available for reading and writing.  This
      * is a transient state that depends on the availability of the underlying
      * implementation (e.g. hardware or driver). It MUST NOT be used to
@@ -34,8 +40,45 @@
      * this state MAY return NOT_AVAILABLE. The HAL implementation MUST ignore
      * the value of the status field when writing a property value coming from
      * Android.
+     *
+     * This represents a general not-available status. If more detailed info is
+     * known, a more specific not-available status should be used instead.
      */
-    UNAVAILABLE = 0x01,
-    /** There is an error with this property. */
+    NOT_AVAILABLE_GENERAL = 0x01,
+    /**
+     * There is an error with this property.
+     */
     ERROR = 0x02,
+    // All NOT_AVAILABLE_XXX status starts with 0x1000.
+    /**
+     * The property is not available because the underlying feature is disabled.
+     */
+    NOT_AVAILABLE_DISABLED = 0x1000 | 0x01,
+    /**
+     * The property is not available because the vehicle speed is too low.
+     */
+    NOT_AVAILABLE_SPEED_LOW = 0x1000 | 0x02,
+    /**
+     * The property is not available because the vehicle speed is too high.
+     */
+    NOT_AVAILABLE_SPEED_HIGH = 0x1000 | 0x03,
+    /**
+     * The property is not available because of bad camera or sensor visibility. Examples
+     * might be bird poop blocking the camera or a bumper cover blocking an ultrasonic sensor.
+     */
+    NOT_AVAILABLE_POOR_VISIBILITY = 0x1000 | 0x04,
+    /**
+     * The property cannot be accessed due to safety reasons. Eg. System could be
+     * in a faulty state, an object or person could be blocking the requested
+     * operation such as closing a trunk door, etc.
+     */
+    NOT_AVAILABLE_SAFETY = 0x1000 | 0x05,
+    /**
+     * The property is not available because the sub-system for the feature is
+     * not connected.
+     *
+     * E.g. the trailer light property is in this state if the trailer is not
+     * attached.
+     */
+    NOT_AVAILABLE_SUBSYSTEM_NOT_CONNECTED = 0x1000 | 0x06,
 }
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 8ef440d..6cd7d1f 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
@@ -93,6 +93,20 @@
                 "description": "Multiple EV port locations\nImplement this property if the vehicle has multiple EV ports. Port locations are defined in PortLocationType. For example, a car has one port in front left and one port in rear left: int32Values[0] = PortLocationType::FRONT_LEFT int32Values[1] = PortLocationType::REAR_LEFT\nIf only one port exists on the vehicle, this property's value should list just one element. See INFO_EV_PORT_LOCATION for describing just one port location."
             },
             {
+                "name": "INFO_MODEL_TRIM",
+                "value": 286261517,
+                "description": "Public trim name of the vehicle.\nThis property must communicate the vehicle's public trim name.\nFor example, say an OEM manufactures two different versions of a vehicle model: \"makeName modelName\" and \"makeName modelName Sport\" This property must be empty for the first vehicle (i.e. base model), and set to \"Sport\" for the second vehicle."
+            },
+            {
+                "name": "Vehicle Size Class.",
+                "value": 289472782,
+                "data_enums": [
+                    "VehicleSizeClass"
+                ],
+                "data_enum": "VehicleSizeClass",
+                "description": "Vehicle Size Class.\nThis property must communicate an integer array that contains the size classifications followed by the vehicle as enumerated in VehicleSizeClass.aidl. If the vehicle follows a single standard, then the array size of the property's value should be 1. If the vehicle follows multiple standards that the OEM wants to communicate, this may be communicated as additional values in the array.\nFor example, suppose a vehicle model follows the VehicleSizeClass.EU_A_SEGMENT standard in the EU and the VehicleSizeClass.JPN_KEI standard in Japan. In this scenario this property must return an intArray = [VehicleSizeClass.EU_A_SEGMENT, VehicleSizeClass.JPN_KEI]. If this vehicle only followed the VehicleSizeClass.EU_A_SEGMENT standard, then we expect intArray = [VehicleSizeClass.EU_A_SEGMENT]."
+            },
+            {
                 "name": "PERF_ODOMETER",
                 "value": 291504644,
                 "description": "Current odometer value of the vehicle"
@@ -118,6 +132,16 @@
                 "description": "Rear bicycle model steering angle for vehicle\nAngle is in degrees.  Left is negative.\nThis property is independent of the angle of the steering wheel. This property must communicate the angle of the rear wheels with respect to the vehicle, not the angle of the steering wheel."
             },
             {
+                "name": "INSTANTANEOUS_FUEL_ECONOMY",
+                "value": 291504657,
+                "description": "Instantaneous Fuel Economy in L\/100km.\nThis property must communicate the instantaneous fuel economy of the vehicle in units of L\/100km. The property's value is independent of DISTANCE_DISPLAY_UNITS, FUEL_VOLUME_DISPLAY_UNITS, and FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME property i.e. this property must always communicate the value in L\/100km.\nFor the EV version of this property, see INSTANTANEOUS_EV_EFFICIENCY."
+            },
+            {
+                "name": "INSTANTANEOUS_EV_EFFICIENCY",
+                "value": 291504658,
+                "description": "Instantaneous EV efficiency in km\/kWh.\nThis property must communicate the instantaneous EV battery efficiency of the vehicle in units of km\/kWh. The property's value is independent of the DISTANCE_DISPLAY_UNITS and EV_BATTERY_DISPLAY_UNITS properties i.e. this property must always communicate the value in km\/kWh.\nFor the fuel version of this property, see INSTANTANEOUS_FUEL_ECONOMY."
+            },
+            {
                 "name": "Temperature of engine coolant",
                 "value": 291504897,
                 "description": "Temperature of engine coolant"
@@ -194,7 +218,7 @@
             {
                 "name": "Tire pressure",
                 "value": 392168201,
-                "description": "Tire pressure\nEach tires is identified by its areaConfig.areaId config and their minFloatValue\/maxFloatValue are used to store OEM recommended pressure range. The minFloatValue and maxFloatValue in VehicleAreaConfig must be defined. The minFloatValue in the areaConfig data represents the lower bound of the recommended tire pressure. The maxFloatValue in the areaConfig data represents the upper bound of the recommended tire pressure. For example: The following areaConfig indicates the recommended tire pressure of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL. .areaConfigs = { VehicleAreaConfig { .areaId = VehicleAreaWheel::LEFT_FRONT, .minFloatValue = 200.0, .maxFloatValue = 240.0, } },"
+                "description": "Tire pressure\nEach tire is identified by its areaConfig.areaId config and its minFloatValue\/maxFloatValue are used to store OEM recommended pressure range.\nThe minFloatValue and maxFloatValue in VehicleAreaConfig must be defined.\nThe minFloatValue in the areaConfig data represents the lower bound of the recommended tire pressure.\nThe maxFloatValue in the areaConfig data represents the upper bound of the recommended tire pressure.\nFor example:\nThe following areaConfig indicates the recommended tire pressure of the left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL. .areaConfigs = { VehicleAreaConfig { .areaId = VehicleAreaWheel::LEFT_FRONT, .minFloatValue = 200.0, .maxFloatValue = 240.0, } }\nIf {@code HasSupportedValueInfo} for a specific area ID is not {@code null}:\n{@code HasSupportedValueInfo.hasMinSupportedValue} and {@code HasSupportedValueInfo.hasMaxSupportedValue} must be {@code true} for the area ID.\n{@code MinMaxSupportedValueResult.minSupportedValue} represents the lower bound of the recommended tire pressure for the tire at the specified area ID.\n{@code MinMaxSupportedValueResult.maxSupportedValue} represents the upper bound of the recommended tire pressure for the tire at the specified area ID.\nFor example, if the recommended tire pressure of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL, {@code getMinMaxSupportedValue} for [propId=TIRE_PRESSURE, areaId=VehicleAreaWheel::LEFT_FRONT] must return a {@code MinMaxSupportedValueResult} with OK status, 200.0 as minSupportedValue, 240.0 as maxSupportedValue.\nAt boot, minFloatValue is equal to minSupportedValue, maxFloatValue is equal to maxSupportedValue."
             },
             {
                 "name": "Critically low tire pressure",
@@ -202,6 +226,31 @@
                 "description": "Critically low tire pressure\nThis property indicates the critically low pressure threshold for each tire. It indicates when it is time for tires to be replaced or fixed. The value must be less than or equal to minFloatValue in TIRE_PRESSURE. Minimum and maximum property values (that is, minFloatValue, maxFloatValue) are not applicable to this property."
             },
             {
+                "name": "ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE",
+                "value": 291504911,
+                "description": "Accelerator pedal compression percentage.\nThis property must communicate the percentage that the physical accelerator pedal in the vehicle is compressed. This property must return a float value from 0 to 100.\n0 indicates the pedal is not compressed. 100 indicates the pedal is maximally compressed."
+            },
+            {
+                "name": "BRAKE_PEDAL_COMPRESSION_PERCENTAGE",
+                "value": 291504912,
+                "description": "Brake pedal compression percentage.\nThis property must communicate the percentage that the physical brake pedal in the vehicle is compressed. This property must return a float value from 0 to 100.\n0 indicates the pedal is not compressed. 100 indicates the pedal is maximally compressed."
+            },
+            {
+                "name": "Brake pad wear percentage.",
+                "value": 392168209,
+                "description": "Brake pad wear percentage.\nThis property must communicate the amount of brake pad wear accumulated by the vehicle as a percentage. This property return a float value from 0 to 100.\n0 indicates the brake pad has no wear. 100 indicates the brake pad is maximally worn."
+            },
+            {
+                "name": "Brake fluid low.",
+                "value": 287310610,
+                "description": "Brake fluid low.\nThis property must communicate that the brake fluid level in the vehicle is low according to the OEM. This property must match the vehicle's brake fluid level status as displayed on the instrument cluster. If the brake fluid level is low, this property must be set to true. If not, it must be set to false."
+            },
+            {
+                "name": "VEHICLE_PASSIVE_SUSPENSION_HEIGHT",
+                "value": 390071059,
+                "description": "Vehicle Passive Suspension Height in mm.\nThis property must communicate the real-time suspension displacement of the vehicle relative to its neutral position, given in mm. In other words, the displacement of the suspension at any given point in time relative to the suspension's position when the vehicle is on a flat surface with no passengers or cargo. When the suspension is compressed in comparison to the neutral position, the value should be negative. When the suspension is decompressed in comparison to the neutral position, the value should be positive.\nExamples for further clarity: 1) Suppose the user is driving on a smooth flat surface, and all wheels are currently compressed by 2 cm in comparison to the default suspension height. In this scenario, this property must be set to -20 for all wheels. 2) Suppose the user drives over a pothole. While the front left wheel is over the pothole, it's decompressed by 3 cm in comparison to the rest of the wheels, or 1 cm in comparison to the default suspension height. All the others are still compressed by 2 cm. In this scenario, this property must be set to -20 for all wheels except for the front left, which must be set to 10.\nHasSupportedValueInfo.hasMinSupportedValue and HasSupportedValueInfo.hasMaxSupportedValue must be true for all areas.\nMinMaxSupportedValueResult.minSupportedValue represents the lower bound of the suspension height for the wheel at the specified area ID.\nMinMaxSupportedValueResult.maxSupportedValue represents the upper bound of the suspension height for the wheel at the specified area ID."
+            },
+            {
                 "name": "ENGINE_IDLE_AUTO_STOP_ENABLED",
                 "value": 287310624,
                 "description": "Represents feature for engine idle automatic stop.\nIf true, the vehicle may automatically shut off the engine when it is not needed and then automatically restart it when needed.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
@@ -213,7 +262,12 @@
                     "ImpactSensorLocation"
                 ],
                 "data_enum": "ImpactSensorLocation",
-                "description": "Impact detected.\nBit flag property to relay information on whether an impact has occurred on a particular side of the vehicle as described through the ImpactSensorLocation enum. As a bit flag property, this property can be set to multiple ORed together values of the enum when necessary.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all bit flags of ImpactSensorLocation are supported."
+                "description": "Impact detected.\nBit flag property to relay information on whether an impact has occurred on a particular side of the vehicle as described through the ImpactSensorLocation enum. As a bit flag property, this property can be set to multiple ORed together values of the enum when necessary.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all bit flags of ImpactSensorLocation are supported.\nIf {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):\n{@code getSupportedValuesList} must return a {@code SupportedValuesListResult} that contains supported values unless all bit flags of ImpactSensorLocation are supported.\nAt boot, supportedEnumValues is equal to the supported values list."
+            },
+            {
+                "name": "Vehicle horn engaged.",
+                "value": 287310656,
+                "description": "Vehicle horn engaged.\nThis property must communicate if the vehicle's horn is currently engaged or not. If true, the horn is engaged. If false, the horn is disengaged."
             },
             {
                 "name": "Currently selected gear",
@@ -222,7 +276,7 @@
                     "VehicleGear"
                 ],
                 "data_enum": "VehicleGear",
-                "description": "Currently selected gear\nThis is the gear selected by the user.\nValues in the config data must represent the list of supported gears for this vehicle. For example, config data for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual transmission the list must be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}\nIn the case of an automatic transmission vehicle that allows the driver to select specific gears on demand (i.e. \"manual mode\"), GEAR_SELECTION's value must be set to the specific gear selected by the driver instead of simply GEAR_DRIVE."
+                "description": "Currently selected gear\nThis is the gear selected by the user.\nValues in the config array must represent the list of supported gears for this vehicle at boot time. For example, config array for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual transmission the list must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}\nIn the case of an automatic transmission vehicle that allows the driver to select specific gears on demand (i.e. \"manual mode\"), GEAR_SELECTION's value must be set to the specific gear selected by the driver instead of simply GEAR_DRIVE.\nIf {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):\n{@code VehicleAreaConfig.HasSupportedValueInfo.hasSupportedValuesList} for the global area ID (0) must be {@code true}.\n{@code getSupportedValuesList} for [GEAR_SELECTION, areaId=0] must return a {@code SupportedValuesListResult} that contains non-null {@code supportedValuesList}.\nThe supportedValues must represent the list of supported gears for this vehicle. For example, for an automatic transmission, the list can be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual transmission it can be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}.\nIn the case of an automatic transmission vehicle that allows the driver to select specific gears on demand (i.e. \"manual mode\"), the GEAR_SELECTION property value must be set to the specific gear selected by the driver instead of simply GEAR_DRIVE.\nAt boot, the config array's values are equal to the supported values list."
             },
             {
                 "name": "CURRENT_GEAR",
@@ -231,7 +285,7 @@
                     "VehicleGear"
                 ],
                 "data_enum": "VehicleGear",
-                "description": "Current gear. In non-manual case, selected gear may not match the current gear. For example, if the selected gear is GEAR_DRIVE, the current gear will be one of GEAR_1, GEAR_2 etc, which reflects the actual gear the transmission is currently running in.\nValues in the config data must represent the list of supported gears for this vehicle.  For example, config data for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...} and for manual transmission the list must be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the same as that of the supported gears reported in GEAR_SELECTION."
+                "description": "Current gear. In non-manual case, selected gear may not match the current gear. For example, if the selected gear is GEAR_DRIVE, the current gear will be one of GEAR_1, GEAR_2 etc, which reflects the actual gear the transmission is currently running in.\nValues in the config array must represent the list of supported gears for this vehicle at boot time.  For example, config array for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...} and for manual transmission the list must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the same as that of the supported gears reported in GEAR_SELECTION.\nIf {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):\n{@code VehicleAreaConfig.HasSupportedValueInfo.hasSupportedValuesList} for the global area ID (0) must be {@code true}.\n{@code getSupportedValuesList} for [GEAR_SELECTION, areaId=0] must return a {@code SupportedValuesListResult} that contains non-null {@code supportedValuesList}.\nThe supported values list must represent the list of supported gears for this vehicle.  For example, for an automatic transmission, this list can be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...} and for manual transmission the list can be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the same as that of the supported gears reported in GEAR_SELECTION.\nAt boot, the config array's values are equal to the supported values list."
             },
             {
                 "name": "Parking brake state.",
@@ -246,7 +300,7 @@
             {
                 "name": "EV_BRAKE_REGENERATION_LEVEL",
                 "value": 289408012,
-                "description": "Regenerative braking level of a electronic vehicle\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between minInt32Value and maxInt32Value must be supported. The minInt32Value must be 0.\nThe maxInt32Value indicates the setting for the maximum amount of energy regenerated from braking. The minInt32Value indicates the setting for no regenerative braking.\nThis property is a more granular form of EV_REGENERATIVE_BRAKING_STATE. It allows the user to set a more specific level of regenerative braking if the states in EvRegenerativeBrakingState are not granular enough for the OEM.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
+                "description": "Regenerative braking level of a electronic vehicle\nThe minInt32Value and maxInt32Value in VehicleAreaConfig must be defined. All values between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the setting for no regenerative braking, must be 0.\nThe maxInt32Value indicates the setting for the maximum amount of energy regenerated from braking.\nAll values between min and max supported value must be supported.\nIf {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):\n{@code HasSupportedValueInfo.hasMinSupportedValue} and {@code HasSupportedValueInfo.hasMaxSupportedValue} must be {@code true} for global area ID(0)\n{@code MinMaxSupportedValueResult.minSupportedValue} must be 0.\n{@code MinMaxSupportedValueResult.maxSupportedValue} indicates the setting for the maximum amount of energy regenerated from braking. The minSupportedValue indicates the setting for no regenerative braking.\nAt boot, minInt32Value is equal to minSupportedValue, maxInt32Value is equal to maxSupportedValue.\n\nThis property is a more granular form of EV_REGENERATIVE_BRAKING_STATE. It allows the user to set a more specific level of regenerative braking if the states in EvRegenerativeBrakingState are not granular enough for the OEM.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Warning for fuel low level.",
@@ -265,7 +319,7 @@
                     "VehicleTurnSignal"
                 ],
                 "data_enum": "VehicleTurnSignal",
-                "description": "State of the vehicles turn signals"
+                "description": "(Deprecated) State of the vehicles turn signals\nThis property has been deprecated as it ambiguously defines the state of the vehicle turn signals without making clear if it means the state of the turn signal lights or the state of the turn signal switch. The introduction of TURN_SIGNAL_LIGHT_STATE and TURN_SIGNAL_SWITCH rectifies this problem."
             },
             {
                 "name": "Represents ignition state",
@@ -293,7 +347,7 @@
                     "EvStoppingMode"
                 ],
                 "data_enum": "EvStoppingMode",
-                "description": "Represents property for the current stopping mode of the vehicle.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless all enum values of EvStoppingMode are supported.\nThe EvStoppingMode enum may be extended to include more states in the future.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
+                "description": "Represents property for the current stopping mode of the vehicle.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless all enum values of EvStoppingMode are supported.\nIf {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):\nFor the global area ID (0), {@code getSupportedValuesList} must return a {@code SupportedValuesListResult} that contains supported values unless all enum values of EvStoppingMode are supported.\nAt boot, supportedEnumValues is equal to the supported values list.\n\nThe EvStoppingMode enum may be extended to include more states in the future.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "ELECTRONIC_STABILITY_CONTROL_ENABLED",
@@ -308,7 +362,25 @@
                     "ErrorState"
                 ],
                 "data_enum": "ElectronicStabilityControlState",
-                "description": "Electronic Stability Control (ESC) state.\nReturns the current state of ESC. This property must always return a valid state defined in ElectronicStabilityControlState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both ElectronicStabilityControlState (including OTHER, which is not recommended) and ErrorState are supported."
+                "description": "Electronic Stability Control (ESC) state.\nReturns the current state of ESC. This property must always return a valid state defined in ElectronicStabilityControlState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both ElectronicStabilityControlState (including OTHER, which is not recommended) and ErrorState are supported.\nIf {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):\nFor the global area ID (0), {@code getSupportedValuesList} must return a {@code SupportedValuesListResult} that contains supported values unless all states of both ElectronicStabilityControlState (including OTHER, which is not recommended) and ErrorState are supported.\nAt boot, supportedEnumValues is equal to the supported values list."
+            },
+            {
+                "name": "Turn signal light state.",
+                "value": 289408016,
+                "data_enums": [
+                    "VehicleTurnSignal"
+                ],
+                "data_enum": "VehicleTurnSignal",
+                "description": "Turn signal light state.\nThis property must communicate the actual state of the turn signal lights.\nExamples: 1) Left turn signal light is currently pulsing, right turn signal light is currently off. This property must return VehicleTurnSignal.LEFT while the light is on during the pulse, and VehicleTurnSignal.NONE when it is off during the pulse. 2) Right turn signal light is currently pulsing, left turn signal light is currently off. This property must return VehicleTurnSignal.RIGHT while the light is on during the pulse, and VehicleTurnSignal.NONE when it is off during the pulse. 3) Both turn signal lights are currently pulsing (e.g. when hazard lights switch is on). This property must return VehicleTurnSignal.LEFT | VehicleTurnSignal.RIGHT while the lights are on during the pulse, and VehicleTurnSignal.NONE when they are off during the pulse.\nNote that this property uses VehicleTurnSignal as a bit flag, unlike TURN_SIGNAL_SWITCH, which uses it like a regular enum. This means this property can support ORed together values in VehicleTurnSignal.\nThis is different from the function of TURN_SIGNAL_SWITCH, which must communicate the state of the turn signal lever\/switch.\nThis property is a replacement to the TURN_SIGNAL_STATE property, which is now deprecated."
+            },
+            {
+                "name": "Turn signal switch.",
+                "value": 289408017,
+                "data_enums": [
+                    "VehicleTurnSignal"
+                ],
+                "data_enum": "VehicleTurnSignal",
+                "description": "Turn signal switch.\nThis property must communicate the state of the turn signal lever\/switch. This is different from the function of TURN_SIGNAL_LIGHT_STATE, which must communicate the actual state of the turn signal lights.\nNote that this property uses VehicleTurnSignal as a regular enum, unlike TURN_SIGNAL_LIGHT_STATE, which uses it like a bit flag. This means this property cannot support ORed together values in VehicleTurnSignal.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Fan speed setting",
@@ -322,7 +394,7 @@
                     "VehicleHvacFanDirection"
                 ],
                 "data_enum": "VehicleHvacFanDirection",
-                "description": "Fan direction setting\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
+                "description": "Fan direction setting\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only.\nThe supported hvac fan direction is exposed through {@code HVAC_FAN_DIRECTION_AVAILABLE} property. Caller should not call {@code getSupportedValuesList}, or use {@code VehicleAreaConfig#supportedEnumValues}."
             },
             {
                 "name": "HVAC current temperature.",
@@ -476,7 +548,11 @@
             {
                 "name": "Speed units for display",
                 "value": 289408517,
-                "description": "Speed units for display\nIndicates type of units the car is using to display speed to user. Eg. m\/s, km\/h, or mph.\nVehiclePropConfig.configArray is used to indicate the supported speed display units. Pressure units are defined in VehicleUnit. For example: configArray[0] = METER_PER_SEC configArray[1] = MILES_PER_HOUR configArray[2] = KILOMETERS_PER_HOUR\nIf updating VEHICLE_SPEED_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties, then their values must be updated and communicated to the AAOS framework as well.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
+                "data_enums": [
+                    "VehicleUnit"
+                ],
+                "data_enum": "VehicleUnit",
+                "description": "Speed units for display\nIndicates type of units the car is using to display speed to user. Eg. m\/s, km\/h, or mph.\nVehiclePropConfig.configArray is used to indicate the supported speed display units. Pressure units are defined in VehicleUnit. For example: configArray[0] = METER_PER_SEC configArray[1] = MILES_PER_HOUR configArray[2] = KILOMETERS_PER_HOUR\nIf {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):\n{@code VehicleAreaConfig.HasSupportedValueInfo.hasSupportedValuesList} for the global area ID (0) must be {@code true}.\n{@code getSupportedValuesLists} for [VEHICLE_SPEED_DISPLAY_UNITS, areaId=0] must return a {@code SupportedValuesListResult} that contains non-null {@code supportedValuesList}, e.g. [METER_PER_SEC, MILES_PER_HOUR, KILOMETERS_PER_HOUR].\nAt boot, the values in the config array are equal to the supported values list.\n\nIf updating VEHICLE_SPEED_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties, then their values must be updated and communicated to the AAOS framework as well.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EXTERNAL_CAR_TIME",
@@ -1352,7 +1428,16 @@
                     "VehicleAutonomousState"
                 ],
                 "data_enum": "VehicleAutonomousState",
-                "description": "Current state of vehicle autonomy.\nDefines the level of autonomy currently engaged in the vehicle from the J3016_202104 revision of the SAE standard levels 0-5, with 0 representing no autonomy and 5 representing full driving automation. These levels should be used in accordance with the standards defined in https:\/\/www.sae.org\/standards\/content\/j3016_202104\/ and https:\/\/www.sae.org\/blog\/sae-j3016-update\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of VehicleAutonomousState are supported."
+                "description": "Current state of vehicle autonomy.\nDefines the level of autonomy currently engaged in the vehicle from the J3016_202104 revision of the SAE standard levels 0-5, with 0 representing no autonomy and 5 representing full driving automation.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of VehicleAutonomousState are supported."
+            },
+            {
+                "name": "VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL",
+                "value": 289410895,
+                "data_enums": [
+                    "VehicleAutonomousState"
+                ],
+                "data_enum": "VehicleAutonomousState",
+                "description": "Target state of vehicle autonomy.\nDefines the level of autonomy being targeted by the vehicle from the J3016_202104 revision of the SAE standard levels 0-5, with 0 representing no autonomy and 5 representing full driving automation.\nFor example, suppose the vehicle is currently in a Level 3 state of automation and wants to give the driver full manual control (i.e. Level 0) as soon as it's safe to do so. In this scenario, this property must be set to VehicleAutonomousState.LEVEL_0. Similarly, if the vehicle is currently in Level 1 state of automation and wants to go up to Level 2, this property must be set to VehicleAutonomousState.LEVEL_2. If the vehicle has already reached and is currently in the target level of autonomy, this property must be equal to the value of VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL.\nFor the global area ID (0), the SupportedValuesListResult#supportedValuesList array must be defined unless all states of VehicleAutonomousState are supported. These values must match the values in supportedValuesList of VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL.\nFor the property that communicates the current state of autonomy, see VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL."
             },
             {
                 "name": "CAMERA_SERVICE_CURRENT_STATE",
@@ -2192,6 +2277,14 @@
                 "value": 11
             },
             {
+                "name": "SAE_J3400_AC",
+                "value": 8
+            },
+            {
+                "name": "SAE_J3400_DC",
+                "value": 9
+            },
+            {
                 "name": "OTHER",
                 "value": 101
             }
@@ -2950,6 +3043,152 @@
         ]
     },
     {
+        "name": "VehicleSizeClass",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "EPA_TWO_SEATER",
+                "value": 256
+            },
+            {
+                "name": "EPA_MINICOMPACT",
+                "value": 257
+            },
+            {
+                "name": "EPA_SUBCOMPACT",
+                "value": 258
+            },
+            {
+                "name": "EPA_COMPACT",
+                "value": 259
+            },
+            {
+                "name": "EPA_MIDSIZE",
+                "value": 260
+            },
+            {
+                "name": "EPA_LARGE",
+                "value": 261
+            },
+            {
+                "name": "EPA_SMALL_STATION_WAGON",
+                "value": 262
+            },
+            {
+                "name": "EPA_MIDSIZE_STATION_WAGON",
+                "value": 263
+            },
+            {
+                "name": "EPA_LARGE_STATION_WAGON",
+                "value": 264
+            },
+            {
+                "name": "EPA_SMALL_PICKUP_TRUCK",
+                "value": 265
+            },
+            {
+                "name": "EPA_STANDARD_PICKUP_TRUCK",
+                "value": 266
+            },
+            {
+                "name": "EPA_VAN",
+                "value": 267
+            },
+            {
+                "name": "EPA_MINIVAN",
+                "value": 268
+            },
+            {
+                "name": "EPA_SMALL_SUV",
+                "value": 269
+            },
+            {
+                "name": "EPA_STANDARD_SUV",
+                "value": 270
+            },
+            {
+                "name": "EU_A_SEGMENT",
+                "value": 512
+            },
+            {
+                "name": "EU_B_SEGMENT",
+                "value": 513
+            },
+            {
+                "name": "EU_C_SEGMENT",
+                "value": 514
+            },
+            {
+                "name": "EU_D_SEGMENT",
+                "value": 515
+            },
+            {
+                "name": "EU_E_SEGMENT",
+                "value": 516
+            },
+            {
+                "name": "EU_F_SEGMENT",
+                "value": 517
+            },
+            {
+                "name": "EU_J_SEGMENT",
+                "value": 518
+            },
+            {
+                "name": "EU_M_SEGMENT",
+                "value": 519
+            },
+            {
+                "name": "EU_S_SEGMENT",
+                "value": 520
+            },
+            {
+                "name": "JPN_KEI",
+                "value": 768
+            },
+            {
+                "name": "JPN_SMALL_SIZE",
+                "value": 769
+            },
+            {
+                "name": "JPN_NORMAL_SIZE",
+                "value": 770
+            },
+            {
+                "name": "US_GVWR_CLASS_1_CV",
+                "value": 1024
+            },
+            {
+                "name": "US_GVWR_CLASS_2_CV",
+                "value": 1025
+            },
+            {
+                "name": "US_GVWR_CLASS_3_CV",
+                "value": 1026
+            },
+            {
+                "name": "US_GVWR_CLASS_4_CV",
+                "value": 1027
+            },
+            {
+                "name": "US_GVWR_CLASS_5_CV",
+                "value": 1028
+            },
+            {
+                "name": "US_GVWR_CLASS_6_CV",
+                "value": 1029
+            },
+            {
+                "name": "US_GVWR_CLASS_7_CV",
+                "value": 1030
+            },
+            {
+                "name": "US_GVWR_CLASS_8_CV",
+                "value": 1031
+            }
+        ]
+    },
+    {
         "name": "VehicleTurnSignal",
         "package": "android.hardware.automotive.vehicle",
         "values": [
diff --git a/automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp b/automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
index 7ff27a4..612ed64 100644
--- a/automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
@@ -19,10 +19,19 @@
 }
 
 cc_library_headers {
+    name: "IVehicleGeneratedHeaders-V3-default",
+    vendor_available: true,
+    local_include_dirs: ["."],
+    export_include_dirs: ["."],
+    defaults: ["VehicleHalInterfaceDefaults-V3"],
+    host_supported: true,
+}
+
+cc_library_headers {
     name: "IVehicleGeneratedHeaders-V3",
     vendor_available: true,
     local_include_dirs: ["."],
     export_include_dirs: ["."],
-    defaults: ["VehicleHalInterfaceDefaults"],
+    defaults: ["VehicleHalInterfaceDefaults-V3"],
     host_supported: true,
 }
diff --git a/automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h
index 6d07fe5..8441af3 100644
--- a/automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h
@@ -49,11 +49,15 @@
         {VehicleProperty::INFO_DRIVER_SEAT, VehiclePropertyAccess::READ},
         {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, VehiclePropertyAccess::READ},
         {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MODEL_TRIM, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_VEHICLE_SIZE_CLASS, VehiclePropertyAccess::READ},
         {VehicleProperty::PERF_ODOMETER, VehiclePropertyAccess::READ},
         {VehicleProperty::PERF_VEHICLE_SPEED, VehiclePropertyAccess::READ},
         {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyAccess::READ},
         {VehicleProperty::PERF_STEERING_ANGLE, VehiclePropertyAccess::READ},
         {VehicleProperty::PERF_REAR_STEERING_ANGLE, VehiclePropertyAccess::READ},
+        {VehicleProperty::INSTANTANEOUS_FUEL_ECONOMY, VehiclePropertyAccess::READ},
+        {VehicleProperty::INSTANTANEOUS_EV_EFFICIENCY, VehiclePropertyAccess::READ},
         {VehicleProperty::ENGINE_COOLANT_TEMP, VehiclePropertyAccess::READ},
         {VehicleProperty::ENGINE_OIL_LEVEL, VehiclePropertyAccess::READ},
         {VehicleProperty::ENGINE_OIL_TEMP, VehiclePropertyAccess::READ},
@@ -70,8 +74,14 @@
         {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess::READ},
         {VehicleProperty::TIRE_PRESSURE, VehiclePropertyAccess::READ},
         {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyAccess::READ},
+        {VehicleProperty::BRAKE_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyAccess::READ},
+        {VehicleProperty::BRAKE_PAD_WEAR_PERCENTAGE, VehiclePropertyAccess::READ},
+        {VehicleProperty::BRAKE_FLUID_LEVEL_LOW, VehiclePropertyAccess::READ},
+        {VehicleProperty::VEHICLE_PASSIVE_SUSPENSION_HEIGHT, VehiclePropertyAccess::READ},
         {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::IMPACT_DETECTED, VehiclePropertyAccess::READ},
+        {VehicleProperty::VEHICLE_HORN_ENGAGED, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::GEAR_SELECTION, VehiclePropertyAccess::READ},
         {VehicleProperty::CURRENT_GEAR, VehiclePropertyAccess::READ},
         {VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyAccess::READ},
@@ -86,6 +96,8 @@
         {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TURN_SIGNAL_LIGHT_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TURN_SIGNAL_SWITCH, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess::READ},
@@ -262,6 +274,7 @@
         {VehicleProperty::VEHICLE_IN_USE, VehiclePropertyAccess::READ_WRITE},
         {VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyAccess::WRITE},
         {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL, VehiclePropertyAccess::READ},
         {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess::WRITE},
         {VehicleProperty::PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyAccess::READ},
         {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
diff --git a/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
index 5ecee95..3775f18 100644
--- a/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
@@ -49,11 +49,15 @@
         {VehicleProperty::INFO_DRIVER_SEAT, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MODEL_TRIM, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_VEHICLE_SIZE_CLASS, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::PERF_ODOMETER, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::PERF_VEHICLE_SPEED, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::PERF_STEERING_ANGLE, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::PERF_REAR_STEERING_ANGLE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::INSTANTANEOUS_FUEL_ECONOMY, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::INSTANTANEOUS_EV_EFFICIENCY, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::ENGINE_COOLANT_TEMP, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::ENGINE_OIL_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::ENGINE_OIL_TEMP, VehiclePropertyChangeMode::CONTINUOUS},
@@ -70,8 +74,14 @@
         {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::TIRE_PRESSURE, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::BRAKE_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::BRAKE_PAD_WEAR_PERCENTAGE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::BRAKE_FLUID_LEVEL_LOW, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_PASSIVE_SUSPENSION_HEIGHT, VehiclePropertyChangeMode::CONTINUOUS},
         {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::IMPACT_DETECTED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_HORN_ENGAGED, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::GEAR_SELECTION, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::CURRENT_GEAR, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyChangeMode::ON_CHANGE},
@@ -86,6 +96,8 @@
         {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TURN_SIGNAL_LIGHT_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TURN_SIGNAL_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode::ON_CHANGE},
@@ -262,6 +274,7 @@
         {VehicleProperty::VEHICLE_IN_USE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyChangeMode::ON_CHANGE},
         {VehicleProperty::PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyChangeMode::STATIC},
         {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
diff --git a/automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h
index 8b9c1bd..0a28b68 100644
--- a/automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h
@@ -48,11 +48,15 @@
         {VehicleProperty::INFO_DRIVER_SEAT, 2},
         {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, 2},
         {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, 2},
+        {VehicleProperty::INFO_MODEL_TRIM, 4},
+        {VehicleProperty::INFO_VEHICLE_SIZE_CLASS, 4},
         {VehicleProperty::PERF_ODOMETER, 2},
         {VehicleProperty::PERF_VEHICLE_SPEED, 2},
         {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, 2},
         {VehicleProperty::PERF_STEERING_ANGLE, 2},
         {VehicleProperty::PERF_REAR_STEERING_ANGLE, 2},
+        {VehicleProperty::INSTANTANEOUS_FUEL_ECONOMY, 4},
+        {VehicleProperty::INSTANTANEOUS_EV_EFFICIENCY, 4},
         {VehicleProperty::ENGINE_COOLANT_TEMP, 2},
         {VehicleProperty::ENGINE_OIL_LEVEL, 2},
         {VehicleProperty::ENGINE_OIL_TEMP, 2},
@@ -69,8 +73,14 @@
         {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, 3},
         {VehicleProperty::TIRE_PRESSURE, 2},
         {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, 2},
+        {VehicleProperty::ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE, 4},
+        {VehicleProperty::BRAKE_PEDAL_COMPRESSION_PERCENTAGE, 4},
+        {VehicleProperty::BRAKE_PAD_WEAR_PERCENTAGE, 4},
+        {VehicleProperty::BRAKE_FLUID_LEVEL_LOW, 4},
+        {VehicleProperty::VEHICLE_PASSIVE_SUSPENSION_HEIGHT, 4},
         {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, 2},
         {VehicleProperty::IMPACT_DETECTED, 3},
+        {VehicleProperty::VEHICLE_HORN_ENGAGED, 4},
         {VehicleProperty::GEAR_SELECTION, 2},
         {VehicleProperty::CURRENT_GEAR, 2},
         {VehicleProperty::PARKING_BRAKE_ON, 2},
@@ -85,6 +95,8 @@
         {VehicleProperty::EV_STOPPING_MODE, 2},
         {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, 3},
         {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, 3},
+        {VehicleProperty::TURN_SIGNAL_LIGHT_STATE, 4},
+        {VehicleProperty::TURN_SIGNAL_SWITCH, 4},
         {VehicleProperty::HVAC_FAN_SPEED, 2},
         {VehicleProperty::HVAC_FAN_DIRECTION, 2},
         {VehicleProperty::HVAC_TEMPERATURE_CURRENT, 2},
@@ -261,6 +273,7 @@
         {VehicleProperty::VEHICLE_IN_USE, 2},
         {VehicleProperty::CLUSTER_HEARTBEAT, 3},
         {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, 3},
+        {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL, 4},
         {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, 3},
         {VehicleProperty::PER_DISPLAY_MAX_BRIGHTNESS, 3},
         {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 2},
diff --git a/automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java
index e9f35a5..1a68d4d 100644
--- a/automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java
@@ -42,11 +42,15 @@
         Map.entry(VehicleProperty.INFO_DRIVER_SEAT, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MODEL_TRIM, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_VEHICLE_SIZE_CLASS, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.PERF_ODOMETER, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INSTANTANEOUS_FUEL_ECONOMY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INSTANTANEOUS_EV_EFFICIENCY, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehiclePropertyAccess.READ),
@@ -63,8 +67,14 @@
         Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.BRAKE_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.BRAKE_PAD_WEAR_PERCENTAGE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.BRAKE_FLUID_LEVEL_LOW, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.VEHICLE_PASSIVE_SUSPENSION_HEIGHT, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.IMPACT_DETECTED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.VEHICLE_HORN_ENGAGED, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyAccess.READ),
@@ -79,6 +89,8 @@
         Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TURN_SIGNAL_LIGHT_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TURN_SIGNAL_SWITCH, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess.READ),
@@ -255,6 +267,7 @@
         Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyAccess.READ_WRITE),
         Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyAccess.WRITE),
         Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess.WRITE),
         Map.entry(VehicleProperty.PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyAccess.READ),
         Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
diff --git a/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
index 3fb52b7..a0dab66 100644
--- a/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
@@ -42,11 +42,15 @@
         Map.entry(VehicleProperty.INFO_DRIVER_SEAT, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MODEL_TRIM, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_VEHICLE_SIZE_CLASS, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.PERF_ODOMETER, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.INSTANTANEOUS_FUEL_ECONOMY, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.INSTANTANEOUS_EV_EFFICIENCY, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehiclePropertyChangeMode.CONTINUOUS),
@@ -63,8 +67,14 @@
         Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.BRAKE_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.BRAKE_PAD_WEAR_PERCENTAGE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.BRAKE_FLUID_LEVEL_LOW, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_PASSIVE_SUSPENSION_HEIGHT, VehiclePropertyChangeMode.CONTINUOUS),
         Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.IMPACT_DETECTED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_HORN_ENGAGED, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyChangeMode.ON_CHANGE),
@@ -79,6 +89,8 @@
         Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TURN_SIGNAL_LIGHT_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TURN_SIGNAL_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode.ON_CHANGE),
@@ -255,6 +267,7 @@
         Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyChangeMode.ON_CHANGE),
         Map.entry(VehicleProperty.PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyChangeMode.STATIC),
         Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
diff --git a/automotive/vehicle/aidl/generated_lib/4/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/EnumForVehicleProperty.java
index 0f86bfa..7ab14ec 100644
--- a/automotive/vehicle/aidl/generated_lib/4/java/EnumForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/4/java/EnumForVehicleProperty.java
@@ -36,6 +36,7 @@
         Map.entry(VehicleProperty.INFO_EV_PORT_LOCATION, List.of(PortLocationType.class)),
         Map.entry(VehicleProperty.INFO_DRIVER_SEAT, List.of(VehicleAreaSeat.class)),
         Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, List.of(PortLocationType.class)),
+        Map.entry(VehicleProperty.INFO_VEHICLE_SIZE_CLASS, List.of(VehicleSizeClass.class)),
         Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, List.of(VehicleOilLevel.class)),
         Map.entry(VehicleProperty.IMPACT_DETECTED, List.of(ImpactSensorLocation.class)),
         Map.entry(VehicleProperty.GEAR_SELECTION, List.of(VehicleGear.class)),
@@ -44,6 +45,8 @@
         Map.entry(VehicleProperty.IGNITION_STATE, List.of(VehicleIgnitionState.class)),
         Map.entry(VehicleProperty.EV_STOPPING_MODE, List.of(EvStoppingMode.class)),
         Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_STATE, List.of(ElectronicStabilityControlState.class, ErrorState.class)),
+        Map.entry(VehicleProperty.TURN_SIGNAL_LIGHT_STATE, List.of(VehicleTurnSignal.class)),
+        Map.entry(VehicleProperty.TURN_SIGNAL_SWITCH, List.of(VehicleTurnSignal.class)),
         Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, List.of(VehicleHvacFanDirection.class)),
         Map.entry(VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS, List.of(VehicleUnit.class)),
         Map.entry(VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE, List.of(VehicleHvacFanDirection.class)),
@@ -51,6 +54,7 @@
         Map.entry(VehicleProperty.FUEL_VOLUME_DISPLAY_UNITS, List.of(VehicleUnit.class)),
         Map.entry(VehicleProperty.TIRE_PRESSURE_DISPLAY_UNITS, List.of(VehicleUnit.class)),
         Map.entry(VehicleProperty.EV_BATTERY_DISPLAY_UNITS, List.of(VehicleUnit.class)),
+        Map.entry(VehicleProperty.VEHICLE_SPEED_DISPLAY_UNITS, List.of(VehicleUnit.class)),
         Map.entry(VehicleProperty.HW_ROTARY_INPUT, List.of(RotaryInputType.class)),
         Map.entry(VehicleProperty.HW_CUSTOM_INPUT, List.of(CustomInputType.class)),
         Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, List.of(VehicleLightState.class)),
@@ -85,6 +89,7 @@
         Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, List.of(GsrComplianceRequirementType.class)),
         Map.entry(VehicleProperty.SHUTDOWN_REQUEST, List.of(VehicleApPowerStateShutdownParam.class)),
         Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, List.of(VehicleAutonomousState.class)),
+        Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL, List.of(VehicleAutonomousState.class)),
         Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, List.of(CameraServiceState.class)),
         Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, List.of(AutomaticEmergencyBrakingState.class, ErrorState.class)),
         Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, List.of(ForwardCollisionWarningState.class, ErrorState.class)),
diff --git a/automotive/vehicle/aidl/impl/3/Android.bp b/automotive/vehicle/aidl/impl/3/Android.bp
new file mode 100644
index 0000000..e575061
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/Android.bp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_defaults {
+    name: "VehicleHalDefaults-V3",
+    static_libs: [
+        "android-automotive-large-parcelable-lib",
+        "libmath",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libutils",
+    ],
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+        "-Wthread-safety",
+    ],
+    defaults: [
+        "VehicleHalInterfaceDefaults-V3",
+        "android-automotive-large-parcelable-defaults",
+    ],
+}
diff --git a/automotive/vehicle/aidl/impl/3/README.md b/automotive/vehicle/aidl/impl/3/README.md
new file mode 100644
index 0000000..bf80122
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/README.md
@@ -0,0 +1,58 @@
+# AIDL VHAL libraries and reference implementation.
+---
+
+This directory stores the libraries useful for implementing vendor AIDL VHAL.
+This directory also stores a reference fake implementation for AIDL VHAL.
+
+## default_config
+
+Stores the default vehicle property configurations for reference vehicle HAL.
+Vendor implementation could copy this library but must update the configuration
+to meet their own requirements, e.g. enable or disable certain properties or
+update the initial value for certain properties.
+
+##	fake_impl
+
+Contains libraries used specifically for the fake reference VHAL implementation.
+These libraries are for test only and must not be directly used for vendor
+VHAL implementation.
+
+These libraries contain test-spcific logic and must not run directly on a real
+vehicle.
+
+## grpc
+
+Stores code for GRPC based VHAL implementation.
+
+## hardware
+
+Defines an interface `IVehicleHardware.h` which vendor must implement for
+vehicle-specific logic if they want to follow our reference VHAL design.
+
+## proto
+
+Stores Some protobuf files translated from AIDL VHAL interface types. These
+files are used in GRPC VHAL implementation.
+
+## utils
+
+Defines a library `VehicleHalUtils-V3` which provides useful utility functions for
+VHAL implementation. Vendor VHAL could use this library.
+
+## vhal
+
+Defines a library `DefaultVehicleHal` which provides generic logic for all VHAL
+implementations (including reference VHAL). Vendor VHAL implementation could
+use this library, along with their own implementation for `IVehicleHardware`
+interface.
+
+Also defines a binary `android.hardware.automotive.vehicle@V3-default-service`
+which is the reference VHAL implementation. It implements `IVehicle.aidl`
+interface. It uses `DefaultVehicleHal`, along with `FakeVehicleHardware`
+(in fake_impl). It simulates the vehicle bus interaction by using an
+in-memory map. Meaning that all properties (except for some special ones) are
+just written into a hash map and read from a hash map without relying on any
+hardware. As a result, the reference implementation can run on emulator or
+any host environment.
+
+Vendor must not directly use the reference implementation for a real vehicle.
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/Android.bp
new file mode 100644
index 0000000..727c193
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/Android.bp
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "VehicleHalJsonConfigLoader-V3",
+    vendor: true,
+    srcs: ["src/*.cpp"],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: ["VehicleHalUtils-V3"],
+    header_libs: [
+        "IVehicleGeneratedHeaders-V3-default",
+    ],
+    shared_libs: ["libjsoncpp"],
+}
+
+cc_library {
+    name: "VehicleHalJsonConfigLoaderEnableTestProperties-V3",
+    vendor: true,
+    srcs: [
+        "src/*.cpp",
+        ":VhalTestVendorProperties-V3",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: ["VehicleHalUtils-V3"],
+    header_libs: [
+        "IVehicleGeneratedHeaders-V3-default",
+        "libbinder_headers",
+    ],
+    cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
+    shared_libs: ["libjsoncpp"],
+    host_supported: true,
+}
+
+cc_library_headers {
+    name: "VehicleHalJsonConfigLoaderHeaders-V3",
+    vendor: true,
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: ["VehicleHalUtils-V3"],
+    header_libs: [
+        "IVehicleGeneratedHeaders-V3-default",
+    ],
+    shared_libs: ["libjsoncpp"],
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h b/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/include/ConfigDeclaration.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h
rename to automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/include/ConfigDeclaration.h
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h b/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/include/JsonConfigLoader.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
rename to automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/include/JsonConfigLoader.h
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
rename to automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
diff --git a/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/test/Android.bp b/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/test/Android.bp
new file mode 100644
index 0000000..1ed4df7
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/test/Android.bp
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package {
+    default_team: "trendy_team_aaos_framework",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "JsonConfigLoaderUnitTest-V3",
+    vendor: true,
+    srcs: ["*.cpp"],
+    static_libs: [
+        "VehicleHalJsonConfigLoader-V3",
+        "VehicleHalUtils-V3",
+        "libgtest",
+        "libjsoncpp",
+    ],
+    defaults: ["VehicleHalDefaults-V3"],
+    test_suites: ["device-tests"],
+}
+
+cc_test {
+    name: "JsonConfigLoaderUnitTestEnableTestProperties-V3",
+    vendor: true,
+    srcs: ["*.cpp"],
+    static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties-V3",
+        "VehicleHalUtils-V3",
+        "libgtest",
+        "libjsoncpp",
+    ],
+    defaults: ["VehicleHalDefaults-V3"],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp b/automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
rename to automotive/vehicle/aidl/impl/3/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
diff --git a/automotive/vehicle/aidl/impl/default_config/TEST_MAPPING b/automotive/vehicle/aidl/impl/3/default_config/TEST_MAPPING
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/TEST_MAPPING
rename to automotive/vehicle/aidl/impl/3/default_config/TEST_MAPPING
diff --git a/automotive/vehicle/aidl/impl/3/default_config/config/Android.bp b/automotive/vehicle/aidl/impl/3/default_config/config/Android.bp
new file mode 100644
index 0000000..bf1aa90
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/default_config/config/Android.bp
@@ -0,0 +1,68 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+filegroup {
+    name: "VehicleHalDefaultProperties_JSON-V3",
+    srcs: ["DefaultProperties.json"],
+}
+
+filegroup {
+    name: "VehicleHalTestProperties_JSON-V3",
+    srcs: ["TestProperties.json"],
+}
+
+filegroup {
+    name: "VehicleHalVendorClusterTestProperties_JSON-V3",
+    srcs: ["VendorClusterTestProperties.json"],
+}
+
+prebuilt_etc {
+    name: "Prebuilt_VehicleHalDefaultProperties_JSON-V3",
+    filename_from_src: true,
+    src: "DefaultProperties.json",
+    sub_dir: "automotive/vhalconfig/3/",
+    vendor: true,
+}
+
+prebuilt_etc {
+    name: "Prebuilt_VehicleHalTestProperties_JSON-V3",
+    filename_from_src: true,
+    src: "TestProperties.json",
+    sub_dir: "automotive/vhalconfig/3/",
+    vendor: true,
+}
+
+prebuilt_etc {
+    name: "Prebuilt_VehicleHalVendorClusterTestProperties_JSON-V3",
+    filename_from_src: true,
+    src: "VendorClusterTestProperties.json",
+    sub_dir: "automotive/vhalconfig/3/",
+    vendor: true,
+}
+
+prebuilt_etc_host {
+    name: "Host_Prebuilt_VehicleHalDefaultProperties_JSON-V3",
+    filename_from_src: true,
+    src: "DefaultProperties.json",
+    relative_install_path: "automotive/vhalconfig/3/",
+}
+
+prebuilt_etc_host {
+    name: "Host_Prebuilt_VehicleHalTestProperties_JSON-V3",
+    filename_from_src: true,
+    src: "TestProperties.json",
+    relative_install_path: "automotive/vhalconfig/3/",
+}
+
+prebuilt_etc_host {
+    name: "Host_Prebuilt_VehicleHalVendorClusterTestProperties_JSON-V3",
+    filename_from_src: true,
+    src: "VendorClusterTestProperties.json",
+    relative_install_path: "automotive/vhalconfig/3/",
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/3/default_config/config/DefaultProperties.json
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
rename to automotive/vehicle/aidl/impl/3/default_config/config/DefaultProperties.json
diff --git a/automotive/vehicle/aidl/impl/default_config/config/README.md b/automotive/vehicle/aidl/impl/3/default_config/config/README.md
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/config/README.md
rename to automotive/vehicle/aidl/impl/3/default_config/config/README.md
diff --git a/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json b/automotive/vehicle/aidl/impl/3/default_config/config/TestProperties.json
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/config/TestProperties.json
rename to automotive/vehicle/aidl/impl/3/default_config/config/TestProperties.json
diff --git a/automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json b/automotive/vehicle/aidl/impl/3/default_config/config/VendorClusterTestProperties.json
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json
rename to automotive/vehicle/aidl/impl/3/default_config/config/VendorClusterTestProperties.json
diff --git a/automotive/vehicle/aidl/impl/3/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/3/default_config/test/Android.bp
new file mode 100644
index 0000000..d125d43
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/default_config/test/Android.bp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_aaos_framework",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "VehicleHalDefaultConfigTest-V3",
+    vendor: true,
+    defaults: ["VehicleHalDefaults-V3"],
+    srcs: ["*.cpp"],
+    static_libs: [
+        "VehicleHalJsonConfigLoader-V3",
+        "VehicleHalUtils-V3",
+        "libgmock",
+        "libgtest",
+        "libjsoncpp",
+    ],
+    header_libs: [
+        "IVehicleGeneratedHeaders-V3-default",
+    ],
+    data: [
+        ":VehicleHalDefaultProperties_JSON-V3",
+    ],
+    test_suites: ["device-tests"],
+}
+
+cc_test {
+    name: "VehicleHalDefaultConfigTestEnableTestProperties-V3",
+    vendor: true,
+    defaults: ["VehicleHalDefaults-V3"],
+    srcs: ["*.cpp"],
+    static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties-V3",
+        "VehicleHalUtils-V3",
+        "libgmock",
+        "libgtest",
+        "libjsoncpp",
+    ],
+    cflags: [
+        "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
+    ],
+    header_libs: [
+        "IVehicleGeneratedHeaders-V3-default",
+    ],
+    data: [
+        ":VehicleHalDefaultProperties_JSON-V3",
+        ":VehicleHalTestProperties_JSON-V3",
+        ":VehicleHalVendorClusterTestProperties_JSON-V3",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp b/automotive/vehicle/aidl/impl/3/default_config/test/DefaultConfigTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
rename to automotive/vehicle/aidl/impl/3/default_config/test/DefaultConfigTest.cpp
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/Android.bp b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/Android.bp
new file mode 100644
index 0000000..10e4b7e
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/Android.bp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "FakeVehicleHalValueGenerators-V3",
+    vendor: true,
+    srcs: ["src/*.cpp"],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: [
+        "VehicleHalUtils-V3",
+        "FakeObd2Frame-V3",
+    ],
+    shared_libs: [
+        "libjsoncpp",
+    ],
+    host_supported: true,
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/FakeValueGenerator.h b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/include/FakeValueGenerator.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/FakeValueGenerator.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/include/FakeValueGenerator.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/include/GeneratorHub.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/include/GeneratorHub.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/src/GeneratorHub.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/src/GeneratorHub.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/Android.bp b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/Android.bp
new file mode 100644
index 0000000..623417b
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/Android.bp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_automotive",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "FakeVehicleHalValueGeneratorsTest-V3",
+    vendor: true,
+    srcs: ["*.cpp"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: [
+        "VehicleHalUtils-V3",
+        "FakeVehicleHalValueGenerators-V3",
+        "FakeObd2Frame-V3",
+        "libjsoncpp",
+    ],
+    data: [
+        ":FakeVehicleHalValueGeneratorsTestFiles-V3",
+    ],
+    test_suites: ["device-tests"],
+}
+
+filegroup {
+    name: "FakeVehicleHalValueGeneratorsTestFiles-V3",
+    srcs: [
+        "prop.json",
+        "prop_different_types.json",
+        "prop_invalid.json",
+    ],
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/prop.json
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
copy to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/prop.json
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/prop_different_types.json b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/prop_different_types.json
new file mode 100644
index 0000000..38cd86b
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/prop_different_types.json
@@ -0,0 +1,74 @@
+[
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 1,
+        "prop": 287310600
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 2,
+        "prop": 289408000
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 3.3,
+        "prop": 291504905
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 4,
+        "prop": 290457096
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": "test",
+        "prop": 286265094
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": [
+            1,
+            2
+        ],
+        "prop": 289476368
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": {
+            "int32Values": [
+                1,
+                2
+            ],
+            "int64Values": [
+                3,
+                4
+            ],
+            "floatValues": [
+                5.5,
+                6.6
+            ],
+            "stringValue": "test"
+        },
+        "prop": 299896626
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": {
+            "int32Values": [
+                1
+            ],
+            "floatValues": [
+                1
+            ]
+        },
+        "prop": 299896064
+    }
+]
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_invalid.json b/automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/prop_invalid.json
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_invalid.json
rename to automotive/vehicle/aidl/impl/3/fake_impl/GeneratorHub/test/prop_invalid.json
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/README.md b/automotive/vehicle/aidl/impl/3/fake_impl/README.md
new file mode 100644
index 0000000..5e1df94
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/README.md
@@ -0,0 +1,28 @@
+# Fake reference AIDL VHAL implementation libraries
+---
+
+This directory stores libraries for implementing a fake reference AIDL VHAL.
+
+WARNING: All the libraries here are for TEST ONLY.
+
+## GeneratorHub
+
+Defines a library `FakeVehicleHalValueGenerators-V3` that could generate fake
+vehicle property values for testing.
+
+## hardware
+
+Defines a fake implementation for device-specifc interface `IVehicleHardware`:
+`FakeVehicleHardware`. This implementation uses a in-memory map for storing
+property values and does not communicate with or depending on any specific
+vehicle bus.
+
+## obd2frame
+
+Defines a library `FakeObd2Frame` that generates fake OBD2 frame for OBD2
+properties.
+
+## userhal
+
+Defines a library `FakeUserHal` that emulates a real User HAL behavior by
+parsing debug commands.
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/Android.bp
new file mode 100644
index 0000000..9b9b4f4
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/Android.bp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "FakeVehicleHardware-V3",
+    vendor: true,
+    srcs: [
+        "src/*.cpp",
+        ":VhalTestVendorProperties-V3",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    cflags: [
+        "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
+    ],
+    defaults: [
+        "VehicleHalDefaults-V3",
+        "FakeVehicleHardwareDefaults-V3",
+    ],
+    whole_static_libs: [
+        "wakeup_client_protos",
+    ],
+    host_supported: true,
+}
+
+cc_defaults {
+    name: "FakeVehicleHardwareDefaults-V3",
+    header_libs: [
+        "IVehicleHardware-V3",
+        "libbinder_headers",
+    ],
+    export_header_lib_headers: ["IVehicleHardware-V3"],
+    static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties-V3",
+        "VehicleHalUtils-V3",
+        "FakeVehicleHalValueGenerators-V3",
+        "FakeObd2Frame-V3",
+        "FakeUserHal-V3",
+    ],
+    required: [
+        "Prebuilt_VehicleHalDefaultProperties_JSON-V3",
+        "Prebuilt_VehicleHalTestProperties_JSON-V3",
+        "Prebuilt_VehicleHalVendorClusterTestProperties_JSON-V3",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libjsoncpp",
+        "libprotobuf-cpp-full",
+    ],
+    export_static_lib_headers: ["VehicleHalUtils-V3"],
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/include/FakeVehicleHardware.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/hardware/include/FakeVehicleHardware.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/src/FakeVehicleHardware.cpp
similarity index 99%
copy from automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
copy to automotive/vehicle/aidl/impl/3/fake_impl/hardware/src/FakeVehicleHardware.cpp
index a6247a7..fbd20c5 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -110,7 +110,7 @@
         toInt(VehiclePropertyType::INT32);
 // The directory for default property configuration file.
 // For config file format, see impl/default_config/config/README.md.
-constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/vhalconfig/";
+constexpr char DEFAULT_CONFIG_DIR[] = "/vendor/etc/automotive/vhalconfig/3/";
 // The directory for property configuration file that overrides the default configuration file.
 // For config file format, see impl/default_config/config/README.md.
 constexpr char OVERRIDE_CONFIG_DIR[] = "/vendor/etc/automotive/vhaloverride/";
@@ -928,8 +928,8 @@
     grpc::ClientContext context;
     auto status = clientStub->IsVehicleInUse(&context, request, &response);
     if (!status.ok()) {
-        return StatusError(StatusCode::TRY_AGAIN) << "Cannot connect to GRPC service "
-                                                  << ", error: " << status.error_message();
+        return StatusError(StatusCode::TRY_AGAIN)
+               << "Cannot connect to GRPC service " << ", error: " << status.error_message();
     }
     auto result = mValuePool->obtainBoolean(response.isvehicleinuse());
     result->prop = toInt(VehicleProperty::VEHICLE_IN_USE);
@@ -946,8 +946,8 @@
     grpc::ClientContext context;
     auto status = clientStub->GetApPowerBootupReason(&context, request, &response);
     if (!status.ok()) {
-        return StatusError(StatusCode::TRY_AGAIN) << "Cannot connect to GRPC service "
-                                                  << ", error: " << status.error_message();
+        return StatusError(StatusCode::TRY_AGAIN)
+               << "Cannot connect to GRPC service " << ", error: " << status.error_message();
     }
     auto result = mValuePool->obtainInt32(response.bootupreason());
     result->prop = toInt(VehicleProperty::AP_POWER_BOOTUP_REASON);
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/Android.bp b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/Android.bp
new file mode 100644
index 0000000..e7e5ba7
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/Android.bp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_aaos_framework",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "FakeVehicleHardwareTest-V3",
+    vendor: true,
+    srcs: [
+        "*.cpp",
+        ":VhalTestVendorProperties-V3",
+    ],
+    cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
+    header_libs: [
+        "IVehicleHardware-V3",
+        "libbinder_headers",
+    ],
+    static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties-V3",
+        "VehicleHalUtils-V3",
+        "FakeVehicleHardware-V3",
+        "FakeVehicleHalValueGenerators-V3",
+        "FakeObd2Frame-V3",
+        "FakeUserHal-V3",
+        "libgtest",
+        "libgmock",
+        "libjsoncpp",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    data: [
+        ":VehicleHalDefaultProperties_JSON-V3",
+        ":VehicleHalTestProperties_JSON-V3",
+        ":VehicleHalVendorClusterTestProperties_JSON-V3",
+        ":FakeVehicleHardwareTestOverrideJson-V3",
+        ":FakeVehicleHardwareTestPropJson-V3",
+    ],
+    defaults: [
+        "VehicleHalDefaults-V3",
+    ],
+    // Need root to use vendor lib: libgrpc++.
+    require_root: true,
+    test_suites: ["device-tests"],
+}
+
+filegroup {
+    name: "FakeVehicleHardwareTestOverrideJson-V3",
+    srcs: ["override/*"],
+}
+
+filegroup {
+    name: "FakeVehicleHardwareTestPropJson-V3",
+    srcs: ["fakedata/prop.json"],
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/fakedata/prop.json
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
rename to automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/fakedata/prop.json
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/override/gear_selection.json
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json
rename to automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/override/gear_selection.json
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json b/automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/override/hvac_temperature_set.json
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json
rename to automotive/vehicle/aidl/impl/3/fake_impl/hardware/test/override/hvac_temperature_set.json
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/Android.bp b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/Android.bp
new file mode 100644
index 0000000..1e71661
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "FakeObd2Frame-V3",
+    vendor: true,
+    srcs: ["src/*.cpp"],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: [
+        "VehicleHalUtils-V3",
+    ],
+    export_static_lib_headers: ["VehicleHalUtils-V3"],
+    host_supported: true,
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/FakeObd2Frame.h b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/include/FakeObd2Frame.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/FakeObd2Frame.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/include/FakeObd2Frame.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/Obd2SensorStore.h b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/include/Obd2SensorStore.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/Obd2SensorStore.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/include/Obd2SensorStore.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/FakeObd2Frame.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/src/FakeObd2Frame.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/FakeObd2Frame.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/src/FakeObd2Frame.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/Obd2SensorStore.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/src/Obd2SensorStore.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/Obd2SensorStore.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/src/Obd2SensorStore.cpp
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/test/Android.bp b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/test/Android.bp
new file mode 100644
index 0000000..8b30477
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/test/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_aaos_framework",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "FakeObd2FrameTest-V3",
+    vendor: true,
+    srcs: ["*.cpp"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: [
+        "FakeObd2Frame-V3",
+        "VehicleHalUtils-V3",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Obd2SensorStoreTest.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/test/Obd2SensorStoreTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Obd2SensorStoreTest.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/obd2frame/test/Obd2SensorStoreTest.cpp
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/userhal/Android.bp b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/Android.bp
new file mode 100644
index 0000000..2adf7c4
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "FakeUserHal-V3",
+    vendor: true,
+    srcs: ["src/*.cpp"],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: [
+        "VehicleHalUtils-V3",
+    ],
+    export_static_lib_headers: ["VehicleHalUtils-V3"],
+    host_supported: true,
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/include/FakeUserHal.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/userhal/include/FakeUserHal.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/UserHalHelper.h b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/include/UserHalHelper.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/userhal/include/UserHalHelper.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/userhal/include/UserHalHelper.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/UserHalTypes.h b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/include/UserHalTypes.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/userhal/include/UserHalTypes.h
rename to automotive/vehicle/aidl/impl/3/fake_impl/userhal/include/UserHalTypes.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/src/FakeUserHal.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/userhal/src/FakeUserHal.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/src/UserHalHelper.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/src/UserHalHelper.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/userhal/src/UserHalHelper.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/userhal/src/UserHalHelper.cpp
diff --git a/automotive/vehicle/aidl/impl/3/fake_impl/userhal/test/Android.bp b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/test/Android.bp
new file mode 100644
index 0000000..55178dc
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/test/Android.bp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_aaos_framework",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "FakeUserHalTest-V3",
+    vendor: true,
+    srcs: ["*.cpp"],
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: [
+        "FakeUserHal-V3",
+        "VehicleHalUtils-V3",
+        "libgtest",
+        "libgmock",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/test/UserHalHelper_test.cpp b/automotive/vehicle/aidl/impl/3/fake_impl/userhal/test/UserHalHelper_test.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/userhal/test/UserHalHelper_test.cpp
rename to automotive/vehicle/aidl/impl/3/fake_impl/userhal/test/UserHalHelper_test.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/Android.bp b/automotive/vehicle/aidl/impl/3/grpc/Android.bp
similarity index 73%
copy from automotive/vehicle/aidl/impl/grpc/Android.bp
copy to automotive/vehicle/aidl/impl/3/grpc/Android.bp
index 7a8da59..6fa2bfa 100644
--- a/automotive/vehicle/aidl/impl/grpc/Android.bp
+++ b/automotive/vehicle/aidl/impl/3/grpc/Android.bp
@@ -17,16 +17,16 @@
 }
 
 genrule {
-    name: "VehicleServerProtoStub_h@default-grpc",
+    name: "VehicleServerProtoStub_h@default-grpc-V3",
     tools: [
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_opt=generate_mock_code=true --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/3/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_opt=generate_mock_code=true --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
         "proto/VehicleServer.proto",
         ":libprotobuf-internal-protos",
-        ":VehicleHalProtoFiles",
+        ":VehicleHalProtoFiles-V3",
     ],
     out: [
         "VehicleServer.pb.h",
@@ -37,16 +37,16 @@
 }
 
 genrule {
-    name: "VehicleServerProtoStub_cc@default-grpc",
+    name: "VehicleServerProtoStub_cc@default-grpc-V3",
     tools: [
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/3/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
         "proto/VehicleServer.proto",
         ":libprotobuf-internal-protos",
-        ":VehicleHalProtoFiles",
+        ":VehicleHalProtoFiles-V3",
     ],
     out: [
         "VehicleServer.pb.cc",
@@ -56,23 +56,23 @@
 }
 
 cc_library_static {
-    name: "android.hardware.automotive.vehicle@default-grpc-libgrpc",
+    name: "android.hardware.automotive.vehicle@default-grpc-libgrpc-V3",
     vendor: true,
     host_supported: true,
     include_dirs: [
         "external/protobuf/src",
     ],
     generated_headers: [
-        "VehicleServerProtoStub_h@default-grpc",
+        "VehicleServerProtoStub_h@default-grpc-V3",
     ],
     export_generated_headers: [
-        "VehicleServerProtoStub_h@default-grpc",
+        "VehicleServerProtoStub_h@default-grpc-V3",
     ],
     generated_sources: [
-        "VehicleServerProtoStub_cc@default-grpc",
+        "VehicleServerProtoStub_cc@default-grpc-V3",
     ],
     whole_static_libs: [
-        "VehicleHalProtos",
+        "VehicleHalProtos-V3",
     ],
     shared_libs: [
         "libgrpc++",
@@ -83,18 +83,18 @@
 }
 
 cc_library_static {
-    name: "android.hardware.automotive.vehicle@default-grpc-hardware-lib",
-    defaults: ["VehicleHalDefaults"],
+    name: "android.hardware.automotive.vehicle@default-grpc-hardware-lib-V3",
+    defaults: ["VehicleHalDefaults-V3"],
     vendor: true,
     srcs: [
         "GRPCVehicleHardware.cpp",
     ],
     whole_static_libs: [
-        "android.hardware.automotive.vehicle@default-grpc-libgrpc",
-        "VehicleHalProtoMessageConverter",
+        "android.hardware.automotive.vehicle@default-grpc-libgrpc-V3",
+        "VehicleHalProtoMessageConverter-V3",
     ],
     header_libs: [
-        "IVehicleHardware",
+        "IVehicleHardware-V3",
     ],
     shared_libs: [
         "libgrpc++",
@@ -107,18 +107,18 @@
 }
 
 cc_library_static {
-    name: "android.hardware.automotive.vehicle@default-grpc-server-lib",
-    defaults: ["VehicleHalDefaults"],
+    name: "android.hardware.automotive.vehicle@default-grpc-server-lib-V3",
+    defaults: ["VehicleHalDefaults-V3"],
     vendor: true,
     srcs: [
         "GRPCVehicleProxyServer.cpp",
     ],
     whole_static_libs: [
-        "android.hardware.automotive.vehicle@default-grpc-libgrpc",
-        "VehicleHalProtoMessageConverter",
+        "android.hardware.automotive.vehicle@default-grpc-libgrpc-V3",
+        "VehicleHalProtoMessageConverter-V3",
     ],
     header_libs: [
-        "IVehicleHardware",
+        "IVehicleHardware-V3",
     ],
     shared_libs: [
         "libgrpc++",
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleHardware.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
rename to automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleHardware.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleHardware.h
similarity index 97%
rename from automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
rename to automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleHardware.h
index 15f473c..ad2f512 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleHardware.h
@@ -115,9 +115,8 @@
     // A map from [propId, areaId] to the latest timestamp this property is updated.
     // The key is a tuple, the first element is the external timestamp (timestamp set by VHAL
     // server), the second element is the Android timestamp (elapsedRealtimeNano).
-    mutable std::unordered_map<PropIdAreaId, std::pair<int64_t, int64_t>,
-                               PropIdAreaIdHash> mLatestUpdateTimestamps
-            GUARDED_BY(mLatestUpdateTimestampsMutex);
+    mutable std::unordered_map<PropIdAreaId, std::pair<int64_t, int64_t>, PropIdAreaIdHash>
+            mLatestUpdateTimestamps GUARDED_BY(mLatestUpdateTimestampsMutex);
 
     // Only used for unit testing.
     GRPCVehicleHardware(std::unique_ptr<proto::VehicleServer::StubInterface> stub,
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleProxyServer.cpp
similarity index 99%
rename from automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
rename to automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleProxyServer.cpp
index 7697c03..927a595 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
+++ b/automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleProxyServer.cpp
@@ -40,7 +40,7 @@
 
 GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::string serverAddr,
                                                std::unique_ptr<IVehicleHardware>&& hardware)
-    : GrpcVehicleProxyServer(std::vector<std::string>({serverAddr}), std::move(hardware)){};
+    : GrpcVehicleProxyServer(std::vector<std::string>({serverAddr}), std::move(hardware)) {};
 
 GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::vector<std::string> serverAddrs,
                                                std::unique_ptr<IVehicleHardware>&& hardware)
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h b/automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleProxyServer.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h
rename to automotive/vehicle/aidl/impl/3/grpc/GRPCVehicleProxyServer.h
diff --git a/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto b/automotive/vehicle/aidl/impl/3/grpc/proto/VehicleServer.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
rename to automotive/vehicle/aidl/impl/3/grpc/proto/VehicleServer.proto
diff --git a/automotive/vehicle/aidl/impl/3/grpc/test/Android.bp b/automotive/vehicle/aidl/impl/3/grpc/test/Android.bp
new file mode 100644
index 0000000..1ab946b
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/grpc/test/Android.bp
@@ -0,0 +1,75 @@
+// Copyright (C) 2023 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_team: "trendy_team_automotive",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "GRPCVehicleHardwareUnitTest-V3",
+    vendor: true,
+    srcs: ["GRPCVehicleHardwareUnitTest.cpp"],
+    whole_static_libs: [
+        "android.hardware.automotive.vehicle@default-grpc-hardware-lib-V3",
+    ],
+    header_libs: [
+        "IVehicleHardware-V3",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    // libgrpc++.so is installed as root, require root to access it.
+    require_root: true,
+    defaults: [
+        "VehicleHalDefaults-V3",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+    test_suites: ["device-tests"],
+}
+
+cc_test {
+    name: "GRPCVehicleProxyServerUnitTest-V3",
+    vendor: true,
+    srcs: ["GRPCVehicleProxyServerUnitTest.cpp"],
+    header_libs: [
+        "IVehicleHardware-V3",
+    ],
+    static_libs: [
+        "android.hardware.automotive.vehicle@default-grpc-hardware-lib-V3",
+        "android.hardware.automotive.vehicle@default-grpc-server-lib-V3",
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libgrpc++",
+        "libprotobuf-cpp-full",
+    ],
+    // libgrpc++.so is installed as root, require root to access it.
+    require_root: true,
+    defaults: [
+        "VehicleHalDefaults-V3",
+    ],
+    cflags: [
+        "-Wno-unused-parameter",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp b/automotive/vehicle/aidl/impl/3/grpc/test/GRPCVehicleHardwareUnitTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
rename to automotive/vehicle/aidl/impl/3/grpc/test/GRPCVehicleHardwareUnitTest.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp b/automotive/vehicle/aidl/impl/3/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
rename to automotive/vehicle/aidl/impl/3/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
diff --git a/automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/Android.bp b/automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/Android.bp
new file mode 100644
index 0000000..5ae94b5
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/Android.bp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_automotive",
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_library {
+    name: "VehicleHalProtoMessageConverter-V3",
+    srcs: [
+        "src/*.cpp",
+    ],
+    vendor: true,
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    shared_libs: ["libprotobuf-cpp-full"],
+    static_libs: [
+        "VehicleHalProtos-V3",
+        "VehicleHalUtils-V3",
+    ],
+    defaults: ["VehicleHalDefaults-V3"],
+    export_static_lib_headers: ["VehicleHalUtils-V3"],
+    host_supported: true,
+}
+
+cc_test_host {
+    name: "VehicleHalProtoMessageConverterTest-V3",
+    srcs: [
+        "test/*.cpp",
+    ],
+    vendor: true,
+    defaults: ["VehicleHalDefaults-V3"],
+    static_libs: [
+        "VehicleHalJsonConfigLoaderEnableTestProperties-V3",
+        "VehicleHalProtoMessageConverter-V3",
+        "VehicleHalProtos-V3",
+        "VehicleHalUtils-V3",
+        "libgtest",
+        "libprotobuf-cpp-full",
+        "libjsoncpp",
+    ],
+    data: [
+        ":VehicleHalDefaultProperties_JSON-V3",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h b/automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
rename to automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp b/automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
rename to automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp b/automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
rename to automotive/vehicle/aidl/impl/3/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
diff --git a/automotive/vehicle/aidl/impl/3/hardware/Android.bp b/automotive/vehicle/aidl/impl/3/hardware/Android.bp
new file mode 100644
index 0000000..953760f
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/hardware/Android.bp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_headers {
+    name: "IVehicleHardware-V3",
+    vendor: true,
+    export_include_dirs: [
+        "include",
+    ],
+    header_libs: [
+        "VehicleHalUtilHeaders-V3",
+    ],
+    export_header_lib_headers: [
+        "VehicleHalUtilHeaders-V3",
+    ],
+    host_supported: true,
+}
diff --git a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/3/hardware/include/IVehicleHardware.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
rename to automotive/vehicle/aidl/impl/3/hardware/include/IVehicleHardware.h
diff --git a/automotive/vehicle/aidl/impl/proto/Android.bp b/automotive/vehicle/aidl/impl/3/proto/Android.bp
similarity index 84%
copy from automotive/vehicle/aidl/impl/proto/Android.bp
copy to automotive/vehicle/aidl/impl/3/proto/Android.bp
index 0d3df49..9840e63 100644
--- a/automotive/vehicle/aidl/impl/proto/Android.bp
+++ b/automotive/vehicle/aidl/impl/3/proto/Android.bp
@@ -24,20 +24,20 @@
 }
 
 filegroup {
-    name: "VehicleHalProtoFiles",
+    name: "VehicleHalProtoFiles-V3",
     srcs: ["**/*.proto"],
     visibility: ["//hardware/interfaces/automotive/vehicle:__subpackages__"],
 }
 
 genrule {
-    name: "VehicleProtoStub_h",
+    name: "VehicleProtoStub_h-V3",
     tools: [
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -Ihardware/interfaces/automotive/vehicle/aidl/impl/3/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
-        ":VehicleHalProtoFiles",
+        ":VehicleHalProtoFiles-V3",
     ],
     out: [
         "android/hardware/automotive/vehicle/DumpOptions.pb.h",
@@ -57,14 +57,14 @@
 }
 
 genrule {
-    name: "VehicleProtoStub_cc",
+    name: "VehicleProtoStub_cc-V3",
     tools: [
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -Ihardware/interfaces/automotive/vehicle/aidl/impl/3/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
-        ":VehicleHalProtoFiles",
+        ":VehicleHalProtoFiles-V3",
     ],
     out: [
         "android/hardware/automotive/vehicle/DumpOptions.pb.cc",
@@ -84,20 +84,20 @@
 }
 
 cc_library_static {
-    name: "VehicleHalProtos",
+    name: "VehicleHalProtos-V3",
     vendor: true,
     host_supported: true,
     include_dirs: [
         "external/protobuf/src",
     ],
     generated_headers: [
-        "VehicleProtoStub_h",
+        "VehicleProtoStub_h-V3",
     ],
     export_generated_headers: [
-        "VehicleProtoStub_h",
+        "VehicleProtoStub_h-V3",
     ],
     generated_sources: [
-        "VehicleProtoStub_cc",
+        "VehicleProtoStub_cc-V3",
     ],
     shared_libs: [
         "libgrpc++_unsecure",
@@ -108,9 +108,9 @@
 }
 
 rust_protobuf {
-    name: "libvehicle_hal_property_protos",
+    name: "libvehicle_hal_property_protos-V3",
     crate_name: "vehicle_hal_property_protos",
-    protos: [":VehicleHalProtoFiles"],
+    protos: [":VehicleHalProtoFiles-V3"],
     source_stem: "vehicle_hal_property_protos",
     host_supported: true,
     vendor_available: true,
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpOptions.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/DumpOptions.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpOptions.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/DumpOptions.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpResult.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/DumpResult.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpResult.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/DumpResult.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/StatusCode.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/StatusCode.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/StatusCode.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/StatusCode.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropConfig.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropConfig.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropConfig.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropConfig.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyAccess.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropertyAccess.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyAccess.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropertyAccess.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyStatus.proto b/automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropertyStatus.proto
similarity index 100%
rename from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyStatus.proto
rename to automotive/vehicle/aidl/impl/3/proto/android/hardware/automotive/vehicle/VehiclePropertyStatus.proto
diff --git a/automotive/vehicle/aidl/impl/utils/README.md b/automotive/vehicle/aidl/impl/3/utils/README.md
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/README.md
rename to automotive/vehicle/aidl/impl/3/utils/README.md
diff --git a/automotive/vehicle/aidl/impl/3/utils/common/Android.bp b/automotive/vehicle/aidl/impl/3/utils/common/Android.bp
new file mode 100644
index 0000000..f653d90
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/utils/common/Android.bp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+    name: "VehicleHalUtils-V3",
+    srcs: ["src/*.cpp"],
+    vendor_available: true,
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+    defaults: ["VehicleHalDefaults-V3"],
+    host_supported: true,
+}
+
+cc_library_headers {
+    name: "VehicleHalUtilHeaders-V3",
+    export_include_dirs: ["include"],
+    vendor: true,
+    host_supported: true,
+}
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/ConcurrentQueue.h b/automotive/vehicle/aidl/impl/3/utils/common/include/ConcurrentQueue.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/include/ConcurrentQueue.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/ConcurrentQueue.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/ParcelableUtils.h b/automotive/vehicle/aidl/impl/3/utils/common/include/ParcelableUtils.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/include/ParcelableUtils.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/ParcelableUtils.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h b/automotive/vehicle/aidl/impl/3/utils/common/include/PendingRequestPool.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/PendingRequestPool.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h b/automotive/vehicle/aidl/impl/3/utils/common/include/PropertyUtils.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/PropertyUtils.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h b/automotive/vehicle/aidl/impl/3/utils/common/include/RecurrentTimer.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/RecurrentTimer.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/3/utils/common/include/VehicleHalTypes.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/VehicleHalTypes.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h b/automotive/vehicle/aidl/impl/3/utils/common/include/VehicleObjectPool.h
similarity index 98%
rename from automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/VehicleObjectPool.h
index 501ce40..e18413b 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
+++ b/automotive/vehicle/aidl/impl/3/utils/common/include/VehicleObjectPool.h
@@ -50,7 +50,7 @@
 struct Deleter {
     using OnDeleteFunc = std::function<void(T*)>;
 
-    explicit Deleter(const OnDeleteFunc& f) : mOnDelete(f){};
+    explicit Deleter(const OnDeleteFunc& f) : mOnDelete(f) {};
 
     Deleter() = default;
     Deleter(const Deleter&) = default;
@@ -76,7 +76,7 @@
     using GetSizeFunc = std::function<size_t(const T&)>;
 
     ObjectPool(size_t maxPoolObjectsSize, GetSizeFunc getSizeFunc)
-        : mMaxPoolObjectsSize(maxPoolObjectsSize), mGetSizeFunc(getSizeFunc){};
+        : mMaxPoolObjectsSize(maxPoolObjectsSize), mGetSizeFunc(getSizeFunc) {};
     virtual ~ObjectPool() = default;
 
     virtual recyclable_ptr<T> obtain() {
@@ -182,7 +182,7 @@
     // approximately this pool would at-most take 4 * 4 * 10240 = 160k memory.
     VehiclePropValuePool(size_t maxRecyclableVectorSize = 4, size_t maxPoolObjectsSize = 10240)
         : mMaxRecyclableVectorSize(maxRecyclableVectorSize),
-          mMaxPoolObjectsSize(maxPoolObjectsSize){};
+          mMaxPoolObjectsSize(maxPoolObjectsSize) {};
 
     // Obtain a recyclable VehiclePropertyValue object from the pool for the given type. If the
     // given type is not MIXED or STRING, the internal value vector size would be set to 1.
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/3/utils/common/include/VehiclePropertyStore.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/VehiclePropertyStore.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/3/utils/common/include/VehicleUtils.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
rename to automotive/vehicle/aidl/impl/3/utils/common/include/VehicleUtils.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp b/automotive/vehicle/aidl/impl/3/utils/common/src/PendingRequestPool.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/src/PendingRequestPool.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/3/utils/common/src/RecurrentTimer.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/src/RecurrentTimer.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp b/automotive/vehicle/aidl/impl/3/utils/common/src/VehicleObjectPool.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/src/VehicleObjectPool.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/3/utils/common/src/VehiclePropertyStore.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/src/VehiclePropertyStore.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp b/automotive/vehicle/aidl/impl/3/utils/common/src/VehicleUtils.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/src/VehicleUtils.cpp
diff --git a/automotive/vehicle/aidl/impl/3/utils/common/test/Android.bp b/automotive/vehicle/aidl/impl/3/utils/common/test/Android.bp
new file mode 100644
index 0000000..0450e99
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/utils/common/test/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_aaos_framework",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "VehicleHalVehicleUtilsTest-V3",
+    srcs: ["*.cpp"],
+    vendor: true,
+    static_libs: [
+        "VehicleHalUtils-V3",
+        "libgtest",
+        "libgmock",
+    ],
+    defaults: ["VehicleHalDefaults-V3"],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/PendingRequestPoolTest.cpp b/automotive/vehicle/aidl/impl/3/utils/common/test/PendingRequestPoolTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/test/PendingRequestPoolTest.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/test/PendingRequestPoolTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp b/automotive/vehicle/aidl/impl/3/utils/common/test/RecurrentTimerTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/test/RecurrentTimerTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp b/automotive/vehicle/aidl/impl/3/utils/common/test/VehicleObjectPoolTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/test/VehicleObjectPoolTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/3/utils/common/test/VehiclePropertyStoreTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/test/VehiclePropertyStoreTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp b/automotive/vehicle/aidl/impl/3/utils/common/test/VehicleUtilsTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp
rename to automotive/vehicle/aidl/impl/3/utils/common/test/VehicleUtilsTest.cpp
diff --git a/automotive/vehicle/aidl/impl/3/utils/test_vendor_properties/Android.bp b/automotive/vehicle/aidl/impl/3/utils/test_vendor_properties/Android.bp
new file mode 100644
index 0000000..42e2317
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/utils/test_vendor_properties/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 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"],
+}
+
+filegroup {
+    name: "VhalTestVendorProperties-V3",
+    srcs: [
+        "**/*.aidl",
+    ],
+    visibility: [
+        "//hardware/interfaces/automotive/vehicle/aidl:__subpackages__",
+        "//packages/services/Car:__subpackages__",
+        "//cts/tests/tests/car_permission_tests",
+    ],
+}
diff --git a/automotive/vehicle/aidl/impl/utils/test_vendor_properties/android/hardware/automotive/vehicle/TestVendorProperty.aidl b/automotive/vehicle/aidl/impl/3/utils/test_vendor_properties/android/hardware/automotive/vehicle/TestVendorProperty.aidl
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/test_vendor_properties/android/hardware/automotive/vehicle/TestVendorProperty.aidl
rename to automotive/vehicle/aidl/impl/3/utils/test_vendor_properties/android/hardware/automotive/vehicle/TestVendorProperty.aidl
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/3/vhal/Android.bp
similarity index 75%
copy from automotive/vehicle/aidl/impl/vhal/Android.bp
copy to automotive/vehicle/aidl/impl/3/vhal/Android.bp
index 54d148e..a648fd4 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/3/vhal/Android.bp
@@ -23,21 +23,21 @@
     name: "android.hardware.automotive.vehicle@V3-default-service",
     vendor: true,
     defaults: [
-        "FakeVehicleHardwareDefaults",
-        "VehicleHalDefaults",
+        "FakeVehicleHardwareDefaults-V3",
+        "VehicleHalDefaults-V3",
         "android-automotive-large-parcelable-defaults",
     ],
-    vintf_fragments: ["vhal-default-service.xml"],
-    init_rc: ["vhal-default-service.rc"],
+    vintf_fragments: ["vhal-default-service-v3.xml"],
+    init_rc: ["vhal-default-service-v3.rc"],
     relative_install_path: "hw",
     srcs: ["src/VehicleService.cpp"],
     static_libs: [
-        "DefaultVehicleHal",
-        "FakeVehicleHardware",
-        "VehicleHalUtils",
+        "DefaultVehicleHal-V3",
+        "FakeVehicleHardware-V3",
+        "VehicleHalUtils-V3",
     ],
     header_libs: [
-        "IVehicleHardware",
+        "IVehicleHardware-V3",
     ],
     shared_libs: [
         "libbinder_ndk",
@@ -45,10 +45,10 @@
 }
 
 cc_library {
-    name: "DefaultVehicleHal",
+    name: "DefaultVehicleHal-V3",
     vendor: true,
     defaults: [
-        "VehicleHalDefaults",
+        "VehicleHalDefaults-V3",
     ],
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
@@ -62,11 +62,11 @@
         ":check_generated_enum_metadata_json",
     ],
     static_libs: [
-        "VehicleHalUtils",
+        "VehicleHalUtils-V3",
     ],
     header_libs: [
-        "IVehicleHardware",
-        "IVehicleGeneratedHeaders-V4",
+        "IVehicleHardware-V3",
+        "IVehicleGeneratedHeaders-V3-default",
     ],
     shared_libs: [
         "libbinder_ndk",
@@ -74,18 +74,18 @@
 }
 
 cc_fuzz {
-    name: "android.hardware.automotive.vehicle-default-service_fuzzer",
+    name: "android.hardware.automotive.vehicle-default-service_fuzzer-V3",
     vendor: true,
     defaults: [
-        "FakeVehicleHardwareDefaults",
-        "VehicleHalDefaults",
+        "FakeVehicleHardwareDefaults-V3",
+        "VehicleHalDefaults-V3",
         "android-automotive-large-parcelable-defaults",
         "service_fuzzer_defaults",
     ],
     static_libs: [
-        "DefaultVehicleHal",
-        "FakeVehicleHardware",
-        "VehicleHalUtils",
+        "DefaultVehicleHal-V3",
+        "FakeVehicleHardware-V3",
+        "VehicleHalUtils-V3",
     ],
     srcs: ["src/fuzzer.cpp"],
     fuzz_config: {
diff --git a/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h b/automotive/vehicle/aidl/impl/3/vhal/include/ConnectedClient.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h
rename to automotive/vehicle/aidl/impl/3/vhal/include/ConnectedClient.h
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/3/vhal/include/DefaultVehicleHal.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
rename to automotive/vehicle/aidl/impl/3/vhal/include/DefaultVehicleHal.h
diff --git a/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h b/automotive/vehicle/aidl/impl/3/vhal/include/SubscriptionManager.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
rename to automotive/vehicle/aidl/impl/3/vhal/include/SubscriptionManager.h
diff --git a/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp b/automotive/vehicle/aidl/impl/3/vhal/src/ConnectedClient.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/src/ConnectedClient.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/3/vhal/src/DefaultVehicleHal.cpp
similarity index 99%
rename from automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/src/DefaultVehicleHal.cpp
index 0ead819..aa9ef53 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/3/vhal/src/DefaultVehicleHal.cpp
@@ -110,7 +110,7 @@
 }  // namespace
 
 DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
-    : DefaultVehicleHal(std::move(vehicleHardware), /* testInterfaceVersion= */ 0){};
+    : DefaultVehicleHal(std::move(vehicleHardware), /* testInterfaceVersion= */ 0) {};
 
 DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware,
                                      int32_t testInterfaceVersion)
diff --git a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp b/automotive/vehicle/aidl/impl/3/vhal/src/SubscriptionManager.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/src/SubscriptionManager.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp b/automotive/vehicle/aidl/impl/3/vhal/src/VehicleService.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/src/VehicleService.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp b/automotive/vehicle/aidl/impl/3/vhal/src/fuzzer.cpp
similarity index 93%
rename from automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/src/fuzzer.cpp
index 6d994bb..ac1e3b1 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp
+++ b/automotive/vehicle/aidl/impl/3/vhal/src/fuzzer.cpp
@@ -25,8 +25,6 @@
 using ::ndk::SharedRefBase;
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    // TODO(b/183141167): need to rewrite 'dump' to avoid SIGPIPE.
-    signal(SIGPIPE, SIG_IGN);
     std::unique_ptr<FakeVehicleHardware> hardware = std::make_unique<FakeVehicleHardware>();
     std::shared_ptr<DefaultVehicleHal> vhal =
             ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
diff --git a/automotive/vehicle/aidl/impl/3/vhal/test/Android.bp b/automotive/vehicle/aidl/impl/3/vhal/test/Android.bp
new file mode 100644
index 0000000..e86bc81
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/3/vhal/test/Android.bp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package {
+    default_team: "trendy_team_aaos_framework",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_test {
+    name: "DefaultVehicleHalTest-V3",
+    vendor: true,
+    srcs: ["*.cpp"],
+    static_libs: [
+        "DefaultVehicleHal-V3",
+        "VehicleHalUtils-V3",
+        "libgtest",
+        "libgmock",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+    ],
+    header_libs: [
+        "IVehicleHardware-V3",
+    ],
+    defaults: [
+        "VehicleHalDefaults-V3",
+    ],
+    test_suites: ["device-tests"],
+}
diff --git a/automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp b/automotive/vehicle/aidl/impl/3/vhal/test/ConnectedClientTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/test/ConnectedClientTest.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/3/vhal/test/DefaultVehicleHalTest.cpp
similarity index 99%
rename from automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/test/DefaultVehicleHalTest.cpp
index 4891bf5..ad34a4c 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/3/vhal/test/DefaultVehicleHalTest.cpp
@@ -1849,6 +1849,12 @@
     std::this_thread::sleep_for(std::chrono::seconds(3));
 
     auto maybeResults = getCallback()->nextOnPropertyEventResults();
+    size_t retryCount = 0;
+    // Add a 1s (100ms * 10) buffer time.
+    while (!maybeResults.has_value() && retryCount < 10) {
+        retryCount++;
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    }
     ASSERT_TRUE(maybeResults.has_value()) << "no results in callback";
     ASSERT_EQ(maybeResults.value().payloads.size(), static_cast<size_t>(1));
     VehiclePropValue gotValue = maybeResults.value().payloads[0];
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp b/automotive/vehicle/aidl/impl/3/vhal/test/MockVehicleCallback.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/test/MockVehicleCallback.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h b/automotive/vehicle/aidl/impl/3/vhal/test/MockVehicleCallback.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/test/MockVehicleCallback.h
rename to automotive/vehicle/aidl/impl/3/vhal/test/MockVehicleCallback.h
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp b/automotive/vehicle/aidl/impl/3/vhal/test/MockVehicleHardware.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/test/MockVehicleHardware.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h b/automotive/vehicle/aidl/impl/3/vhal/test/MockVehicleHardware.h
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
rename to automotive/vehicle/aidl/impl/3/vhal/test/MockVehicleHardware.h
diff --git a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp b/automotive/vehicle/aidl/impl/3/vhal/test/SubscriptionManagerTest.cpp
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
rename to automotive/vehicle/aidl/impl/3/vhal/test/SubscriptionManagerTest.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.rc b/automotive/vehicle/aidl/impl/3/vhal/vhal-default-service-v3.rc
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/vhal-default-service.rc
rename to automotive/vehicle/aidl/impl/3/vhal/vhal-default-service-v3.rc
diff --git a/automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml b/automotive/vehicle/aidl/impl/3/vhal/vhal-default-service-v3.xml
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/vhal-default-service.xml
rename to automotive/vehicle/aidl/impl/3/vhal/vhal-default-service-v3.xml
diff --git a/automotive/vehicle/aidl/impl/Android.bp b/automotive/vehicle/aidl/impl/current/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/Android.bp
rename to automotive/vehicle/aidl/impl/current/Android.bp
diff --git a/automotive/vehicle/aidl/impl/README.md b/automotive/vehicle/aidl/impl/current/README.md
similarity index 100%
rename from automotive/vehicle/aidl/impl/README.md
rename to automotive/vehicle/aidl/impl/current/README.md
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
rename to automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/Android.bp
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/ConfigDeclaration.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/ConfigDeclaration.h
copy to automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/ConfigDeclaration.h
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/JsonConfigLoader.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/include/JsonConfigLoader.h
copy to automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/include/JsonConfigLoader.h
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
new file mode 100644
index 0000000..7a1f0e0
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -0,0 +1,727 @@
+/*
+ * 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 <JsonConfigLoader.h>
+
+#include <AccessForVehicleProperty.h>
+#include <ChangeModeForVehicleProperty.h>
+#include <PropertyUtils.h>
+
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+#include <android/hardware/automotive/vehicle/TestVendorProperty.h>
+#endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+
+#include <android-base/strings.h>
+#include <fstream>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace jsonconfigloader_impl {
+
+using ::aidl::android::hardware::automotive::vehicle::AccessForVehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::AutomaticEmergencyBrakingState;
+using ::aidl::android::hardware::automotive::vehicle::BlindSpotWarningState;
+using ::aidl::android::hardware::automotive::vehicle::CameraServiceState;
+using ::aidl::android::hardware::automotive::vehicle::ChangeModeForVehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::CrossTrafficMonitoringWarningState;
+using ::aidl::android::hardware::automotive::vehicle::CruiseControlCommand;
+using ::aidl::android::hardware::automotive::vehicle::CruiseControlState;
+using ::aidl::android::hardware::automotive::vehicle::CruiseControlType;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDistractionWarning;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionState;
+using ::aidl::android::hardware::automotive::vehicle::DriverDrowsinessAttentionWarning;
+using ::aidl::android::hardware::automotive::vehicle::ElectronicStabilityControlState;
+using ::aidl::android::hardware::automotive::vehicle::EmergencyLaneKeepAssistState;
+using ::aidl::android::hardware::automotive::vehicle::ErrorState;
+using ::aidl::android::hardware::automotive::vehicle::EvConnectorType;
+using ::aidl::android::hardware::automotive::vehicle::EvsServiceState;
+using ::aidl::android::hardware::automotive::vehicle::EvsServiceType;
+using ::aidl::android::hardware::automotive::vehicle::ForwardCollisionWarningState;
+using ::aidl::android::hardware::automotive::vehicle::FuelType;
+using ::aidl::android::hardware::automotive::vehicle::GsrComplianceRequirementType;
+using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionDriverState;
+using ::aidl::android::hardware::automotive::vehicle::HandsOnDetectionWarning;
+using ::aidl::android::hardware::automotive::vehicle::ImpactSensorLocation;
+using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistCommand;
+using ::aidl::android::hardware::automotive::vehicle::LaneCenteringAssistState;
+using ::aidl::android::hardware::automotive::vehicle::LaneDepartureWarningState;
+using ::aidl::android::hardware::automotive::vehicle::LaneKeepAssistState;
+using ::aidl::android::hardware::automotive::vehicle::LocationCharacterization;
+using ::aidl::android::hardware::automotive::vehicle::LowSpeedAutomaticEmergencyBrakingState;
+using ::aidl::android::hardware::automotive::vehicle::LowSpeedCollisionWarningState;
+using ::aidl::android::hardware::automotive::vehicle::RawPropValues;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAirbagLocation;
+using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerBootupReason;
+using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
+using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAutonomousState;
+using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
+using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
+using ::aidl::android::hardware::automotive::vehicle::VehicleIgnitionState;
+using ::aidl::android::hardware::automotive::vehicle::VehicleOilLevel;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
+using ::aidl::android::hardware::automotive::vehicle::VehicleSeatOccupancyState;
+using ::aidl::android::hardware::automotive::vehicle::VehicleSizeClass;
+using ::aidl::android::hardware::automotive::vehicle::VehicleTurnSignal;
+using ::aidl::android::hardware::automotive::vehicle::VehicleUnit;
+using ::aidl::android::hardware::automotive::vehicle::VehicleVendorPermission;
+using ::aidl::android::hardware::automotive::vehicle::WindshieldWipersState;
+using ::aidl::android::hardware::automotive::vehicle::WindshieldWipersSwitch;
+
+using ::android::base::Error;
+using ::android::base::Result;
+
+// 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 = {
+        {"DOOR_1_RIGHT", DOOR_1_RIGHT},
+        {"DOOR_1_LEFT", DOOR_1_LEFT},
+        {"DOOR_2_RIGHT", DOOR_2_RIGHT},
+        {"DOOR_2_LEFT", DOOR_2_LEFT},
+        {"DOOR_REAR", DOOR_REAR},
+        {"HVAC_ALL", HVAC_ALL},
+        {"HVAC_LEFT", HVAC_LEFT},
+        {"HVAC_RIGHT", HVAC_RIGHT},
+        {"HVAC_FRONT_ROW", HVAC_FRONT_ROW},
+        {"HVAC_REAR_ROW", HVAC_REAR_ROW},
+        {"WINDOW_1_LEFT", WINDOW_1_LEFT},
+        {"WINDOW_1_RIGHT", WINDOW_1_RIGHT},
+        {"WINDOW_2_LEFT", WINDOW_2_LEFT},
+        {"WINDOW_2_RIGHT", WINDOW_2_RIGHT},
+        {"WINDOW_ROOF_TOP_1", WINDOW_ROOF_TOP_1},
+        {"WINDOW_1_RIGHT_2_LEFT_2_RIGHT", WINDOW_1_RIGHT | WINDOW_2_LEFT | WINDOW_2_RIGHT},
+        {"SEAT_1_LEFT", SEAT_1_LEFT},
+        {"SEAT_1_RIGHT", SEAT_1_RIGHT},
+        {"SEAT_2_LEFT", SEAT_2_LEFT},
+        {"SEAT_2_RIGHT", SEAT_2_RIGHT},
+        {"SEAT_2_CENTER", SEAT_2_CENTER},
+        {"SEAT_2_LEFT_2_RIGHT_2_CENTER", SEAT_2_LEFT | SEAT_2_RIGHT | SEAT_2_CENTER},
+        {"WHEEL_REAR_RIGHT", WHEEL_REAR_RIGHT},
+        {"WHEEL_REAR_LEFT", WHEEL_REAR_LEFT},
+        {"WHEEL_FRONT_RIGHT", WHEEL_FRONT_RIGHT},
+        {"WHEEL_FRONT_LEFT", WHEEL_FRONT_LEFT},
+        {"CHARGE_PORT_FRONT_LEFT", CHARGE_PORT_FRONT_LEFT},
+        {"CHARGE_PORT_REAR_LEFT", CHARGE_PORT_REAR_LEFT},
+        {"FAN_DIRECTION_UNKNOWN", toInt(VehicleHvacFanDirection::UNKNOWN)},
+        {"FAN_DIRECTION_FLOOR", FAN_DIRECTION_FLOOR},
+        {"FAN_DIRECTION_FACE", FAN_DIRECTION_FACE},
+        {"FAN_DIRECTION_DEFROST", FAN_DIRECTION_DEFROST},
+        {"FAN_DIRECTION_FACE_FLOOR", FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR},
+        {"FAN_DIRECTION_FACE_DEFROST", FAN_DIRECTION_FACE | FAN_DIRECTION_DEFROST},
+        {"FAN_DIRECTION_FLOOR_DEFROST", FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST},
+        {"FAN_DIRECTION_FLOOR_DEFROST_FACE",
+         FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST | FAN_DIRECTION_FACE},
+        {"FUEL_DOOR_REAR_LEFT", FUEL_DOOR_REAR_LEFT},
+        {"LIGHT_STATE_ON", LIGHT_STATE_ON},
+        {"LIGHT_STATE_OFF", LIGHT_STATE_OFF},
+        {"LIGHT_SWITCH_OFF", LIGHT_SWITCH_OFF},
+        {"LIGHT_SWITCH_ON", LIGHT_SWITCH_ON},
+        {"LIGHT_SWITCH_AUTO", LIGHT_SWITCH_AUTO},
+        {"EV_STOPPING_MODE_CREEP", EV_STOPPING_MODE_CREEP},
+        {"EV_STOPPING_MODE_ROLL", EV_STOPPING_MODE_ROLL},
+        {"EV_STOPPING_MODE_HOLD", EV_STOPPING_MODE_HOLD},
+        {"MIRROR_DRIVER_LEFT_RIGHT",
+         toInt(VehicleAreaMirror::DRIVER_LEFT) | toInt(VehicleAreaMirror::DRIVER_RIGHT)},
+};
+
+// 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 {
+  public:
+    ConstantParser() {
+        for (const T& v : ndk::enum_range<T>()) {
+            std::string name = aidl::android::hardware::automotive::vehicle::toString(v);
+            // We use the same constant for both VehicleUnit::GALLON and VehicleUnit::US_GALLON,
+            // which caused toString() not work properly for US_GALLON. So we explicitly add the
+            // map here.
+            if (name == "GALLON") {
+                mValueByName["US_GALLON"] = toInt(v);
+            }
+            mValueByName[name] = toInt(v);
+        }
+    }
+
+    ~ConstantParser() = default;
+
+    Result<int> parseValue(const std::string& name) const override {
+        auto it = mValueByName.find(name);
+        if (it == mValueByName.end()) {
+            return Error() << "Constant name: " << name << " is not defined";
+        }
+        return it->second;
+    }
+
+  private:
+    std::unordered_map<std::string, int> mValueByName;
+};
+
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+// A class to parse constant values for type T where T is defined as an enum in CPP AIDL backend.
+template <class T>
+class CppConstantParser final : public ConstantParserInterface {
+  public:
+    CppConstantParser() {
+        for (const T& v : android::enum_range<T>()) {
+            std::string name = android::hardware::automotive::vehicle::toString(v);
+            mValueByName[name] = toInt(v);
+        }
+    }
+
+    ~CppConstantParser() = default;
+
+    Result<int> parseValue(const std::string& name) const override {
+        auto it = mValueByName.find(name);
+        if (it == mValueByName.end()) {
+            return Error() << "Constant name: " << name << " is not defined";
+        }
+        return it->second;
+    }
+
+  private:
+    std::unordered_map<std::string, int> mValueByName;
+};
+#endif
+
+// A class to parse constant values defined in CONSTANTS_BY_NAME map.
+class LocalVariableParser final : public ConstantParserInterface {
+  public:
+    ~LocalVariableParser() = default;
+
+    Result<int> parseValue(const std::string& name) const override {
+        auto constantsIt = CONSTANTS_BY_NAME.find(name);
+        if (constantsIt == CONSTANTS_BY_NAME.end()) {
+            return Error() << "Constant variable name: " << name << " is not defined";
+        }
+        return constantsIt->second;
+    }
+};
+
+JsonValueParser::JsonValueParser() {
+    mConstantParsersByType["VehiclePropertyAccess"] =
+            std::make_unique<ConstantParser<VehiclePropertyAccess>>();
+    mConstantParsersByType["VehiclePropertyChangeMode"] =
+            std::make_unique<ConstantParser<VehiclePropertyChangeMode>>();
+    mConstantParsersByType["LocationCharacterization"] =
+            std::make_unique<ConstantParser<LocationCharacterization>>();
+    mConstantParsersByType["VehicleGear"] = std::make_unique<ConstantParser<VehicleGear>>();
+    mConstantParsersByType["VehicleAreaWindow"] =
+            std::make_unique<ConstantParser<VehicleAreaWindow>>();
+    mConstantParsersByType["VehicleAreaMirror"] =
+            std::make_unique<ConstantParser<VehicleAreaMirror>>();
+    mConstantParsersByType["VehicleOilLevel"] = std::make_unique<ConstantParser<VehicleOilLevel>>();
+    mConstantParsersByType["VehicleUnit"] = std::make_unique<ConstantParser<VehicleUnit>>();
+    mConstantParsersByType["VehicleSeatOccupancyState"] =
+            std::make_unique<ConstantParser<VehicleSeatOccupancyState>>();
+    mConstantParsersByType["VehicleHvacFanDirection"] =
+            std::make_unique<ConstantParser<VehicleHvacFanDirection>>();
+    mConstantParsersByType["VehicleApPowerStateReport"] =
+            std::make_unique<ConstantParser<VehicleApPowerStateReport>>();
+    mConstantParsersByType["VehicleTurnSignal"] =
+            std::make_unique<ConstantParser<VehicleTurnSignal>>();
+    mConstantParsersByType["VehicleVendorPermission"] =
+            std::make_unique<ConstantParser<VehicleVendorPermission>>();
+    mConstantParsersByType["EvsServiceType"] = std::make_unique<ConstantParser<EvsServiceType>>();
+    mConstantParsersByType["EvsServiceState"] = std::make_unique<ConstantParser<EvsServiceState>>();
+    mConstantParsersByType["EvConnectorType"] = std::make_unique<ConstantParser<EvConnectorType>>();
+    mConstantParsersByType["VehicleProperty"] = std::make_unique<ConstantParser<VehicleProperty>>();
+    mConstantParsersByType["GsrComplianceRequirementType"] =
+            std::make_unique<ConstantParser<GsrComplianceRequirementType>>();
+    mConstantParsersByType["VehicleIgnitionState"] =
+            std::make_unique<ConstantParser<VehicleIgnitionState>>();
+    mConstantParsersByType["FuelType"] = std::make_unique<ConstantParser<FuelType>>();
+    mConstantParsersByType["WindshieldWipersState"] =
+            std::make_unique<ConstantParser<WindshieldWipersState>>();
+    mConstantParsersByType["WindshieldWipersSwitch"] =
+            std::make_unique<ConstantParser<WindshieldWipersSwitch>>();
+    mConstantParsersByType["VehicleAutonomousState"] =
+            std::make_unique<ConstantParser<VehicleAutonomousState>>();
+    mConstantParsersByType["VehicleAirbagLocation"] =
+            std::make_unique<ConstantParser<VehicleAirbagLocation>>();
+    mConstantParsersByType["ImpactSensorLocation"] =
+            std::make_unique<ConstantParser<ImpactSensorLocation>>();
+    mConstantParsersByType["VehicleSizeClass"] =
+            std::make_unique<ConstantParser<VehicleSizeClass>>();
+    mConstantParsersByType["EmergencyLaneKeepAssistState"] =
+            std::make_unique<ConstantParser<EmergencyLaneKeepAssistState>>();
+    mConstantParsersByType["CameraServiceState"] =
+            std::make_unique<ConstantParser<CameraServiceState>>();
+    mConstantParsersByType["CruiseControlType"] =
+            std::make_unique<ConstantParser<CruiseControlType>>();
+    mConstantParsersByType["CruiseControlState"] =
+            std::make_unique<ConstantParser<CruiseControlState>>();
+    mConstantParsersByType["CruiseControlCommand"] =
+            std::make_unique<ConstantParser<CruiseControlCommand>>();
+    mConstantParsersByType["HandsOnDetectionDriverState"] =
+            std::make_unique<ConstantParser<HandsOnDetectionDriverState>>();
+    mConstantParsersByType["HandsOnDetectionWarning"] =
+            std::make_unique<ConstantParser<HandsOnDetectionWarning>>();
+    mConstantParsersByType["DriverDrowsinessAttentionState"] =
+            std::make_unique<ConstantParser<DriverDrowsinessAttentionState>>();
+    mConstantParsersByType["DriverDrowsinessAttentionWarning"] =
+            std::make_unique<ConstantParser<DriverDrowsinessAttentionWarning>>();
+    mConstantParsersByType["DriverDistractionState"] =
+            std::make_unique<ConstantParser<DriverDistractionState>>();
+    mConstantParsersByType["DriverDistractionWarning"] =
+            std::make_unique<ConstantParser<DriverDistractionWarning>>();
+    mConstantParsersByType["ErrorState"] = std::make_unique<ConstantParser<ErrorState>>();
+    mConstantParsersByType["AutomaticEmergencyBrakingState"] =
+            std::make_unique<ConstantParser<AutomaticEmergencyBrakingState>>();
+    mConstantParsersByType["ForwardCollisionWarningState"] =
+            std::make_unique<ConstantParser<ForwardCollisionWarningState>>();
+    mConstantParsersByType["BlindSpotWarningState"] =
+            std::make_unique<ConstantParser<BlindSpotWarningState>>();
+    mConstantParsersByType["LaneDepartureWarningState"] =
+            std::make_unique<ConstantParser<LaneDepartureWarningState>>();
+    mConstantParsersByType["LaneKeepAssistState"] =
+            std::make_unique<ConstantParser<LaneKeepAssistState>>();
+    mConstantParsersByType["LaneCenteringAssistCommand"] =
+            std::make_unique<ConstantParser<LaneCenteringAssistCommand>>();
+    mConstantParsersByType["LaneCenteringAssistState"] =
+            std::make_unique<ConstantParser<LaneCenteringAssistState>>();
+    mConstantParsersByType["LowSpeedCollisionWarningState"] =
+            std::make_unique<ConstantParser<LowSpeedCollisionWarningState>>();
+    mConstantParsersByType["ElectronicStabilityControlState"] =
+            std::make_unique<ConstantParser<ElectronicStabilityControlState>>();
+    mConstantParsersByType["CrossTrafficMonitoringWarningState"] =
+            std::make_unique<ConstantParser<CrossTrafficMonitoringWarningState>>();
+    mConstantParsersByType["LowSpeedAutomaticEmergencyBrakingState"] =
+            std::make_unique<ConstantParser<LowSpeedAutomaticEmergencyBrakingState>>();
+    mConstantParsersByType["VehicleApPowerBootupReason"] =
+            std::make_unique<ConstantParser<VehicleApPowerBootupReason>>();
+    mConstantParsersByType["Constants"] = std::make_unique<LocalVariableParser>();
+#ifdef ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+    mConstantParsersByType["TestVendorProperty"] =
+            std::make_unique<CppConstantParser<TestVendorProperty>>();
+#endif  // ENABLE_VEHICLE_HAL_TEST_PROPERTIES
+}
+
+template <>
+Result<bool> JsonValueParser::convertValueToType<bool>(const std::string& fieldName,
+                                                       const Json::Value& value) {
+    if (!value.isBool()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect bool";
+    }
+    return value.asBool();
+}
+
+template <>
+Result<int32_t> JsonValueParser::convertValueToType<int32_t>(const std::string& fieldName,
+                                                             const Json::Value& value) {
+    if (!value.isInt()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect int";
+    }
+    return static_cast<int32_t>(value.asInt());
+}
+
+template <>
+Result<float> JsonValueParser::convertValueToType<float>(const std::string& fieldName,
+                                                         const Json::Value& value) {
+    // isFloat value does not exist, so we use isDouble here.
+    if (!value.isDouble()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect float";
+    }
+    return value.asFloat();
+}
+
+template <>
+Result<int64_t> JsonValueParser::convertValueToType<int64_t>(const std::string& fieldName,
+                                                             const Json::Value& value) {
+    if (!value.isInt64()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect int64";
+    }
+    return static_cast<int64_t>(value.asInt64());
+}
+
+template <>
+Result<std::string> JsonValueParser::convertValueToType<std::string>(const std::string& fieldName,
+                                                                     const Json::Value& value) {
+    if (!value.isString()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect string";
+    }
+    return value.asString();
+}
+
+Result<std::string> JsonValueParser::parseStringValue(const std::string& fieldName,
+                                                      const Json::Value& value) const {
+    return convertValueToType<std::string>(fieldName, value);
+}
+
+template <class T>
+Result<T> JsonValueParser::parseValue(const std::string& fieldName,
+                                      const Json::Value& value) const {
+    if (!value.isString()) {
+        return convertValueToType<T>(fieldName, value);
+    }
+    auto maybeTypeAndValue = maybeGetTypeAndValueName(value.asString());
+    if (!maybeTypeAndValue.has_value()) {
+        return Error() << "Invalid constant value: " << value << " for field: " << fieldName;
+    }
+    auto constantParseResult = parseConstantValue(maybeTypeAndValue.value());
+    if (!constantParseResult.ok()) {
+        return constantParseResult.error();
+    }
+    int constantValue = constantParseResult.value();
+    return static_cast<T>(constantValue);
+}
+
+template <>
+Result<std::string> JsonValueParser::parseValue<std::string>(const std::string& fieldName,
+                                                             const Json::Value& value) const {
+    return parseStringValue(fieldName, value);
+}
+
+template <class T>
+Result<std::vector<T>> JsonValueParser::parseArray(const std::string& fieldName,
+                                                   const Json::Value& value) const {
+    if (!value.isArray()) {
+        return Error() << "The value: " << value << " for field: " << fieldName
+                       << " is not in correct type, expect array";
+    }
+    std::vector<T> parsedValues;
+    for (unsigned int i = 0; i < value.size(); i++) {
+        auto result = parseValue<T>(fieldName, value[i]);
+        if (!result.ok()) {
+            return result.error();
+        }
+        parsedValues.push_back(result.value());
+    }
+    return std::move(parsedValues);
+}
+
+std::optional<std::pair<std::string, std::string>> JsonValueParser::maybeGetTypeAndValueName(
+        const std::string& jsonFieldValue) const {
+    size_t pos = jsonFieldValue.find(DELIMITER);
+    if (pos == std::string::npos) {
+        return {};
+    }
+    std::string type = jsonFieldValue.substr(0, pos);
+    std::string valueName = jsonFieldValue.substr(pos + DELIMITER.length(), std::string::npos);
+    if (type != "Constants" && mConstantParsersByType.find(type) == mConstantParsersByType.end()) {
+        return {};
+    }
+    return std::make_pair(type, valueName);
+}
+
+Result<int> JsonValueParser::parseConstantValue(
+        const std::pair<std::string, std::string>& typeValueName) const {
+    const std::string& type = typeValueName.first;
+    const std::string& valueName = typeValueName.second;
+    auto it = mConstantParsersByType.find(type);
+    if (it == mConstantParsersByType.end()) {
+        return Error() << "Unrecognized type: " << type;
+    }
+    auto result = it->second->parseValue(valueName);
+    if (!result.ok()) {
+        return Error() << type << "::" << valueName << " undefined";
+    }
+    return result;
+}
+
+template <class T>
+bool JsonConfigParser::tryParseJsonValueToVariable(const Json::Value& parentJsonNode,
+                                                   const std::string& fieldName,
+                                                   bool fieldIsOptional, T* outPtr,
+                                                   std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return false;
+    }
+    if (!parentJsonNode.isMember(fieldName)) {
+        if (!fieldIsOptional) {
+            errors->push_back("Missing required field: " + fieldName +
+                              " in node: " + parentJsonNode.toStyledString());
+            return false;
+        }
+        return true;
+    }
+    auto result = mValueParser.parseValue<T>(fieldName, parentJsonNode[fieldName]);
+    if (!result.ok()) {
+        errors->push_back(result.error().message());
+        return false;
+    }
+    *outPtr = std::move(result.value());
+    return true;
+}
+
+template <class T>
+bool JsonConfigParser::tryParseJsonArrayToVariable(const Json::Value& parentJsonNode,
+                                                   const std::string& fieldName,
+                                                   bool fieldIsOptional, std::vector<T>* outPtr,
+                                                   std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return false;
+    }
+    if (!parentJsonNode.isMember(fieldName)) {
+        if (!fieldIsOptional) {
+            errors->push_back("Missing required field: " + fieldName +
+                              " in node: " + parentJsonNode.toStyledString());
+            return false;
+        }
+        return true;
+    }
+    auto result = mValueParser.parseArray<T>(fieldName, parentJsonNode[fieldName]);
+    if (!result.ok()) {
+        errors->push_back(result.error().message());
+        return false;
+    }
+    *outPtr = std::move(result.value());
+    return true;
+}
+
+template <class T>
+void JsonConfigParser::parseAccessChangeMode(const Json::Value& parentJsonNode,
+                                             const std::string& fieldName,
+                                             const std::string& propStr,
+                                             const T* defaultAccessChangeModeValuePtr, T* outPtr,
+                                             std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return;
+    }
+    if (parentJsonNode.isMember(fieldName)) {
+        auto result = mValueParser.parseValue<int32_t>(fieldName, parentJsonNode[fieldName]);
+        if (!result.ok()) {
+            errors->push_back(result.error().message());
+            return;
+        }
+        *outPtr = static_cast<T>(result.value());
+        return;
+    }
+    if (defaultAccessChangeModeValuePtr == NULL) {
+        errors->push_back("No " + fieldName + " specified for property: " + propStr);
+        return;
+    }
+    *outPtr = *defaultAccessChangeModeValuePtr;
+    return;
+}
+
+bool JsonConfigParser::parsePropValues(const Json::Value& parentJsonNode,
+                                       const std::string& fieldName, RawPropValues* outPtr,
+                                       std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return false;
+    }
+    if (!parentJsonNode.isMember(fieldName)) {
+        return false;
+    }
+    const Json::Value& jsonValue = parentJsonNode[fieldName];
+    bool success = true;
+    success &= tryParseJsonArrayToVariable(jsonValue, "int32Values",
+                                           /*optional=*/true, &(outPtr->int32Values), errors);
+    success &= tryParseJsonArrayToVariable(jsonValue, "floatValues",
+                                           /*optional=*/true, &(outPtr->floatValues), errors);
+    success &= tryParseJsonArrayToVariable(jsonValue, "int64Values",
+                                           /*optional=*/true, &(outPtr->int64Values), errors);
+    // We don't support "byteValues" yet.
+    success &= tryParseJsonValueToVariable(jsonValue, "stringValue",
+                                           /*optional=*/true, &(outPtr->stringValue), errors);
+    return success;
+}
+
+void JsonConfigParser::parseAreas(const Json::Value& parentJsonNode, const std::string& fieldName,
+                                  ConfigDeclaration* config, std::vector<std::string>* errors) {
+    if (!parentJsonNode.isObject()) {
+        errors->push_back("Node: " + parentJsonNode.toStyledString() + " is not an object");
+        return;
+    }
+    if (!parentJsonNode.isMember(fieldName)) {
+        return;
+    }
+    std::string propStr = parentJsonNode["property"].toStyledString();
+    const Json::Value& jsonValue = parentJsonNode[fieldName];
+
+    if (!jsonValue.isArray()) {
+        errors->push_back("Field: " + fieldName + " is not an array");
+        return;
+    }
+    for (unsigned int i = 0; i < jsonValue.size(); i++) {
+        int32_t areaId;
+        const Json::Value& jsonAreaConfig = jsonValue[i];
+        if (!tryParseJsonValueToVariable(jsonAreaConfig, "areaId",
+                                         /*optional=*/false, &areaId, errors)) {
+            continue;
+        }
+        VehicleAreaConfig areaConfig = {};
+        areaConfig.areaId = areaId;
+        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);
+
+        // 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);
+
+        std::vector<int64_t> supportedEnumValues;
+        tryParseJsonArrayToVariable(jsonAreaConfig, "supportedEnumValues", /*optional=*/true,
+                                    &supportedEnumValues, errors);
+        if (!supportedEnumValues.empty()) {
+            areaConfig.supportedEnumValues = std::move(supportedEnumValues);
+        }
+        config->config.areaConfigs.push_back(std::move(areaConfig));
+
+        RawPropValues areaValue = {};
+        if (parsePropValues(jsonAreaConfig, "defaultValue", &areaValue, errors)) {
+            config->initialAreaValues[areaId] = std::move(areaValue);
+        }
+    }
+}
+
+std::optional<ConfigDeclaration> JsonConfigParser::parseEachProperty(
+        const Json::Value& propJsonValue, std::vector<std::string>* errors) {
+    size_t initialErrorCount = errors->size();
+    ConfigDeclaration configDecl = {};
+    int32_t propId;
+
+    if (!tryParseJsonValueToVariable(propJsonValue, "property", /*optional=*/false, &propId,
+                                     errors)) {
+        return std::nullopt;
+    }
+
+    configDecl.config.prop = propId;
+    std::string propStr = propJsonValue["property"].toStyledString();
+    VehiclePropertyAccess* defaultAccessMode = NULL;
+    auto itAccess = AccessForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+    if (itAccess != AccessForVehicleProperty.end()) {
+        defaultAccessMode = &itAccess->second;
+    }
+    VehiclePropertyChangeMode* defaultChangeMode = NULL;
+    auto itChangeMode = ChangeModeForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+    if (itChangeMode != ChangeModeForVehicleProperty.end()) {
+        defaultChangeMode = &itChangeMode->second;
+    }
+    parseAccessChangeMode(propJsonValue, "access", propStr, defaultAccessMode,
+                          &configDecl.config.access, errors);
+
+    parseAccessChangeMode(propJsonValue, "changeMode", propStr, defaultChangeMode,
+                          &configDecl.config.changeMode, errors);
+
+    tryParseJsonValueToVariable(propJsonValue, "configString", /*optional=*/true,
+                                &configDecl.config.configString, errors);
+
+    tryParseJsonArrayToVariable(propJsonValue, "configArray", /*optional=*/true,
+                                &configDecl.config.configArray, errors);
+
+    parsePropValues(propJsonValue, "defaultValue", &configDecl.initialValue, errors);
+
+    tryParseJsonValueToVariable(propJsonValue, "minSampleRate", /*optional=*/true,
+                                &configDecl.config.minSampleRate, errors);
+
+    tryParseJsonValueToVariable(propJsonValue, "maxSampleRate", /*optional=*/true,
+                                &configDecl.config.maxSampleRate, errors);
+
+    parseAreas(propJsonValue, "areas", &configDecl, errors);
+
+    // If there is no area config, by default we allow variable update rate, so we have to add
+    // a global area config.
+    if (configDecl.config.areaConfigs.size() == 0) {
+        VehicleAreaConfig areaConfig = {
+                .areaId = 0,
+                .access = configDecl.config.access,
+                .supportVariableUpdateRate = true,
+        };
+        configDecl.config.areaConfigs.push_back(std::move(areaConfig));
+    }
+
+    if (errors->size() != initialErrorCount) {
+        return std::nullopt;
+    }
+
+    return configDecl;
+}
+
+Result<std::unordered_map<int32_t, ConfigDeclaration>> JsonConfigParser::parseJsonConfig(
+        std::istream& is) {
+    Json::CharReaderBuilder builder;
+    Json::Value root;
+    std::unordered_map<int32_t, ConfigDeclaration> configsByPropId;
+    std::string errs;
+    if (!Json::parseFromStream(builder, is, &root, &errs)) {
+        return Error() << "Failed to parse property config file as JSON, error: " << errs;
+    }
+    if (!root.isObject()) {
+        return Error() << "root element must be an object";
+    }
+    if (!root.isMember("properties") || !root["properties"].isArray()) {
+        return Error() << "Missing 'properties' field in root or the field is not an array";
+    }
+    Json::Value properties = root["properties"];
+    std::vector<std::string> errors;
+    for (unsigned int i = 0; i < properties.size(); i++) {
+        if (auto maybeConfig = parseEachProperty(properties[i], &errors); maybeConfig.has_value()) {
+            configsByPropId[maybeConfig.value().config.prop] = std::move(maybeConfig.value());
+        }
+    }
+    if (!errors.empty()) {
+        return Error() << android::base::Join(errors, '\n');
+    }
+    return configsByPropId;
+}
+
+}  // namespace jsonconfigloader_impl
+
+JsonConfigLoader::JsonConfigLoader() {
+    mParser = std::make_unique<jsonconfigloader_impl::JsonConfigParser>();
+}
+
+android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>>
+JsonConfigLoader::loadPropConfig(std::istream& is) {
+    return mParser->parseJsonConfig(is);
+}
+
+android::base::Result<std::unordered_map<int32_t, ConfigDeclaration>>
+JsonConfigLoader::loadPropConfig(const std::string& configPath) {
+    std::ifstream ifs(configPath.c_str());
+    if (!ifs) {
+        return android::base::Error() << "couldn't open " << configPath << " for parsing.";
+    }
+
+    return loadPropConfig(ifs);
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp b/automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
copy to automotive/vehicle/aidl/impl/current/default_config/JsonConfigLoader/test/JsonConfigLoaderUnitTest.cpp
diff --git a/automotive/vehicle/aidl/impl/default_config/TEST_MAPPING b/automotive/vehicle/aidl/impl/current/default_config/TEST_MAPPING
similarity index 100%
copy from automotive/vehicle/aidl/impl/default_config/TEST_MAPPING
copy to automotive/vehicle/aidl/impl/current/default_config/TEST_MAPPING
diff --git a/automotive/vehicle/aidl/impl/default_config/config/Android.bp b/automotive/vehicle/aidl/impl/current/default_config/config/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/config/Android.bp
rename to automotive/vehicle/aidl/impl/current/default_config/config/Android.bp
diff --git a/automotive/vehicle/aidl/impl/current/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/current/default_config/config/DefaultProperties.json
new file mode 100644
index 0000000..86ac92e
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/default_config/config/DefaultProperties.json
@@ -0,0 +1,5260 @@
+{
+    "apiVersion": 1,
+    "properties": [
+        {
+            "property": "VehicleProperty::INFO_FUEL_CAPACITY",
+            "defaultValue": {
+                "floatValues": [
+                    15000.0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_FUEL_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    "FuelType::FUEL_TYPE_UNLEADED"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_EV_BATTERY_CAPACITY",
+            "defaultValue": {
+                "floatValues": [
+                    150000.0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_EV_CONNECTOR_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    "EvConnectorType::IEC_TYPE_1_AC"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_FUEL_DOOR_LOCATION",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::FUEL_DOOR_REAR_LEFT"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_EV_PORT_LOCATION",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::CHARGE_PORT_FRONT_LEFT"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::CHARGE_PORT_FRONT_LEFT",
+                    "Constants::CHARGE_PORT_REAR_LEFT"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_VIN",
+            "defaultValue": {
+                "stringValue": "1GCARVIN123456789"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MAKE",
+            "defaultValue": {
+                "stringValue": "Toy Vehicle"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MODEL",
+            "defaultValue": {
+                "stringValue": "Speedy Model"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MODEL_YEAR",
+            "defaultValue": {
+                "int32Values": [
+                    2023
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_EXTERIOR_DIMENSIONS",
+            "defaultValue": {
+                "int32Values": [
+                    1776,
+                    4950,
+                    2008,
+                    2140,
+                    2984,
+                    1665,
+                    1667,
+                    11800
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_MODEL_TRIM",
+            "defaultValue": {
+                "stringValue": "Sport"
+            }
+        },
+        {
+            "property": "VehicleProperty::INFO_VEHICLE_SIZE_CLASS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleSizeClass::EU_A_SEGMENT",
+                    "VehicleSizeClass::JPN_KEI"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::PERF_VEHICLE_SPEED",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::MILES_PER_HOUR"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::METER_PER_SEC",
+                "VehicleUnit::MILES_PER_HOUR",
+                "VehicleUnit::KILOMETERS_PER_HOUR"
+            ]
+        },
+        {
+            "property": "VehicleProperty::EV_BATTERY_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::KILOWATT_HOUR"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::WATT_HOUR",
+                "VehicleUnit::AMPERE_HOURS",
+                "VehicleUnit::KILOWATT_HOUR"
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_MEMORY_SELECT",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_MEMORY_SET",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BELT_BUCKLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BELT_HEIGHT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    10
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BELT_HEIGHT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FORE_AFT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FORE_AFT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEIGHT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEIGHT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_DEPTH_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_DEPTH_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_TILT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_TILT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_ANGLE_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_ANGLE_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT_2_RIGHT_2_CENTER",
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_EASY_ACCESS_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_AIRBAG_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_WALK_IN_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 5
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 5
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_AIRBAGS_DEPLOYED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "supportedEnumValues": [
+                        "VehicleAirbagLocation::FRONT",
+                        "VehicleAirbagLocation::KNEE",
+                        "VehicleAirbagLocation::LEFT_SIDE",
+                        "VehicleAirbagLocation::RIGHT_SIDE",
+                        "VehicleAirbagLocation::CURTAIN"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "supportedEnumValues": [
+                        "VehicleAirbagLocation::FRONT",
+                        "VehicleAirbagLocation::KNEE",
+                        "VehicleAirbagLocation::LEFT_SIDE",
+                        "VehicleAirbagLocation::RIGHT_SIDE",
+                        "VehicleAirbagLocation::CURTAIN"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "supportedEnumValues": [
+                        "VehicleAirbagLocation::FRONT",
+                        "VehicleAirbagLocation::CURTAIN"
+                    ]
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "supportedEnumValues": [
+                        "VehicleAirbagLocation::FRONT",
+                        "VehicleAirbagLocation::CURTAIN"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::SEAT_OCCUPANCY",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleSeatOccupancyState::VACANT"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::INFO_DRIVER_SEAT",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::SEAT_1_LEFT"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::PERF_ODOMETER",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::PERF_STEERING_ANGLE",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::PERF_REAR_STEERING_ANGLE",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::INSTANTANEOUS_FUEL_ECONOMY",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::INSTANTANEOUS_EV_EFFICIENCY",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::ENGINE_RPM",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::FUEL_LEVEL",
+            "defaultValue": {
+                "floatValues": [
+                    15000.0
+                ]
+            },
+            "maxSampleRate": 100.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::FUEL_DOOR_OPEN",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_BATTERY_LEVEL",
+            "defaultValue": {
+                "floatValues": [
+                    150000.0
+                ]
+            },
+            "maxSampleRate": 100.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::EV_CURRENT_BATTERY_CAPACITY",
+            "defaultValue": {
+                "floatValues": [
+                    150000.0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_PORT_OPEN",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_PORT_CONNECTED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT",
+            "defaultValue": {
+                "floatValues": [
+                    12.5
+                ]
+            },
+            "comment": "ConfigArray specifies Max current draw allowed by vehicle in amperes",
+            "configArray": [
+                20
+            ]
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_PERCENT_LIMIT",
+            "defaultValue": {
+                "floatValues": [
+                    40.0
+                ]
+            },
+            "configArray": [
+                20,
+                40,
+                60,
+                80,
+                100
+            ]
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    2
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_CHARGE_TIME_REMAINING",
+            "defaultValue": {
+                "int32Values": [
+                    20
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::EV_REGENERATIVE_BRAKING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    2
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::TRAILER_PRESENT",
+            "defaultValue": {
+                "int32Values": [
+                    2
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_CURB_WEIGHT",
+            "defaultValue": {
+                "int32Values": [
+                    2211
+                ]
+            },
+            "configArray": [
+                2948
+            ],
+            "comment": "unit is kg"
+        },
+        {
+            "property": "VehicleProperty::RANGE_REMAINING",
+            "defaultValue": {
+                "floatValues": [
+                    50000.0
+                ]
+            },
+            "comment": "units in meter",
+            "maxSampleRate": 2.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE",
+            "defaultValue": {
+                "floatValues": [
+                    25.0
+                ]
+            },
+            "maxSampleRate": 2.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::TIRE_PRESSURE",
+            "defaultValue": {
+                "floatValues": [
+                    200.0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::WHEEL_FRONT_LEFT",
+                    "minFloatValue": 193.0,
+                    "maxFloatValue": 300.0
+                },
+                {
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT",
+                    "minFloatValue": 193.0,
+                    "maxFloatValue": 300.0
+                },
+                {
+                    "areaId": "Constants::WHEEL_REAR_LEFT",
+                    "minFloatValue": 193.0,
+                    "maxFloatValue": 300.0
+                },
+                {
+                    "areaId": "Constants::WHEEL_REAR_RIGHT",
+                    "minFloatValue": 193.0,
+                    "maxFloatValue": 300.0
+                }
+            ],
+            "comment": "Units in kpa",
+            "maxSampleRate": 2.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            137.0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_FRONT_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            137.0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            137.0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_REAR_RIGHT"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            137.0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_REAR_LEFT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::BRAKE_PEDAL_COMPRESSION_PERCENTAGE",
+            "defaultValue": {
+                "floatValues": [
+                    0.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::BRAKE_PAD_WEAR_PERCENTAGE",
+            "areas": [
+                {
+                    "areaId": "Constants::WHEEL_FRONT_LEFT",
+                    "defaultValue": {
+                        "floatValues": [
+                            0.0
+                        ]
+                    }
+                },
+                {
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT",
+                    "defaultValue": {
+                        "floatValues": [
+                            0.0
+                        ]
+                    }
+                },
+                {
+                    "areaId": "Constants::WHEEL_REAR_LEFT",
+                    "defaultValue": {
+                        "floatValues": [
+                            0.0
+                        ]
+                    }
+                },
+                {
+                    "areaId": "Constants::WHEEL_REAR_RIGHT",
+                    "defaultValue": {
+                        "floatValues": [
+                            0.0
+                        ]
+                    }
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::BRAKE_FLUID_LEVEL_LOW",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_PASSIVE_SUSPENSION_HEIGHT",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_FRONT_LEFT",
+                    "minInt32Value": -100,
+                    "maxInt32Value": 100
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_FRONT_RIGHT",
+                    "minInt32Value": -100,
+                    "maxInt32Value": 100
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_REAR_RIGHT",
+                    "minInt32Value": -100,
+                    "maxInt32Value": 100
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "Constants::WHEEL_REAR_LEFT",
+                    "minInt32Value": -100,
+                    "maxInt32Value": 100
+                }
+            ],
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::PSI"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::KILOPASCAL",
+                "VehicleUnit::PSI",
+                "VehicleUnit::BAR"
+            ]
+        },
+        {
+            "property": "VehicleProperty::CURRENT_GEAR",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleGear::GEAR_PARK"
+                ]
+            },
+            "configArray": [
+                "VehicleGear::GEAR_PARK",
+                "VehicleGear::GEAR_NEUTRAL",
+                "VehicleGear::GEAR_REVERSE",
+                "VehicleGear::GEAR_1",
+                "VehicleGear::GEAR_2",
+                "VehicleGear::GEAR_3",
+                "VehicleGear::GEAR_4",
+                "VehicleGear::GEAR_5"
+            ]
+        },
+        {
+            "property": "VehicleProperty::PARKING_BRAKE_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::PARKING_BRAKE_AUTO_APPLY",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EV_BRAKE_REGENERATION_LEVEL",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::EV_STOPPING_MODE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::EV_STOPPING_MODE_CREEP"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::EV_STOPPING_MODE_CREEP",
+                        "Constants::EV_STOPPING_MODE_ROLL",
+                        "Constants::EV_STOPPING_MODE_HOLD"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::FUEL_LEVEL_LOW",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::US_GALLON"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::LITER",
+                "VehicleUnit::US_GALLON"
+            ]
+        },
+        {
+            "property": "VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HW_KEY_INPUT",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HW_KEY_INPUT_V2",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0,
+                    0
+                ],
+                "int64Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HW_MOTION_INPUT",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0,
+                    0,
+                    1,
+                    0,
+                    0
+                ],
+                "floatValues": [
+                    0,
+                    0,
+                    0,
+                    0
+                ],
+                "int64Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HW_ROTARY_INPUT",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HW_CUSTOM_INPUT",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    0,
+                    0
+                ]
+            },
+            "configArray": [
+                0,
+                0,
+                0,
+                3,
+                0,
+                0,
+                0,
+                0,
+                0
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM",
+            "defaultValue": {
+                "int32Values": [
+                    50
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_POWER_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ],
+            "configArray": [
+                "VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM",
+                "VehicleProperty::HVAC_AC_ON",
+                "VehicleProperty::HVAC_AUTO_ON",
+                "VehicleProperty::HVAC_AUTO_RECIRC_ON",
+                "VehicleProperty::HVAC_FAN_DIRECTION",
+                "VehicleProperty::HVAC_FAN_SPEED",
+                "VehicleProperty::HVAC_MAX_AC_ON",
+                "VehicleProperty::HVAC_RECIRC_ON",
+                "VehicleProperty::HVAC_TEMPERATURE_CURRENT",
+                "VehicleProperty::HVAC_TEMPERATURE_SET"
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_DEFROSTER",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
+                }
+            ],
+            "comment": "0 means using for all areas"
+        },
+        {
+            "property": "VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD"
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD"
+                }
+            ],
+            "comment": "0 means using for all areas"
+        },
+        {
+            "property": "VehicleProperty::HVAC_MAX_DEFROST_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_FRONT_ROW"
+                },
+                {
+                    "areaId": "Constants::HVAC_REAR_ROW"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_RECIRC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AUTO_RECIRC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_MAX_AC_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_AUTO_ON",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_DUAL_ON",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::HVAC_ALL"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_SPEED",
+            "defaultValue": {
+                "int32Values": [
+                    3
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 1,
+                    "maxInt32Value": 7
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_DIRECTION",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleHvacFanDirection::FACE"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::FAN_DIRECTION_UNKNOWN",
+                    "Constants::FAN_DIRECTION_FACE",
+                    "Constants::FAN_DIRECTION_FLOOR",
+                    "Constants::FAN_DIRECTION_FACE_FLOOR",
+                    "Constants::FAN_DIRECTION_DEFROST",
+                    "Constants::FAN_DIRECTION_FACE_DEFROST",
+                    "Constants::FAN_DIRECTION_FLOOR_DEFROST",
+                    "Constants::FAN_DIRECTION_FLOOR_DEFROST_FACE"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_SEAT_VENTILATION",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3
+                }
+            ],
+            "comment": "0 is off and +ve values indicate ventilation level."
+        },
+        {
+            "property": "VehicleProperty::HVAC_STEERING_WHEEL_HEAT",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                }
+            ],
+            "comment": "+ve values for heating and -ve for cooling"
+        },
+        {
+            "property": "VehicleProperty::HVAC_SEAT_TEMPERATURE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                }
+            ],
+            "comment": "+ve values for heating and -ve for cooling"
+        },
+        {
+            "property": "VehicleProperty::HVAC_SIDE_MIRROR_HEAT",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 2
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_CURRENT",
+            "defaultValue": {
+                "floatValues": [
+                    19.1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_SET",
+            "defaultValue": {
+                "floatValues": [
+                    17.0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER",
+                    "minFloatValue": 16.0,
+                    "maxFloatValue": 28.0
+                }
+            ],
+            "comment":
+                    "minFloatValue and maxFloatValue in area config should match corresponding values in configArray",
+            "configArray": [
+                160,
+                280,
+                5,
+                608,
+                824,
+                9
+            ]
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION",
+            "defaultValue": {
+                "floatValues": [
+                    66.19999694824219,
+                    "VehicleUnit::FAHRENHEIT",
+                    19.0,
+                    66.2
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ENV_OUTSIDE_TEMPERATURE",
+            "defaultValue": {
+                "floatValues": [
+                    25.0
+                ]
+            },
+            "maxSampleRate": 2.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::FAHRENHEIT"
+                ]
+            },
+            "configArray": [
+                "VehicleUnit::FAHRENHEIT",
+                "VehicleUnit::CELSIUS"
+            ]
+        },
+        {
+            "property": "VehicleProperty::DISTANCE_DISPLAY_UNITS",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleUnit::MILE"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0
+                }
+            ],
+            "configArray": [
+                "VehicleUnit::KILOMETER",
+                "VehicleUnit::MILE"
+            ]
+        },
+        {
+            "property": "VehicleProperty::NIGHT_MODE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::GEAR_SELECTION",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleGear::GEAR_PARK"
+                ]
+            },
+            "configArray": [
+                "VehicleGear::GEAR_PARK",
+                "VehicleGear::GEAR_NEUTRAL",
+                "VehicleGear::GEAR_REVERSE",
+                "VehicleGear::GEAR_DRIVE",
+                "VehicleGear::GEAR_1",
+                "VehicleGear::GEAR_2",
+                "VehicleGear::GEAR_3",
+                "VehicleGear::GEAR_4",
+                "VehicleGear::GEAR_5"
+            ]
+        },
+        {
+            "property": "VehicleProperty::TURN_SIGNAL_LIGHT_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleTurnSignal::NONE"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::TURN_SIGNAL_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleTurnSignal::NONE"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::IGNITION_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleIgnitionState::ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ENGINE_COOLANT_TEMP",
+            "defaultValue": {
+                "floatValues": [
+                    75.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::ENGINE_OIL_LEVEL",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleOilLevel::NORMAL"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ENGINE_OIL_TEMP",
+            "defaultValue": {
+                "floatValues": [
+                    101.0
+                ]
+            },
+            "maxSampleRate": 10.0,
+            "minSampleRate": 0.10000000149011612
+        },
+        {
+            "property": "VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::IMPACT_DETECTED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_HORN_ENGAGED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::DOOR_LOCK",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_1_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_1_RIGHT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_2_LEFT"
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1
+                        ]
+                    },
+                    "areaId": "Constants::DOOR_2_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DOOR_CHILD_LOCK_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::DOOR_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::DOOR_2_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DOOR_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::DOOR_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_REAR",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DOOR_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::DOOR_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::DOOR_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_Z_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_Z_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_Y_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+                    "minInt32Value": -3,
+                    "maxInt32Value": 3
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_Y_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "VehicleAreaMirror::DRIVER_CENTER",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_LOCK",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::MIRROR_FOLD",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::MIRROR_AUTO_FOLD_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::MIRROR_AUTO_TILT_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::MIRROR_DRIVER_LEFT_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDOW_LOCK",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            0
+                        ]
+                    },
+                    "areaId": "Constants::WINDOW_1_RIGHT_2_LEFT_2_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDOW_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::WINDOW_1_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::WINDOW_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::WINDOW_2_LEFT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::WINDOW_2_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                },
+                {
+                    "areaId": "Constants::WINDOW_ROOF_TOP_1",
+                    "minInt32Value": -10,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDOW_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::WINDOW_1_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::WINDOW_1_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::WINDOW_2_LEFT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::WINDOW_2_RIGHT",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                },
+                {
+                    "areaId": "Constants::WINDOW_ROOF_TOP_1",
+                    "minInt32Value": -1,
+                    "maxInt32Value": 1
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDSHIELD_WIPERS_PERIOD",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3000
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 3000
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDSHIELD_WIPERS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "WindshieldWipersState::OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+                    "supportedEnumValues": [
+                        "WindshieldWipersState::OFF",
+                        "WindshieldWipersState::ON",
+                        "WindshieldWipersState::SERVICE"
+                    ]
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+                    "supportedEnumValues": [
+                        "WindshieldWipersState::OFF",
+                        "WindshieldWipersState::ON"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WINDSHIELD_WIPERS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "WindshieldWipersSwitch::OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "VehicleAreaWindow::FRONT_WINDSHIELD",
+                    "supportedEnumValues": [
+                        "WindshieldWipersSwitch::OFF",
+                        "WindshieldWipersSwitch::MIST",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_1",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_2",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_3",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_4",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_5",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_1",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_2",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_3",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_4",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_5",
+                        "WindshieldWipersSwitch::AUTO",
+                        "WindshieldWipersSwitch::SERVICE"
+                    ]
+                },
+                {
+                    "areaId": "VehicleAreaWindow::REAR_WINDSHIELD",
+                    "supportedEnumValues": [
+                        "WindshieldWipersSwitch::OFF",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_1",
+                        "WindshieldWipersSwitch::INTERMITTENT_LEVEL_2",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_1",
+                        "WindshieldWipersSwitch::CONTINUOUS_LEVEL_2",
+                        "WindshieldWipersSwitch::AUTO",
+                        "WindshieldWipersSwitch::SERVICE"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_DEPTH_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_DEPTH_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": -2,
+                    "maxInt32Value": 2
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_LOCKED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::GLOVE_BOX_DOOR_POS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT",
+                    "minInt32Value": 0,
+                    "maxInt32Value": 10
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::GLOVE_BOX_LOCKED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::WHEEL_TICK",
+            "defaultValue": {
+                "int64Values": [
+                    0,
+                    100000,
+                    200000,
+                    300000,
+                    400000
+                ]
+            },
+            "configArray": [
+                15,
+                50000,
+                50000,
+                50000,
+                50000
+            ],
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::ABS_ACTIVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::TRACTION_CONTROL_ACTIVE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::AP_POWER_STATE_REQ",
+            "configArray": [
+                0
+            ]
+        },
+        {
+            "property": "VehicleProperty::AP_POWER_STATE_REPORT",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleApPowerStateReport::WAIT_FOR_VHAL",
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::AP_POWER_BOOTUP_REASON",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleApPowerBootupReason::USER_POWER_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::PER_DISPLAY_BRIGHTNESS"
+        },
+        {
+            "property": "VehicleProperty::PER_DISPLAY_MAX_BRIGHTNESS",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    100,
+                    1,
+                    100,
+                    2,
+                    100,
+                    3,
+                    100
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VALET_MODE_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HEAD_UP_DISPLAY_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::OBD2_LIVE_FRAME",
+            "configArray": [
+                0,
+                0
+            ]
+        },
+        {
+            "property": "VehicleProperty::OBD2_FREEZE_FRAME",
+            "configArray": [
+                0,
+                0
+            ]
+        },
+        {
+            "property": "VehicleProperty::OBD2_FREEZE_FRAME_INFO"
+        },
+        {
+            "property": "VehicleProperty::OBD2_FREEZE_FRAME_CLEAR",
+            "configArray": [
+                1
+            ]
+        },
+        {
+            "property": "VehicleProperty::HEADLIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HIGH_BEAM_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FRONT_FOG_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::REAR_FOG_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HAZARD_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::CABIN_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::READING_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_LIGHTS_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_STATE_ON"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_STATE_OFF",
+                        "Constants::LIGHT_STATE_ON"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HEADLIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FRONT_FOG_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::REAR_FOG_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HAZARD_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::CABIN_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_OFF"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::READING_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_OFF"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": "Constants::SEAT_1_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_1_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_LEFT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_RIGHT"
+                },
+                {
+                    "areaId": "Constants::SEAT_2_CENTER"
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH",
+            "defaultValue": {
+                "int32Values": [
+                    "Constants::LIGHT_SWITCH_AUTO"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "Constants::LIGHT_SWITCH_OFF",
+                        "Constants::LIGHT_SWITCH_ON",
+                        "Constants::LIGHT_SWITCH_AUTO"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::EVS_SERVICE_REQUEST",
+            "defaultValue": {
+                "int32Values": [
+                    "EvsServiceType::REARVIEW",
+                    "EvsServiceState::OFF"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_MAP_SERVICE"
+        },
+        {
+            "property": "VehicleProperty::LOCATION_CHARACTERIZATION",
+            "defaultValue": {
+                "int32Values": [
+                    "LocationCharacterization::RAW_GNSS_ONLY"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ULTRASONICS_SENSOR_POSITION",
+            "comment":
+                    "Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            -1000,
+                            3900,
+                            0
+                        ]
+                    },
+                    "areaId": 1,
+                    "comment": "Rough numbers representing front left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            -600,
+                            4000,
+                            0
+                        ]
+                    },
+                    "areaId": 2,
+                    "comment": "Rough numbers representing front 2nd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            -200,
+                            4000,
+                            0
+                        ]
+                    },
+                    "areaId": 4,
+                    "comment": "Rough numbers representing front 3rd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            200,
+                            4000,
+                            0
+                        ]
+                    },
+                    "areaId": 8,
+                    "comment": "Rough numbers representing front 3rd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            600,
+                            4000,
+                            0
+                        ]
+                    },
+                    "areaId": 16,
+                    "comment": "Rough numbers representing front 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1000,
+                            3900,
+                            0
+                        ]
+                    },
+                    "areaId": 32,
+                    "comment": "Rough numbers representing front right most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            -1000,
+                            -900,
+                            0
+                        ]
+                    },
+                    "areaId": 64,
+                    "comment": "Rough numbers representing back left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            -600,
+                            -1000,
+                            0
+                        ]
+                    },
+                    "areaId": 128,
+                    "comment": "Rough numbers representing back 2nd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            -200,
+                            -1000,
+                            0
+                        ]
+                    },
+                    "areaId": 256,
+                    "comment": "Rough numbers representing back 3rd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            200,
+                            -1000,
+                            0
+                        ]
+                    },
+                    "areaId": 512,
+                    "comment": "Rough numbers representing back 3rd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            600,
+                            -1000,
+                            0
+                        ]
+                    },
+                    "areaId": 1024,
+                    "comment": "Rough numbers representing back 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1000,
+                            -900,
+                            0
+                        ]
+                    },
+                    "areaId": 2048,
+                    "comment": "Rough numbers representing back right most sensor."
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION",
+            "comment":
+                    "Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            0.924,
+                            0,
+                            0,
+                            0.383
+                        ]
+                    },
+                    "areaId": 1,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing front left most sensor rotated 45 degrees counter-clockwise."
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            1,
+                            0,
+                            0,
+                            0
+                        ]
+                    },
+                    "areaId": 2,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing front 2nd to the left sensor rotated 0 degrees"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            1,
+                            0,
+                            0,
+                            0
+                        ]
+                    },
+                    "areaId": 4,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing front 3rd to the left sensor rotated 0 degrees"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            1,
+                            0,
+                            0,
+                            0
+                        ]
+                    },
+                    "areaId": 8,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing front 3rd to the right sensor rotated 0 degrees"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            1,
+                            0,
+                            0,
+                            0
+                        ]
+                    },
+                    "areaId": 16,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing front 2nd to the right sensor rotated 0 degrees"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            0.924,
+                            0,
+                            0,
+                            -0.383
+                        ]
+                    },
+                    "areaId": 32,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing front right most sensor rotated 45 degrees clockwise."
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            60,
+                            61,
+                            62,
+                            63
+                        ]
+                    },
+                    "areaId": 64,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing back left most sensor rotated 45 degrees counter-clockwise."
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            70,
+                            71,
+                            72,
+                            73
+                        ]
+                    },
+                    "areaId": 128,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing back 2nd to the left sensor rotated 0 degrees"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            81,
+                            82,
+                            83,
+                            84
+                        ]
+                    },
+                    "areaId": 256,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing back 3rd to the right sensor rotated 0 degrees"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            90,
+                            91,
+                            92,
+                            93
+                        ]
+                    },
+                    "areaId": 512,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing back 3rd to the right sensor rotated 0 degrees"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            100,
+                            101,
+                            102,
+                            103
+                        ]
+                    },
+                    "areaId": 1024,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing back 2nd to the right sensor rotated 0 degrees"
+                },
+                {
+                    "defaultValue": {
+                        "floatValues": [
+                            110,
+                            111,
+                            112,
+                            113
+                        ]
+                    },
+                    "areaId": 2048,
+                    "comment":
+                            "Rough quaternion values [w, x, y, z] representing back right most sensor rotated 45 degrees clockwise."
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW",
+            "comment":
+                    "Default values for 12 individual ultrasonic sensors installed on the vehicle. Six sensors on the front bumper. Six sensors on the back bumper.",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            85,
+                            45
+                        ]
+                    },
+                    "areaId": 1,
+                    "comment": "Rough values representing front left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            75,
+                            45
+                        ]
+                    },
+                    "areaId": 2,
+                    "comment": "Rough values representing front 2nd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            75,
+                            45
+                        ]
+                    },
+                    "areaId": 4,
+                    "comment": "Rough values representing front 3rd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            75,
+                            45
+                        ]
+                    },
+                    "areaId": 8,
+                    "comment": "Rough values representing front 3rd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            75,
+                            45
+                        ]
+                    },
+                    "areaId": 16,
+                    "comment": "Rough values representing front 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            85,
+                            45
+                        ]
+                    },
+                    "areaId": 32,
+                    "comment": "Rough values representing front right most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            85,
+                            45
+                        ]
+                    },
+                    "areaId": 64,
+                    "comment": "Rough values representing back left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            75,
+                            45
+                        ]
+                    },
+                    "areaId": 128,
+                    "comment": "Rough values representing back 2nd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            75,
+                            45
+                        ]
+                    },
+                    "areaId": 256,
+                    "comment": "Rough values representing back 3rd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            75,
+                            45
+                        ]
+                    },
+                    "areaId": 512,
+                    "comment": "Rough values representing back 3rd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            75,
+                            45
+                        ]
+                    },
+                    "areaId": 1024,
+                    "comment": "Rough values representing back 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            85,
+                            45
+                        ]
+                    },
+                    "areaId": 2048,
+                    "comment": "Rough values representing back right most sensor."
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            4000
+                        ]
+                    },
+                    "areaId": 1,
+                    "comment": "Rough values representing front left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            3000
+                        ]
+                    },
+                    "areaId": 2,
+                    "comment": "Rough values representing front 2nd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            3000
+                        ]
+                    },
+                    "areaId": 4,
+                    "comment": "Rough values representing front 3rd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            3000
+                        ]
+                    },
+                    "areaId": 8,
+                    "comment": "Rough values representing front 3rd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            3000
+                        ]
+                    },
+                    "areaId": 16,
+                    "comment": "Rough values representing front 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            4000
+                        ]
+                    },
+                    "areaId": 32,
+                    "comment": "Rough values representing front right most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            4000
+                        ]
+                    },
+                    "areaId": 64,
+                    "comment": "Rough values representing back left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            3000
+                        ]
+                    },
+                    "areaId": 128,
+                    "comment": "Rough values representing back 2nd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            3000
+                        ]
+                    },
+                    "areaId": 256,
+                    "comment": "Rough values representing back 3rd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            3000
+                        ]
+                    },
+                    "areaId": 512,
+                    "comment": "Rough values representing back 3rd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            3000
+                        ]
+                    },
+                    "areaId": 1024,
+                    "comment": "Rough values representing back 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            4000
+                        ]
+                    },
+                    "areaId": 2048,
+                    "comment": "Rough values representing back right most sensor."
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            4000
+                        ]
+                    },
+                    "areaId": 1,
+                    "comment": "Rough values representing front left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            3000
+                        ]
+                    },
+                    "areaId": 2,
+                    "comment": "Rough values representing front 2nd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            3000
+                        ]
+                    },
+                    "areaId": 4,
+                    "comment": "Rough values representing front 3rd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            3000
+                        ]
+                    },
+                    "areaId": 8,
+                    "comment": "Rough values representing front 3rd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            3000
+                        ]
+                    },
+                    "areaId": 16,
+                    "comment": "Rough values representing front 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            4000
+                        ]
+                    },
+                    "areaId": 32,
+                    "comment": "Rough values representing front right most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            4000
+                        ]
+                    },
+                    "areaId": 64,
+                    "comment": "Rough values representing back left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            3000
+                        ]
+                    },
+                    "areaId": 128,
+                    "comment": "Rough values representing back 2nd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            3000
+                        ]
+                    },
+                    "areaId": 256,
+                    "comment": "Rough values representing back 3rd to the left sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            3000
+                        ]
+                    },
+                    "areaId": 512,
+                    "comment": "Rough values representing back 3rd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            3000
+                        ]
+                    },
+                    "areaId": 1024,
+                    "comment": "Rough values representing back 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            150,
+                            999,
+                            1000,
+                            1999,
+                            2000,
+                            4000
+                        ]
+                    },
+                    "areaId": 2048,
+                    "comment": "Rough values representing back right most sensor."
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE",
+            "areas": [
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            2000,
+                            10
+                        ]
+                    },
+                    "areaId": 1,
+                    "comment": "Rough values representing front left most sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": []
+                    },
+                    "areaId": 2,
+                    "comment":
+                            "Rough values representing front 2nd to the left sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": []
+                    },
+                    "areaId": 4,
+                    "comment":
+                            "Rough values representing front 3rd to the left sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": []
+                    },
+                    "areaId": 8,
+                    "comment":
+                            "Rough values representing front 3rd to the right sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": []
+                    },
+                    "areaId": 16,
+                    "comment":
+                            "Rough values representing front 2nd to the right sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": []
+                    },
+                    "areaId": 32,
+                    "comment":
+                            "Rough values representing front right most sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": []
+                    },
+                    "areaId": 64,
+                    "comment": "Rough values representing back left most sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": []
+                    },
+                    "areaId": 128,
+                    "comment":
+                            "Rough values representing back 2nd to the left sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": []
+                    },
+                    "areaId": 256,
+                    "comment":
+                            "Rough values representing back 3rd to the left sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            1000
+                        ]
+                    },
+                    "areaId": 512,
+                    "comment":
+                            "Rough values representing back 3rd to the right sensor. Nothing detected."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            2000,
+                            50
+                        ]
+                    },
+                    "areaId": 1024,
+                    "comment": "Rough values representing back 2nd to the right sensor."
+                },
+                {
+                    "defaultValue": {
+                        "int32Values": [
+                            2000
+                        ]
+                    },
+                    "areaId": 2048,
+                    "comment":
+                            "Rough values representing back right most sensor. No distance error."
+                }
+            ],
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "EmergencyLaneKeepAssistState::ENABLED"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_TYPE",
+            "defaultValue": {
+                "int32Values": [
+                    "CruiseControlType::ADAPTIVE"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "CruiseControlState::ENABLED"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CRUISE_CONTROL_TARGET_SPEED",
+            "defaultValue": {
+                "floatValues": [
+                    25.0
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minFloatValue": 20.0,
+                    "maxFloatValue": 35.0
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP",
+            "defaultValue": {
+                "int32Values": [
+                    1200
+                ]
+            },
+            "configArray": [
+                1200,
+                1400,
+                1600,
+                1800,
+                2000,
+                2200
+            ]
+        },
+        {
+            "property": "VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE",
+            "defaultValue": {
+                "int32Values": [
+                    100000
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "minInt32Value": 0,
+                    "maxInt32Value": 200000
+                }
+            ],
+            "maxSampleRate": 10.0,
+            "minSampleRate": 1.0
+        },
+        {
+            "property": "VehicleProperty::HANDS_ON_DETECTION_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "HandsOnDetectionDriverState::HANDS_ON"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "HandsOnDetectionDriverState::HANDS_ON",
+                        "HandsOnDetectionDriverState::HANDS_OFF"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::HANDS_ON_DETECTION_WARNING",
+            "defaultValue": {
+                "int32Values": [
+                    "HandsOnDetectionWarning::NO_WARNING"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "HandsOnDetectionWarning::NO_WARNING",
+                        "HandsOnDetectionWarning::WARNING"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "DriverDrowsinessAttentionState::KSS_RATING_3_ALERT"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING",
+            "defaultValue": {
+                "int32Values": [
+                    "DriverDrowsinessAttentionWarning::NO_WARNING"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "DriverDrowsinessAttentionWarning::NO_WARNING",
+                        "DriverDrowsinessAttentionWarning::WARNING"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::DRIVER_DISTRACTION_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "DriverDistractionState::NOT_DISTRACTED"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "DriverDistractionState::NOT_DISTRACTED",
+                        "DriverDistractionState::DISTRACTED"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::DRIVER_DISTRACTION_WARNING",
+            "defaultValue": {
+                "int32Values": [
+                    "DriverDistractionWarning::NO_WARNING"
+                ]
+            },
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportedEnumValues": [
+                        "ErrorState::NOT_AVAILABLE_DISABLED",
+                        "DriverDistractionWarning::NO_WARNING",
+                        "DriverDistractionWarning::WARNING"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::INITIAL_USER_INFO"
+        },
+        {
+            "property": "VehicleProperty::SWITCH_USER"
+        },
+        {
+            "property": "VehicleProperty::CREATE_USER"
+        },
+        {
+            "property": "VehicleProperty::REMOVE_USER"
+        },
+        {
+            "property": "VehicleProperty::USER_IDENTIFICATION_ASSOCIATION"
+        },
+        {
+            "property": "VehicleProperty::POWER_POLICY_REQ"
+        },
+        {
+            "property": "VehicleProperty::POWER_POLICY_GROUP_REQ"
+        },
+        {
+            "property": "VehicleProperty::CURRENT_POWER_POLICY"
+        },
+        {
+            "property": "VehicleProperty::ANDROID_EPOCH_TIME"
+        },
+        {
+            "property": "VehicleProperty::WATCHDOG_ALIVE"
+        },
+        {
+            "property": "VehicleProperty::WATCHDOG_TERMINATED_PROCESS"
+        },
+        {
+            "property": "VehicleProperty::VHAL_HEARTBEAT",
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportVariableUpdateRate": false
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_SWITCH_UI",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            },
+            "comment": "0 means ClusterHome"
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_DISPLAY_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    0,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1,
+                    -1
+                ]
+            },
+            "comment":
+                    "Value means: 0 /* Off */, -1, -1, -1, -1 /* Bounds */, -1, -1, -1, -1 /* Insets */"
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_REPORT_STATE",
+            "configArray": [
+                0,
+                0,
+                0,
+                11,
+                0,
+                0,
+                0,
+                0,
+                16
+            ]
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_REQUEST_DISPLAY"
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_NAVIGATION_STATE"
+        },
+        {
+            "property": "VehicleProperty::CLUSTER_HEARTBEAT",
+            "configArray": [
+                0,
+                0,
+                0,
+                0,
+                0,
+                2,
+                0,
+                0,
+                16
+            ],
+            "areas": [
+                {
+                    "areaId": 0,
+                    "supportVariableUpdateRate": false
+                }
+            ],
+            "comment": "configArray specifies it consists of int64[2] and byte[16]."
+        },
+        {
+            "property": "VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT",
+            "defaultValue": {
+                "int32Values": [
+                    "GsrComplianceRequirementType::GSR_COMPLIANCE_REQUIRED_V1"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::SHUTDOWN_REQUEST"
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_IN_USE",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleAutonomousState::LEVEL_0"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL",
+            "defaultValue": {
+                "int32Values": [
+                    "VehicleAutonomousState::LEVEL_0"
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    0
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "ErrorState::NOT_AVAILABLE_DISABLED"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::FORWARD_COLLISION_WARNING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "ForwardCollisionWarningState::NO_WARNING"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::BLIND_SPOT_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::BLIND_SPOT_WARNING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "BlindSpotWarningState::NO_WARNING"
+                ]
+            },
+            "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_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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_DEPARTURE_WARNING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "LaneDepartureWarningState::NO_WARNING"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::LANE_KEEP_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_KEEP_ASSIST_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "LaneKeepAssistState::ENABLED"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::LANE_CENTERING_ASSIST_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LANE_CENTERING_ASSIST_COMMAND"
+        },
+        {
+            "property": "VehicleProperty::LANE_CENTERING_ASSIST_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "LaneCenteringAssistState::ENABLED"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "LowSpeedCollisionWarningState::NO_WARNING"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "ElectronicStabilityControlState::ENABLED"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "CrossTrafficMonitoringWarningState::NO_WARNING"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
+            "defaultValue": {
+                "int32Values": [
+                    1
+                ]
+            }
+        },
+        {
+            "property": "VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "LowSpeedAutomaticEmergencyBrakingState::ENABLED"
+                ]
+            },
+            "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"
+                    ]
+                }
+            ]
+        },
+        {
+            "property": "VehicleProperty::CAMERA_SERVICE_CURRENT_STATE",
+            "defaultValue": {
+                "int32Values": [
+                    "CameraServiceState::UNAVAILABLE",
+                    "CameraServiceState::UNAVAILABLE",
+                    "CameraServiceState::UNAVAILABLE",
+                    "CameraServiceState::UNAVAILABLE",
+                    "CameraServiceState::UNAVAILABLE",
+                    "CameraServiceState::UNAVAILABLE",
+                    "CameraServiceState::UNAVAILABLE",
+                    "CameraServiceState::UNAVAILABLE"
+                ]
+            }
+        }
+    ]
+}
diff --git a/automotive/vehicle/aidl/impl/default_config/config/README.md b/automotive/vehicle/aidl/impl/current/default_config/config/README.md
similarity index 100%
copy from automotive/vehicle/aidl/impl/default_config/config/README.md
copy to automotive/vehicle/aidl/impl/current/default_config/config/README.md
diff --git a/automotive/vehicle/aidl/impl/default_config/config/TestProperties.json b/automotive/vehicle/aidl/impl/current/default_config/config/TestProperties.json
similarity index 100%
copy from automotive/vehicle/aidl/impl/default_config/config/TestProperties.json
copy to automotive/vehicle/aidl/impl/current/default_config/config/TestProperties.json
diff --git a/automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json b/automotive/vehicle/aidl/impl/current/default_config/config/VendorClusterTestProperties.json
similarity index 100%
copy from automotive/vehicle/aidl/impl/default_config/config/VendorClusterTestProperties.json
copy to automotive/vehicle/aidl/impl/current/default_config/config/VendorClusterTestProperties.json
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/current/default_config/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/default_config/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/default_config/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp b/automotive/vehicle/aidl/impl/current/default_config/test/DefaultConfigTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/default_config/test/DefaultConfigTest.cpp
copy to automotive/vehicle/aidl/impl/current/default_config/test/DefaultConfigTest.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/Android.bp b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/Android.bp
rename to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/Android.bp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/FakeValueGenerator.h b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/include/FakeValueGenerator.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/FakeValueGenerator.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/include/FakeValueGenerator.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/include/GeneratorHub.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/GeneratorHub.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/include/GeneratorHub.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/include/JsonFakeValueGenerator.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/include/LinearFakeValueGenerator.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/src/GeneratorHub.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/GeneratorHub.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/src/GeneratorHub.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/src/JsonFakeValueGenerator.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/src/LinearFakeValueGenerator.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/FakeVehicleHalValueGeneratorsTest.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/prop.json
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/prop.json
diff --git a/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/prop_different_types.json b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/prop_different_types.json
new file mode 100644
index 0000000..38cd86b
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/prop_different_types.json
@@ -0,0 +1,74 @@
+[
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 1,
+        "prop": 287310600
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 2,
+        "prop": 289408000
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 3.3,
+        "prop": 291504905
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": 4,
+        "prop": 290457096
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": "test",
+        "prop": 286265094
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": [
+            1,
+            2
+        ],
+        "prop": 289476368
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": {
+            "int32Values": [
+                1,
+                2
+            ],
+            "int64Values": [
+                3,
+                4
+            ],
+            "floatValues": [
+                5.5,
+                6.6
+            ],
+            "stringValue": "test"
+        },
+        "prop": 299896626
+    },
+    {
+        "timestamp": 1000000,
+        "areaId": 0,
+        "value": {
+            "int32Values": [
+                1
+            ],
+            "floatValues": [
+                1
+            ]
+        },
+        "prop": 299896064
+    }
+]
\ No newline at end of file
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_invalid.json b/automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/prop_invalid.json
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_invalid.json
copy to automotive/vehicle/aidl/impl/current/fake_impl/GeneratorHub/test/prop_invalid.json
diff --git a/automotive/vehicle/aidl/impl/fake_impl/README.md b/automotive/vehicle/aidl/impl/current/fake_impl/README.md
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/README.md
rename to automotive/vehicle/aidl/impl/current/fake_impl/README.md
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/Android.bp
rename to automotive/vehicle/aidl/impl/current/fake_impl/hardware/Android.bp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/hardware/include/FakeVehicleHardware.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
similarity index 99%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
rename to automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
index a6247a7..52daf68 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -928,8 +928,8 @@
     grpc::ClientContext context;
     auto status = clientStub->IsVehicleInUse(&context, request, &response);
     if (!status.ok()) {
-        return StatusError(StatusCode::TRY_AGAIN) << "Cannot connect to GRPC service "
-                                                  << ", error: " << status.error_message();
+        return StatusError(StatusCode::TRY_AGAIN)
+               << "Cannot connect to GRPC service " << ", error: " << status.error_message();
     }
     auto result = mValuePool->obtainBoolean(response.isvehicleinuse());
     result->prop = toInt(VehicleProperty::VEHICLE_IN_USE);
@@ -946,8 +946,8 @@
     grpc::ClientContext context;
     auto status = clientStub->GetApPowerBootupReason(&context, request, &response);
     if (!status.ok()) {
-        return StatusError(StatusCode::TRY_AGAIN) << "Cannot connect to GRPC service "
-                                                  << ", error: " << status.error_message();
+        return StatusError(StatusCode::TRY_AGAIN)
+               << "Cannot connect to GRPC service " << ", error: " << status.error_message();
     }
     auto result = mValuePool->obtainInt32(response.bootupreason());
     result->prop = toInt(VehicleProperty::AP_POWER_BOOTUP_REASON);
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/hardware/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/fakedata/prop.json
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/hardware/test/fakedata/prop.json
copy to automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/fakedata/prop.json
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/override/gear_selection.json
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/gear_selection.json
copy to automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/override/gear_selection.json
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json b/automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/override/hvac_temperature_set.json
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/hardware/test/override/hvac_temperature_set.json
copy to automotive/vehicle/aidl/impl/current/fake_impl/hardware/test/override/hvac_temperature_set.json
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/Android.bp b/automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/obd2frame/Android.bp
rename to automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/Android.bp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/FakeObd2Frame.h b/automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/include/FakeObd2Frame.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/FakeObd2Frame.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/include/FakeObd2Frame.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/Obd2SensorStore.h b/automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/include/Obd2SensorStore.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/obd2frame/include/Obd2SensorStore.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/include/Obd2SensorStore.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/FakeObd2Frame.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/src/FakeObd2Frame.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/FakeObd2Frame.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/src/FakeObd2Frame.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/Obd2SensorStore.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/src/Obd2SensorStore.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/obd2frame/src/Obd2SensorStore.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/src/Obd2SensorStore.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Android.bp b/automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/test/FakeObd2FrameTest.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Obd2SensorStoreTest.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/test/Obd2SensorStoreTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/obd2frame/test/Obd2SensorStoreTest.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/obd2frame/test/Obd2SensorStoreTest.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/Android.bp b/automotive/vehicle/aidl/impl/current/fake_impl/userhal/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/userhal/Android.bp
rename to automotive/vehicle/aidl/impl/current/fake_impl/userhal/Android.bp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h b/automotive/vehicle/aidl/impl/current/fake_impl/userhal/include/FakeUserHal.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/userhal/include/FakeUserHal.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/userhal/include/FakeUserHal.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/UserHalHelper.h b/automotive/vehicle/aidl/impl/current/fake_impl/userhal/include/UserHalHelper.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/userhal/include/UserHalHelper.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/userhal/include/UserHalHelper.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/include/UserHalTypes.h b/automotive/vehicle/aidl/impl/current/fake_impl/userhal/include/UserHalTypes.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/userhal/include/UserHalTypes.h
copy to automotive/vehicle/aidl/impl/current/fake_impl/userhal/include/UserHalTypes.h
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/userhal/src/FakeUserHal.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/userhal/src/FakeUserHal.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/userhal/src/FakeUserHal.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/src/UserHalHelper.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/userhal/src/UserHalHelper.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/userhal/src/UserHalHelper.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/userhal/src/UserHalHelper.cpp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/test/Android.bp b/automotive/vehicle/aidl/impl/current/fake_impl/userhal/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/fake_impl/userhal/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/fake_impl/userhal/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/fake_impl/userhal/test/UserHalHelper_test.cpp b/automotive/vehicle/aidl/impl/current/fake_impl/userhal/test/UserHalHelper_test.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/fake_impl/userhal/test/UserHalHelper_test.cpp
copy to automotive/vehicle/aidl/impl/current/fake_impl/userhal/test/UserHalHelper_test.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/Android.bp b/automotive/vehicle/aidl/impl/current/grpc/Android.bp
similarity index 89%
rename from automotive/vehicle/aidl/impl/grpc/Android.bp
rename to automotive/vehicle/aidl/impl/current/grpc/Android.bp
index 7a8da59..f798b72 100644
--- a/automotive/vehicle/aidl/impl/grpc/Android.bp
+++ b/automotive/vehicle/aidl/impl/current/grpc/Android.bp
@@ -22,7 +22,7 @@
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_opt=generate_mock_code=true --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/current/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_opt=generate_mock_code=true --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
         "proto/VehicleServer.proto",
         ":libprotobuf-internal-protos",
@@ -42,7 +42,7 @@
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -I$$(dirname $(location proto/VehicleServer.proto)) -Ihardware/interfaces/automotive/vehicle/aidl/impl/current/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(location proto/VehicleServer.proto) --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
         "proto/VehicleServer.proto",
         ":libprotobuf-internal-protos",
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.cpp
copy to automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.h
similarity index 97%
copy from automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
copy to automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.h
index 15f473c..ad2f512 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleHardware.h
@@ -115,9 +115,8 @@
     // A map from [propId, areaId] to the latest timestamp this property is updated.
     // The key is a tuple, the first element is the external timestamp (timestamp set by VHAL
     // server), the second element is the Android timestamp (elapsedRealtimeNano).
-    mutable std::unordered_map<PropIdAreaId, std::pair<int64_t, int64_t>,
-                               PropIdAreaIdHash> mLatestUpdateTimestamps
-            GUARDED_BY(mLatestUpdateTimestampsMutex);
+    mutable std::unordered_map<PropIdAreaId, std::pair<int64_t, int64_t>, PropIdAreaIdHash>
+            mLatestUpdateTimestamps GUARDED_BY(mLatestUpdateTimestampsMutex);
 
     // Only used for unit testing.
     GRPCVehicleHardware(std::unique_ptr<proto::VehicleServer::StubInterface> stub,
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.cpp
similarity index 99%
copy from automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
copy to automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.cpp
index 7697c03..927a595 100644
--- a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.cpp
+++ b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.cpp
@@ -40,7 +40,7 @@
 
 GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::string serverAddr,
                                                std::unique_ptr<IVehicleHardware>&& hardware)
-    : GrpcVehicleProxyServer(std::vector<std::string>({serverAddr}), std::move(hardware)){};
+    : GrpcVehicleProxyServer(std::vector<std::string>({serverAddr}), std::move(hardware)) {};
 
 GrpcVehicleProxyServer::GrpcVehicleProxyServer(std::vector<std::string> serverAddrs,
                                                std::unique_ptr<IVehicleHardware>&& hardware)
diff --git a/automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h b/automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/grpc/GRPCVehicleProxyServer.h
copy to automotive/vehicle/aidl/impl/current/grpc/GRPCVehicleProxyServer.h
diff --git a/automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto b/automotive/vehicle/aidl/impl/current/grpc/proto/VehicleServer.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/grpc/proto/VehicleServer.proto
copy to automotive/vehicle/aidl/impl/current/grpc/proto/VehicleServer.proto
diff --git a/automotive/vehicle/aidl/impl/grpc/test/Android.bp b/automotive/vehicle/aidl/impl/current/grpc/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/grpc/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp b/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleHardwareUnitTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleHardwareUnitTest.cpp
copy to automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleHardwareUnitTest.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp b/automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
copy to automotive/vehicle/aidl/impl/current/grpc/test/GRPCVehicleProxyServerUnitTest.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/Android.bp
rename to automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/Android.bp
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
copy to automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/include/ProtoMessageConverter.h
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
copy to automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/src/ProtoMessageConverter.cpp
diff --git a/automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp b/automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
copy to automotive/vehicle/aidl/impl/current/grpc/utils/proto_message_converter/test/proto_message_converter_test.cpp
diff --git a/automotive/vehicle/aidl/impl/hardware/Android.bp b/automotive/vehicle/aidl/impl/current/hardware/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/hardware/Android.bp
rename to automotive/vehicle/aidl/impl/current/hardware/Android.bp
diff --git a/automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h b/automotive/vehicle/aidl/impl/current/hardware/include/IVehicleHardware.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/hardware/include/IVehicleHardware.h
copy to automotive/vehicle/aidl/impl/current/hardware/include/IVehicleHardware.h
diff --git a/automotive/vehicle/aidl/impl/proto/Android.bp b/automotive/vehicle/aidl/impl/current/proto/Android.bp
similarity index 92%
rename from automotive/vehicle/aidl/impl/proto/Android.bp
rename to automotive/vehicle/aidl/impl/current/proto/Android.bp
index 0d3df49..2b5cdf4 100644
--- a/automotive/vehicle/aidl/impl/proto/Android.bp
+++ b/automotive/vehicle/aidl/impl/current/proto/Android.bp
@@ -35,7 +35,7 @@
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -Ihardware/interfaces/automotive/vehicle/aidl/impl/current/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
         ":VehicleHalProtoFiles",
     ],
@@ -62,7 +62,7 @@
         "aprotoc",
         "protoc-gen-grpc-cpp-plugin",
     ],
-    cmd: "$(location aprotoc) -Ihardware/interfaces/automotive/vehicle/aidl/impl/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
+    cmd: "$(location aprotoc) -Ihardware/interfaces/automotive/vehicle/aidl/impl/current/proto -Iexternal/protobuf/src --plugin=protoc-gen-grpc=$(location protoc-gen-grpc-cpp-plugin) $(in) --grpc_out=$(genDir) --cpp_out=$(genDir)",
     srcs: [
         ":VehicleHalProtoFiles",
     ],
@@ -123,4 +123,5 @@
     proto_flags: [
         "-I external/protobuf/src",
     ],
+    min_sdk_version: "35",
 }
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpOptions.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/DumpOptions.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpOptions.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/DumpOptions.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpResult.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/DumpResult.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/DumpResult.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/DumpResult.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/StatusCode.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/StatusCode.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/StatusCode.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/StatusCode.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/SubscribeOptions.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/SubscribeRequest.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/UnsubscribeRequest.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehicleAreaConfig.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropConfig.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropConfig.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropConfig.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropConfig.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropValue.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropValueRequest.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyAccess.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropertyAccess.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyAccess.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropertyAccess.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.proto
diff --git a/automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyStatus.proto b/automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropertyStatus.proto
similarity index 100%
copy from automotive/vehicle/aidl/impl/proto/android/hardware/automotive/vehicle/VehiclePropertyStatus.proto
copy to automotive/vehicle/aidl/impl/current/proto/android/hardware/automotive/vehicle/VehiclePropertyStatus.proto
diff --git a/automotive/vehicle/aidl/impl/utils/README.md b/automotive/vehicle/aidl/impl/current/utils/README.md
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/README.md
copy to automotive/vehicle/aidl/impl/current/utils/README.md
diff --git a/automotive/vehicle/aidl/impl/utils/common/Android.bp b/automotive/vehicle/aidl/impl/current/utils/common/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/Android.bp
rename to automotive/vehicle/aidl/impl/current/utils/common/Android.bp
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/ConcurrentQueue.h b/automotive/vehicle/aidl/impl/current/utils/common/include/ConcurrentQueue.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/include/ConcurrentQueue.h
copy to automotive/vehicle/aidl/impl/current/utils/common/include/ConcurrentQueue.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/ParcelableUtils.h b/automotive/vehicle/aidl/impl/current/utils/common/include/ParcelableUtils.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/include/ParcelableUtils.h
copy to automotive/vehicle/aidl/impl/current/utils/common/include/ParcelableUtils.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h b/automotive/vehicle/aidl/impl/current/utils/common/include/PendingRequestPool.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/include/PendingRequestPool.h
copy to automotive/vehicle/aidl/impl/current/utils/common/include/PendingRequestPool.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h b/automotive/vehicle/aidl/impl/current/utils/common/include/PropertyUtils.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
copy to automotive/vehicle/aidl/impl/current/utils/common/include/PropertyUtils.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h b/automotive/vehicle/aidl/impl/current/utils/common/include/RecurrentTimer.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
copy to automotive/vehicle/aidl/impl/current/utils/common/include/RecurrentTimer.h
diff --git a/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleHalTypes.h
new file mode 100644
index 0000000..4fa0a06
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleHalTypes.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
+#define android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
+
+#include <aidl/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.h>
+#include <aidl/android/hardware/automotive/vehicle/BlindSpotWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/CameraServiceState.h>
+#include <aidl/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/CruiseControlCommand.h>
+#include <aidl/android/hardware/automotive/vehicle/CruiseControlState.h>
+#include <aidl/android/hardware/automotive/vehicle/CruiseControlType.h>
+#include <aidl/android/hardware/automotive/vehicle/DiagnosticFloatSensorIndex.h>
+#include <aidl/android/hardware/automotive/vehicle/DiagnosticIntegerSensorIndex.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDistractionState.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDistractionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.h>
+#include <aidl/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/ElectronicStabilityControlState.h>
+#include <aidl/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.h>
+#include <aidl/android/hardware/automotive/vehicle/ErrorState.h>
+#include <aidl/android/hardware/automotive/vehicle/EvConnectorType.h>
+#include <aidl/android/hardware/automotive/vehicle/EvStoppingMode.h>
+#include <aidl/android/hardware/automotive/vehicle/EvsServiceState.h>
+#include <aidl/android/hardware/automotive/vehicle/EvsServiceType.h>
+#include <aidl/android/hardware/automotive/vehicle/ForwardCollisionWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/FuelType.h>
+#include <aidl/android/hardware/automotive/vehicle/GetValueRequest.h>
+#include <aidl/android/hardware/automotive/vehicle/GetValueResult.h>
+#include <aidl/android/hardware/automotive/vehicle/GetValueResults.h>
+#include <aidl/android/hardware/automotive/vehicle/GsrComplianceRequirementType.h>
+#include <aidl/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.h>
+#include <aidl/android/hardware/automotive/vehicle/HandsOnDetectionWarning.h>
+#include <aidl/android/hardware/automotive/vehicle/ImpactSensorLocation.h>
+#include <aidl/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.h>
+#include <aidl/android/hardware/automotive/vehicle/LaneCenteringAssistState.h>
+#include <aidl/android/hardware/automotive/vehicle/LaneDepartureWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/LaneKeepAssistState.h>
+#include <aidl/android/hardware/automotive/vehicle/LocationCharacterization.h>
+#include <aidl/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.h>
+#include <aidl/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.h>
+#include <aidl/android/hardware/automotive/vehicle/Obd2CommonIgnitionMonitors.h>
+#include <aidl/android/hardware/automotive/vehicle/Obd2FuelSystemStatus.h>
+#include <aidl/android/hardware/automotive/vehicle/Obd2FuelType.h>
+#include <aidl/android/hardware/automotive/vehicle/Obd2IgnitionMonitorKind.h>
+#include <aidl/android/hardware/automotive/vehicle/Obd2SecondaryAirStatus.h>
+#include <aidl/android/hardware/automotive/vehicle/Obd2SparkIgnitionMonitors.h>
+#include <aidl/android/hardware/automotive/vehicle/PortLocationType.h>
+#include <aidl/android/hardware/automotive/vehicle/SetValueRequest.h>
+#include <aidl/android/hardware/automotive/vehicle/SetValueResult.h>
+#include <aidl/android/hardware/automotive/vehicle/SetValueResults.h>
+#include <aidl/android/hardware/automotive/vehicle/StatusCode.h>
+#include <aidl/android/hardware/automotive/vehicle/SubscribeOptions.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAirbagLocation.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerBootupReason.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReport.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleArea.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAutonomousState.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleGear.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleHvacFanDirection.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleIgnitionState.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleLightState.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleLightSwitch.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleOilLevel.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropConfig.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropConfigs.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropError.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropValue.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyGroup.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyStatus.h>
+#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyType.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleSizeClass.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleTurnSignal.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleUnit.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleVendorPermission.h>
+#include <aidl/android/hardware/automotive/vehicle/WindshieldWipersState.h>
+#include <aidl/android/hardware/automotive/vehicle/WindshieldWipersSwitch.h>
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_utils_common_include_VehicleHalTypes_H_
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleObjectPool.h
similarity index 98%
copy from automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
copy to automotive/vehicle/aidl/impl/current/utils/common/include/VehicleObjectPool.h
index 501ce40..e18413b 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
+++ b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleObjectPool.h
@@ -50,7 +50,7 @@
 struct Deleter {
     using OnDeleteFunc = std::function<void(T*)>;
 
-    explicit Deleter(const OnDeleteFunc& f) : mOnDelete(f){};
+    explicit Deleter(const OnDeleteFunc& f) : mOnDelete(f) {};
 
     Deleter() = default;
     Deleter(const Deleter&) = default;
@@ -76,7 +76,7 @@
     using GetSizeFunc = std::function<size_t(const T&)>;
 
     ObjectPool(size_t maxPoolObjectsSize, GetSizeFunc getSizeFunc)
-        : mMaxPoolObjectsSize(maxPoolObjectsSize), mGetSizeFunc(getSizeFunc){};
+        : mMaxPoolObjectsSize(maxPoolObjectsSize), mGetSizeFunc(getSizeFunc) {};
     virtual ~ObjectPool() = default;
 
     virtual recyclable_ptr<T> obtain() {
@@ -182,7 +182,7 @@
     // approximately this pool would at-most take 4 * 4 * 10240 = 160k memory.
     VehiclePropValuePool(size_t maxRecyclableVectorSize = 4, size_t maxPoolObjectsSize = 10240)
         : mMaxRecyclableVectorSize(maxRecyclableVectorSize),
-          mMaxPoolObjectsSize(maxPoolObjectsSize){};
+          mMaxPoolObjectsSize(maxPoolObjectsSize) {};
 
     // Obtain a recyclable VehiclePropertyValue object from the pool for the given type. If the
     // given type is not MIXED or STRING, the internal value vector size would be set to 1.
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/current/utils/common/include/VehiclePropertyStore.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
copy to automotive/vehicle/aidl/impl/current/utils/common/include/VehiclePropertyStore.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/current/utils/common/include/VehicleUtils.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
copy to automotive/vehicle/aidl/impl/current/utils/common/include/VehicleUtils.h
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp b/automotive/vehicle/aidl/impl/current/utils/common/src/PendingRequestPool.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/src/PendingRequestPool.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/src/PendingRequestPool.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/current/utils/common/src/RecurrentTimer.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/src/RecurrentTimer.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp b/automotive/vehicle/aidl/impl/current/utils/common/src/VehicleObjectPool.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/src/VehicleObjectPool.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/current/utils/common/src/VehiclePropertyStore.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/src/VehiclePropertyStore.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp b/automotive/vehicle/aidl/impl/current/utils/common/src/VehicleUtils.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/src/VehicleUtils.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/Android.bp b/automotive/vehicle/aidl/impl/current/utils/common/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/common/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/utils/common/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/PendingRequestPoolTest.cpp b/automotive/vehicle/aidl/impl/current/utils/common/test/PendingRequestPoolTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/test/PendingRequestPoolTest.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/test/PendingRequestPoolTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp b/automotive/vehicle/aidl/impl/current/utils/common/test/RecurrentTimerTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/test/RecurrentTimerTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp b/automotive/vehicle/aidl/impl/current/utils/common/test/VehicleObjectPoolTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/test/VehicleObjectPoolTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/current/utils/common/test/VehiclePropertyStoreTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/test/VehiclePropertyStoreTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp b/automotive/vehicle/aidl/impl/current/utils/common/test/VehicleUtilsTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp
copy to automotive/vehicle/aidl/impl/current/utils/common/test/VehicleUtilsTest.cpp
diff --git a/automotive/vehicle/aidl/impl/utils/test_vendor_properties/Android.bp b/automotive/vehicle/aidl/impl/current/utils/test_vendor_properties/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/utils/test_vendor_properties/Android.bp
rename to automotive/vehicle/aidl/impl/current/utils/test_vendor_properties/Android.bp
diff --git a/automotive/vehicle/aidl/impl/utils/test_vendor_properties/android/hardware/automotive/vehicle/TestVendorProperty.aidl b/automotive/vehicle/aidl/impl/current/utils/test_vendor_properties/android/hardware/automotive/vehicle/TestVendorProperty.aidl
similarity index 100%
copy from automotive/vehicle/aidl/impl/utils/test_vendor_properties/android/hardware/automotive/vehicle/TestVendorProperty.aidl
copy to automotive/vehicle/aidl/impl/current/utils/test_vendor_properties/android/hardware/automotive/vehicle/TestVendorProperty.aidl
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/current/vhal/Android.bp
similarity index 97%
rename from automotive/vehicle/aidl/impl/vhal/Android.bp
rename to automotive/vehicle/aidl/impl/current/vhal/Android.bp
index 54d148e..8764eff 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/current/vhal/Android.bp
@@ -20,7 +20,7 @@
 }
 
 cc_binary {
-    name: "android.hardware.automotive.vehicle@V3-default-service",
+    name: "android.hardware.automotive.vehicle@V4-default-service",
     vendor: true,
     defaults: [
         "FakeVehicleHardwareDefaults",
diff --git a/automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h b/automotive/vehicle/aidl/impl/current/vhal/include/ConnectedClient.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/vhal/include/ConnectedClient.h
copy to automotive/vehicle/aidl/impl/current/vhal/include/ConnectedClient.h
diff --git a/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h
new file mode 100644
index 0000000..5d64e6f
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/vhal/include/DefaultVehicleHal.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
+
+#include <ConnectedClient.h>
+#include <ParcelableUtils.h>
+#include <PendingRequestPool.h>
+#include <RecurrentTimer.h>
+#include <SubscriptionManager.h>
+
+#include <ConcurrentQueue.h>
+#include <IVehicleHardware.h>
+#include <VehicleUtils.h>
+#include <aidl/android/hardware/automotive/vehicle/BnVehicle.h>
+#include <android-base/expected.h>
+#include <android-base/thread_annotations.h>
+#include <android/binder_auto_utils.h>
+
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <shared_mutex>
+#include <unordered_map>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
+class DefaultVehicleHal final : public aidlvhal::BnVehicle {
+  public:
+    using CallbackType = std::shared_ptr<aidlvhal::IVehicleCallback>;
+
+    explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
+
+    // Test-only
+    DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware, int32_t testInterfaceVersion);
+
+    ~DefaultVehicleHal();
+
+    ndk::ScopedAStatus getAllPropConfigs(aidlvhal::VehiclePropConfigs* returnConfigs) override;
+    ndk::ScopedAStatus getValues(const CallbackType& callback,
+                                 const aidlvhal::GetValueRequests& requests) override;
+    ndk::ScopedAStatus setValues(const CallbackType& callback,
+                                 const aidlvhal::SetValueRequests& requests) override;
+    ndk::ScopedAStatus getPropConfigs(const std::vector<int32_t>& props,
+                                      aidlvhal::VehiclePropConfigs* returnConfigs) override;
+    ndk::ScopedAStatus subscribe(const CallbackType& callback,
+                                 const std::vector<aidlvhal::SubscribeOptions>& options,
+                                 int32_t maxSharedMemoryFileCount) override;
+    ndk::ScopedAStatus unsubscribe(const CallbackType& callback,
+                                   const std::vector<int32_t>& propIds) override;
+    ndk::ScopedAStatus returnSharedMemory(const CallbackType& callback,
+                                          int64_t sharedMemoryId) override;
+    ndk::ScopedAStatus getSupportedValuesLists(
+            const std::vector<aidlvhal::PropIdAreaId>& propIdAreaIds,
+            aidlvhal::SupportedValuesListResults* supportedValuesListResults) override;
+    ndk::ScopedAStatus getMinMaxSupportedValue(
+            const std::vector<aidlvhal::PropIdAreaId>& propIdAreaIds,
+            aidlvhal::MinMaxSupportedValueResults* minMaxSupportedValueResults) override;
+    ndk::ScopedAStatus registerSupportedValueChangeCallback(
+            const std::shared_ptr<aidlvhal::IVehicleCallback>& callback,
+            const std::vector<aidlvhal::PropIdAreaId>& propIdAreaIds) override;
+    ndk::ScopedAStatus unregisterSupportedValueChangeCallback(
+            const std::shared_ptr<aidlvhal::IVehicleCallback>& callback,
+            const std::vector<aidlvhal::PropIdAreaId>& propIdAreaIds) override;
+    binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
+
+    IVehicleHardware* getHardware();
+
+  private:
+    // friend class for unit testing.
+    friend class DefaultVehicleHalTest;
+
+    using GetValuesClient = GetSetValuesClient<aidlvhal::GetValueResult, aidlvhal::GetValueResults>;
+    using SetValuesClient = GetSetValuesClient<aidlvhal::SetValueResult, aidlvhal::SetValueResults>;
+
+    // A wrapper for binder lifecycle operations to enable stubbing for test.
+    class BinderLifecycleInterface {
+      public:
+        virtual ~BinderLifecycleInterface() = default;
+
+        virtual binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
+                                            void* cookie) = 0;
+
+        virtual bool isAlive(const AIBinder* binder) = 0;
+    };
+
+    // A real implementation for BinderLifecycleInterface.
+    class BinderLifecycleHandler final : public BinderLifecycleInterface {
+      public:
+        binder_status_t linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient,
+                                    void* cookie) override;
+
+        bool isAlive(const AIBinder* binder) override;
+    };
+
+    // OnBinderDiedContext is a type used as a cookie passed deathRecipient. The deathRecipient's
+    // onBinderDied function takes only a cookie as input and we have to store all the contexts
+    // as the cookie.
+    struct OnBinderDiedContext {
+        DefaultVehicleHal* vhal;
+        const AIBinder* clientId;
+    };
+
+    // BinderDiedUnlinkedEvent represents either an onBinderDied or an onBinderUnlinked event.
+    struct BinderDiedUnlinkedEvent {
+        // true for onBinderDied, false for onBinderUnlinked.
+        bool forOnBinderDied;
+        const AIBinder* clientId;
+    };
+
+    // The default timeout of get or set value requests is 30s.
+    // TODO(b/214605968): define TIMEOUT_IN_NANO in IVehicle and allow getValues/setValues/subscribe
+    // to specify custom timeouts.
+    static constexpr int64_t TIMEOUT_IN_NANO = 30'000'000'000;
+    // heart beat event interval: 3s
+    static constexpr int64_t HEART_BEAT_INTERVAL_IN_NANO = 3'000'000'000;
+    bool mShouldRefreshPropertyConfigs;
+    std::unique_ptr<IVehicleHardware> mVehicleHardware;
+
+    // PendingRequestPool is thread-safe.
+    std::shared_ptr<PendingRequestPool> mPendingRequestPool;
+    // SubscriptionManager is thread-safe.
+    std::shared_ptr<SubscriptionManager> mSubscriptionManager;
+    // ConcurrentQueue is thread-safe.
+    std::shared_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>> mBatchedEventQueue;
+    // BatchingConsumer is thread-safe.
+    std::shared_ptr<BatchingConsumer<aidlvhal::VehiclePropValue>>
+            mPropertyChangeEventsBatchingConsumer;
+    // Only set once during initialization.
+    std::chrono::nanoseconds mEventBatchingWindow;
+    // Only used for testing.
+    int32_t mTestInterfaceVersion = 0;
+
+    mutable std::atomic<bool> mConfigInit = false;
+    mutable std::shared_timed_mutex mConfigLock;
+    mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId
+            GUARDED_BY(mConfigLock);
+    mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigLock);
+
+    std::mutex mLock;
+    std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
+            GUARDED_BY(mLock);
+    std::unordered_map<const AIBinder*, std::shared_ptr<GetValuesClient>> mGetValuesClients
+            GUARDED_BY(mLock);
+    std::unordered_map<const AIBinder*, std::shared_ptr<SetValuesClient>> mSetValuesClients
+            GUARDED_BY(mLock);
+    // mBinderLifecycleHandler is only going to be changed in test.
+    std::unique_ptr<BinderLifecycleInterface> mBinderLifecycleHandler;
+
+    // Only initialized once.
+    std::shared_ptr<std::function<void()>> mRecurrentAction;
+    // RecurrentTimer is thread-safe.
+    RecurrentTimer mRecurrentTimer;
+
+    ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
+
+    // ConcurrentQueue is thread-safe.
+    ConcurrentQueue<BinderDiedUnlinkedEvent> mBinderEvents;
+
+    // A thread to handle onBinderDied or onBinderUnlinked event.
+    std::thread mOnBinderDiedUnlinkedHandlerThread;
+
+    android::base::Result<void> checkProperty(const aidlvhal::VehiclePropValue& propValue);
+
+    android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
+            const std::vector<aidlvhal::GetValueRequest>& requests);
+
+    android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
+            const std::vector<aidlvhal::SetValueRequest>& requests);
+    VhalResult<void> checkSubscribeOptions(
+            const std::vector<aidlvhal::SubscribeOptions>& options,
+            const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId)
+            REQUIRES_SHARED(mConfigLock);
+
+    VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value,
+                                           aidlvhal::VehiclePropertyAccess accessToTest) const;
+
+    VhalResult<void> checkReadPermission(const aidlvhal::VehiclePropValue& value) const;
+
+    VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const;
+
+    android::base::Result<aidlvhal::VehiclePropConfig> getConfig(int32_t propId) const;
+
+    void onBinderDiedWithContext(const AIBinder* clientId);
+
+    void onBinderUnlinkedWithContext(const AIBinder* clientId);
+
+    // Registers a onBinderDied callback for the client if not already registered.
+    // Returns true if the client Binder is alive, false otherwise.
+    bool monitorBinderLifeCycleLocked(const AIBinder* clientId) REQUIRES(mLock);
+
+    bool checkDumpPermission();
+
+    bool isConfigSupportedForCurrentVhalVersion(const aidlvhal::VehiclePropConfig& config) const;
+
+    bool getAllPropConfigsFromHardwareLocked() const EXCLUDES(mConfigLock);
+
+    // The looping handler function to process all onBinderDied or onBinderUnlinked events in
+    // mBinderEvents.
+    void onBinderDiedUnlinkedHandler();
+
+    size_t countSubscribeClients();
+
+    // Handles the property change events in batch.
+    void handleBatchedPropertyEvents(std::vector<aidlvhal::VehiclePropValue>&& batchedEvents);
+
+    int32_t getVhalInterfaceVersion() const;
+
+    // Gets mConfigsByPropId, lazy init it if necessary. Note that the reference is only valid in
+    // the scope of the callback and it is guaranteed that read lock is obtained during the
+    // callback.
+    void getConfigsByPropId(
+            std::function<void(const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>&)>
+                    callback) const EXCLUDES(mConfigLock);
+
+    // Puts the property change events into a queue so that they can handled in batch.
+    static void batchPropertyChangeEvent(
+            const std::weak_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>>& batchedEventQueue,
+            std::vector<aidlvhal::VehiclePropValue>&& updatedValues);
+
+    // Gets or creates a {@code T} object for the client to or from {@code clients}.
+    template <class T>
+    static std::shared_ptr<T> getOrCreateClient(
+            std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
+            const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool);
+
+    static void onPropertyChangeEvent(const std::weak_ptr<SubscriptionManager>& subscriptionManager,
+                                      std::vector<aidlvhal::VehiclePropValue>&& updatedValues);
+
+    static void onPropertySetErrorEvent(
+            const std::weak_ptr<SubscriptionManager>& subscriptionManager,
+            const std::vector<SetValueErrorEvent>& errorEvents);
+
+    static void checkHealth(IVehicleHardware* hardware,
+                            std::weak_ptr<SubscriptionManager> subscriptionManager);
+
+    static void onBinderDied(void* cookie);
+
+    static void onBinderUnlinked(void* cookie);
+
+    static void parseSubscribeOptions(
+            const std::vector<aidlvhal::SubscribeOptions>& options,
+            const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& configsByPropId,
+            std::vector<aidlvhal::SubscribeOptions>& onChangeSubscriptions,
+            std::vector<aidlvhal::SubscribeOptions>& continuousSubscriptions);
+
+    // Test-only
+    // Set the default timeout for pending requests.
+    void setTimeout(int64_t timeoutInNano);
+
+    // Test-only
+    void setBinderLifecycleHandler(std::unique_ptr<BinderLifecycleInterface> impl);
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_include_DefaultVehicleHal_H_
diff --git a/automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h b/automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/vhal/include/SubscriptionManager.h
copy to automotive/vehicle/aidl/impl/current/vhal/include/SubscriptionManager.h
diff --git a/automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/ConnectedClient.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/vhal/src/ConnectedClient.cpp
copy to automotive/vehicle/aidl/impl/current/vhal/src/ConnectedClient.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
similarity index 96%
copy from automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
copy to automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
index 0ead819..1e55a1a 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/src/DefaultVehicleHal.cpp
@@ -49,12 +49,15 @@
 using ::aidl::android::hardware::automotive::vehicle::GetValueRequests;
 using ::aidl::android::hardware::automotive::vehicle::GetValueResult;
 using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::MinMaxSupportedValueResults;
 using ::aidl::android::hardware::automotive::vehicle::SetValueRequest;
 using ::aidl::android::hardware::automotive::vehicle::SetValueRequests;
 using ::aidl::android::hardware::automotive::vehicle::SetValueResult;
 using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
 using ::aidl::android::hardware::automotive::vehicle::StatusCode;
 using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::SupportedValuesListResults;
 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfigs;
@@ -110,7 +113,7 @@
 }  // namespace
 
 DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
-    : DefaultVehicleHal(std::move(vehicleHardware), /* testInterfaceVersion= */ 0){};
+    : DefaultVehicleHal(std::move(vehicleHardware), /* testInterfaceVersion= */ 0) {};
 
 DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware,
                                      int32_t testInterfaceVersion)
@@ -961,6 +964,34 @@
     return ScopedAStatus::ok();
 }
 
+ScopedAStatus DefaultVehicleHal::getSupportedValuesLists(
+        const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&,
+        SupportedValuesListResults*) {
+    // TODO(b/381020465): Add relevant implementation.
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus DefaultVehicleHal::getMinMaxSupportedValue(
+        const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&,
+        MinMaxSupportedValueResults*) {
+    // TODO(b/381020465): Add relevant implementation.
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus DefaultVehicleHal::registerSupportedValueChangeCallback(
+        const std::shared_ptr<IVehicleCallback>&,
+        const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&) {
+    // TODO(b/381020465): Add relevant implementation.
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ScopedAStatus DefaultVehicleHal::unregisterSupportedValueChangeCallback(
+        const std::shared_ptr<IVehicleCallback>&,
+        const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&) {
+    // TODO(b/381020465): Add relevant implementation.
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
 IVehicleHardware* DefaultVehicleHal::getHardware() {
     return mVehicleHardware.get();
 }
diff --git a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
copy to automotive/vehicle/aidl/impl/current/vhal/src/SubscriptionManager.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/VehicleService.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/vhal/src/VehicleService.cpp
copy to automotive/vehicle/aidl/impl/current/vhal/src/VehicleService.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp b/automotive/vehicle/aidl/impl/current/vhal/src/fuzzer.cpp
similarity index 93%
copy from automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp
copy to automotive/vehicle/aidl/impl/current/vhal/src/fuzzer.cpp
index 6d994bb..ac1e3b1 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/fuzzer.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/src/fuzzer.cpp
@@ -25,8 +25,6 @@
 using ::ndk::SharedRefBase;
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    // TODO(b/183141167): need to rewrite 'dump' to avoid SIGPIPE.
-    signal(SIGPIPE, SIG_IGN);
     std::unique_ptr<FakeVehicleHardware> hardware = std::make_unique<FakeVehicleHardware>();
     std::shared_ptr<DefaultVehicleHal> vhal =
             ::ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware));
diff --git a/automotive/vehicle/aidl/impl/vhal/test/Android.bp b/automotive/vehicle/aidl/impl/current/vhal/test/Android.bp
similarity index 100%
rename from automotive/vehicle/aidl/impl/vhal/test/Android.bp
rename to automotive/vehicle/aidl/impl/current/vhal/test/Android.bp
diff --git a/automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/ConnectedClientTest.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/vhal/test/ConnectedClientTest.cpp
copy to automotive/vehicle/aidl/impl/current/vhal/test/ConnectedClientTest.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
similarity index 99%
copy from automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
copy to automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
index 4891bf5..ad34a4c 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/DefaultVehicleHalTest.cpp
@@ -1849,6 +1849,12 @@
     std::this_thread::sleep_for(std::chrono::seconds(3));
 
     auto maybeResults = getCallback()->nextOnPropertyEventResults();
+    size_t retryCount = 0;
+    // Add a 1s (100ms * 10) buffer time.
+    while (!maybeResults.has_value() && retryCount < 10) {
+        retryCount++;
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    }
     ASSERT_TRUE(maybeResults.has_value()) << "no results in callback";
     ASSERT_EQ(maybeResults.value().payloads.size(), static_cast<size_t>(1));
     VehiclePropValue gotValue = maybeResults.value().payloads[0];
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleCallback.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleCallback.cpp
new file mode 100644
index 0000000..72c5dc5
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleCallback.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MockVehicleCallback.h"
+
+#include <android-base/thread_annotations.h>
+#include <chrono>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+namespace {
+
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::PropIdAreaId;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
+using ::android::base::ScopedLockAssertion;
+using ::ndk::ScopedAStatus;
+using ::ndk::ScopedFileDescriptor;
+
+template <class T>
+static ScopedAStatus storeResults(const T& results, std::list<T>* storedResults) {
+    T resultsCopy{
+            .payloads = results.payloads,
+    };
+    int fd = results.sharedMemoryFd.get();
+    if (fd != -1) {
+        resultsCopy.sharedMemoryFd = ScopedFileDescriptor(dup(fd));
+    }
+    storedResults->push_back(std::move(resultsCopy));
+    return ScopedAStatus::ok();
+}
+
+}  // namespace
+
+ScopedAStatus MockVehicleCallback::onGetValues(const GetValueResults& results) {
+    ScopedAStatus result;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        result = storeResults(results, &mGetValueResults);
+    }
+    mCond.notify_all();
+    return result;
+}
+
+ScopedAStatus MockVehicleCallback::onSetValues(const SetValueResults& results) {
+    ScopedAStatus result;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        result = storeResults(results, &mSetValueResults);
+    }
+    mCond.notify_all();
+    return result;
+}
+
+ScopedAStatus MockVehicleCallback::onPropertyEvent(const VehiclePropValues& results,
+                                                   int32_t sharedMemoryFileCount) {
+    ScopedAStatus result;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        mSharedMemoryFileCount = sharedMemoryFileCount;
+        result = storeResults(results, &mOnPropertyEventResults);
+    }
+    mCond.notify_all();
+    return result;
+}
+
+ScopedAStatus MockVehicleCallback::onPropertySetError(const VehiclePropErrors& results) {
+    ScopedAStatus result;
+    {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        result = storeResults(results, &mOnPropertySetErrorResults);
+    }
+    mCond.notify_all();
+    return result;
+}
+
+ScopedAStatus MockVehicleCallback::onSupportedValueChange(const std::vector<PropIdAreaId>&) {
+    // TODO(b/381020465): Add relevant implementation.
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+std::optional<GetValueResults> MockVehicleCallback::nextGetValueResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return pop(mGetValueResults);
+}
+
+std::optional<SetValueResults> MockVehicleCallback::nextSetValueResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return pop(mSetValueResults);
+}
+
+std::optional<VehiclePropValues> MockVehicleCallback::nextOnPropertyEventResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return pop(mOnPropertyEventResults);
+}
+
+size_t MockVehicleCallback::countOnPropertyEventResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return mOnPropertyEventResults.size();
+}
+
+std::optional<VehiclePropErrors> MockVehicleCallback::nextOnPropertySetErrorResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return pop(mOnPropertySetErrorResults);
+}
+
+size_t MockVehicleCallback::countOnPropertySetErrorResults() {
+    std::scoped_lock<std::mutex> lockGuard(mLock);
+    return mOnPropertySetErrorResults.size();
+}
+
+bool MockVehicleCallback::waitForSetValueResults(size_t size, size_t timeoutInNano) {
+    std::unique_lock lk(mLock);
+    return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
+        ScopedLockAssertion lockAssertion(mLock);
+        return mSetValueResults.size() >= size;
+    });
+}
+
+bool MockVehicleCallback::waitForGetValueResults(size_t size, size_t timeoutInNano) {
+    std::unique_lock lk(mLock);
+    return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
+        ScopedLockAssertion lockAssertion(mLock);
+        return mGetValueResults.size() >= size;
+    });
+}
+
+bool MockVehicleCallback::waitForOnPropertyEventResults(size_t size, size_t timeoutInNano) {
+    std::unique_lock lk(mLock);
+    return mCond.wait_for(lk, std::chrono::nanoseconds(timeoutInNano), [this, size] {
+        ScopedLockAssertion lockAssertion(mLock);
+        return mOnPropertyEventResults.size() >= size;
+    });
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleCallback.h b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleCallback.h
new file mode 100644
index 0000000..81a85ff
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleCallback.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
+#define android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
+
+#include <VehicleHalTypes.h>
+
+#include <aidl/android/hardware/automotive/vehicle/BnVehicleCallback.h>
+#include <android-base/thread_annotations.h>
+
+#include <condition_variable>
+#include <list>
+#include <mutex>
+#include <optional>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+template <class T>
+std::optional<T> pop(std::list<T>& items) {
+    if (items.size() > 0) {
+        auto item = std::move(items.front());
+        items.pop_front();
+        return item;
+    }
+    return std::nullopt;
+}
+
+// MockVehicleCallback is a mock VehicleCallback implementation that simply stores the results.
+class MockVehicleCallback final
+    : public aidl::android::hardware::automotive::vehicle::BnVehicleCallback {
+  public:
+    ndk::ScopedAStatus onGetValues(
+            const aidl::android::hardware::automotive::vehicle::GetValueResults& results) override;
+    ndk::ScopedAStatus onSetValues(
+            const aidl::android::hardware::automotive::vehicle::SetValueResults& results) override;
+    ndk::ScopedAStatus onPropertyEvent(
+            const aidl::android::hardware::automotive::vehicle::VehiclePropValues&,
+            int32_t) override;
+    ndk::ScopedAStatus onPropertySetError(
+            const aidl::android::hardware::automotive::vehicle::VehiclePropErrors&) override;
+    ndk::ScopedAStatus onSupportedValueChange(
+            const std::vector<aidl::android::hardware::automotive::vehicle::PropIdAreaId>&)
+            override;
+
+    // Test functions
+    std::optional<aidl::android::hardware::automotive::vehicle::GetValueResults>
+    nextGetValueResults();
+    std::optional<aidl::android::hardware::automotive::vehicle::SetValueResults>
+    nextSetValueResults();
+    std::optional<aidl::android::hardware::automotive::vehicle::VehiclePropValues>
+    nextOnPropertyEventResults();
+    size_t countOnPropertySetErrorResults();
+    std::optional<aidl::android::hardware::automotive::vehicle::VehiclePropErrors>
+    nextOnPropertySetErrorResults();
+    size_t countOnPropertyEventResults();
+    bool waitForSetValueResults(size_t size, size_t timeoutInNano);
+    bool waitForGetValueResults(size_t size, size_t timeoutInNano);
+    bool waitForOnPropertyEventResults(size_t size, size_t timeoutInNano);
+
+  private:
+    std::mutex mLock;
+    std::condition_variable mCond;
+    std::list<aidl::android::hardware::automotive::vehicle::GetValueResults> mGetValueResults
+            GUARDED_BY(mLock);
+    std::list<aidl::android::hardware::automotive::vehicle::SetValueResults> mSetValueResults
+            GUARDED_BY(mLock);
+    std::list<aidl::android::hardware::automotive::vehicle::VehiclePropValues>
+            mOnPropertyEventResults GUARDED_BY(mLock);
+    int32_t mSharedMemoryFileCount GUARDED_BY(mLock);
+    std::list<aidl::android::hardware::automotive::vehicle::VehiclePropErrors>
+            mOnPropertySetErrorResults GUARDED_BY(mLock);
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+
+#endif  // android_hardware_automotive_vehicle_aidl_impl_vhal_test_MockVehicleCallback_H_
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.cpp
similarity index 100%
copy from automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.cpp
copy to automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.cpp
diff --git a/automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h b/automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.h
similarity index 100%
copy from automotive/vehicle/aidl/impl/vhal/test/MockVehicleHardware.h
copy to automotive/vehicle/aidl/impl/current/vhal/test/MockVehicleHardware.h
diff --git a/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp b/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp
new file mode 100644
index 0000000..5d58de5
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/vhal/test/SubscriptionManagerTest.cpp
@@ -0,0 +1,889 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SubscriptionManager.h"
+
+#include <MockVehicleHardware.h>
+#include <VehicleHalTypes.h>
+
+#include <aidl/android/hardware/automotive/vehicle/BnVehicleCallback.h>
+#include <android-base/thread_annotations.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <float.h>
+#include <chrono>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+using ::aidl::android::hardware::automotive::vehicle::BnVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::GetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::IVehicleCallback;
+using ::aidl::android::hardware::automotive::vehicle::SetValueResults;
+using ::aidl::android::hardware::automotive::vehicle::SubscribeOptions;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropErrors;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VehiclePropValues;
+using ::ndk::ScopedAStatus;
+using ::ndk::SpAIBinder;
+using ::testing::Contains;
+using ::testing::ElementsAre;
+using ::testing::UnorderedElementsAre;
+
+class PropertyCallback final : public BnVehicleCallback {
+  public:
+    ScopedAStatus onGetValues(const GetValueResults&) override { return ScopedAStatus::ok(); }
+
+    ScopedAStatus onSetValues(const SetValueResults&) override { return ScopedAStatus::ok(); }
+
+    ScopedAStatus onPropertyEvent(const VehiclePropValues& values, int32_t) override {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        for (const auto& value : values.payloads) {
+            mEvents.push_back(value);
+        }
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onPropertySetError(const VehiclePropErrors&) override {
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onSupportedValueChange(
+            const std::vector<::aidl::android::hardware::automotive::vehicle::PropIdAreaId>&)
+            override {
+        return ScopedAStatus::ok();
+    }
+
+    // Test functions.
+    std::list<VehiclePropValue> getEvents() {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        return mEvents;
+    }
+
+    void clearEvents() {
+        std::scoped_lock<std::mutex> lockGuard(mLock);
+        mEvents.clear();
+    }
+
+  private:
+    std::mutex mLock;
+    std::list<VehiclePropValue> mEvents GUARDED_BY(mLock);
+};
+
+class SubscriptionManagerTest : public testing::Test {
+  public:
+    void SetUp() override {
+        mHardware = std::make_shared<MockVehicleHardware>();
+        mManager = std::make_unique<SubscriptionManager>(mHardware.get());
+        mCallback = ndk::SharedRefBase::make<PropertyCallback>();
+        // Keep the local binder alive.
+        mBinder = mCallback->asBinder();
+        mCallbackClient = IVehicleCallback::fromBinder(mBinder);
+        std::shared_ptr<IVehicleCallback> callbackClient = mCallbackClient;
+        mHardware->registerOnPropertyChangeEvent(
+                std::make_unique<IVehicleHardware::PropertyChangeCallback>(
+                        [callbackClient](std::vector<VehiclePropValue> updatedValues) {
+                            VehiclePropValues values = {
+                                    .payloads = std::move(updatedValues),
+                            };
+                            callbackClient->onPropertyEvent(values, 0);
+                        }));
+    }
+
+    SubscriptionManager* getManager() { return mManager.get(); }
+
+    std::shared_ptr<IVehicleCallback> getCallbackClient() { return mCallbackClient; }
+
+    PropertyCallback* getCallback() { return mCallback.get(); }
+
+    std::list<VehiclePropValue> getEvents() { return getCallback()->getEvents(); }
+
+    void clearEvents() { return getCallback()->clearEvents(); }
+
+    std::shared_ptr<MockVehicleHardware> getHardware() { return mHardware; }
+
+  private:
+    std::unique_ptr<SubscriptionManager> mManager;
+    std::shared_ptr<PropertyCallback> mCallback;
+    std::shared_ptr<IVehicleCallback> mCallbackClient;
+    std::shared_ptr<MockVehicleHardware> mHardware;
+    SpAIBinder mBinder;
+};
+
+TEST_F(SubscriptionManagerTest, testSubscribeGlobalContinuous) {
+    std::vector<SubscribeOptions> options = {{
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 10.0,
+    }};
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribedContinuousPropIdAreaIds(),
+                UnorderedElementsAre(std::pair<int32_t, int32_t>(0, 0)));
+
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+
+    // Theoretically trigger 10 times, but check for at least 9 times to be stable.
+    ASSERT_GE(getEvents().size(), static_cast<size_t>(9));
+    EXPECT_EQ(getEvents().back().prop, 0);
+    EXPECT_EQ(getEvents().back().areaId, 0);
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribeMultiplePropsGlobalContinuous) {
+    std::vector<SubscribeOptions> options = {{
+                                                     .propId = 0,
+                                                     .areaIds = {0},
+                                                     .sampleRate = 10.0,
+                                             },
+                                             {
+                                                     .propId = 1,
+                                                     .areaIds = {0},
+                                                     .sampleRate = 20.0,
+                                             }};
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+
+    size_t event0Count = 0;
+    size_t event1Count = 0;
+
+    for (const auto& event : getEvents()) {
+        if (event.prop == 0) {
+            event0Count++;
+        } else {
+            event1Count++;
+        }
+    }
+
+    // Theoretically trigger 10 times, but check for at least 9 times to be stable.
+    EXPECT_GE(event0Count, static_cast<size_t>(9));
+    // Theoretically trigger 20 times, but check for at least 15 times to be stable.
+    EXPECT_GE(event1Count, static_cast<size_t>(15));
+}
+
+TEST_F(SubscriptionManagerTest, testOverrideSubscriptionContinuous) {
+    std::vector<SubscribeOptions> options = {{
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 20.0,
+    }};
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    // Override sample rate to be 10.0.
+    options[0].sampleRate = 10.0;
+    result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+
+    // Theoretically trigger 10 times, but check for at least 9 times to be stable.
+    EXPECT_GE(getEvents().size(), static_cast<size_t>(9));
+    EXPECT_LE(getEvents().size(), static_cast<size_t>(15));
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribeMultipleAreasContinuous) {
+    std::vector<SubscribeOptions> options = {
+            {
+                    .propId = 0,
+                    .areaIds = {0, 1},
+                    .sampleRate = 10.0,
+            },
+    };
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+
+    size_t area0Count = 0;
+    size_t area1Count = 0;
+
+    for (const auto& event : getEvents()) {
+        if (event.areaId == 0) {
+            area0Count++;
+        } else {
+            area1Count++;
+        }
+    }
+
+    // Theoretically trigger 10 times, but check for at least 9 times to be stable.
+    EXPECT_GE(area0Count, static_cast<size_t>(9));
+    // Theoretically trigger 10 times, but check for at least 9 times to be stable.
+    EXPECT_GE(area1Count, static_cast<size_t>(9));
+}
+
+TEST_F(SubscriptionManagerTest, testUnsubscribeGlobalContinuous) {
+    std::vector<SubscribeOptions> options = {{
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 100.0,
+    }};
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    result = getManager()->unsubscribe(getCallbackClient()->asBinder().get());
+    ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
+
+    ASSERT_EQ(getHardware()->getSubscribedContinuousPropIdAreaIds().size(), 0u);
+
+    // Wait for the last events to come.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    clearEvents();
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    ASSERT_TRUE(getEvents().empty());
+}
+
+TEST_F(SubscriptionManagerTest, testUnsubscribeMultipleAreas) {
+    std::vector<SubscribeOptions> options = {
+            {
+                    .propId = 0,
+                    .areaIds = {0, 1, 2, 3, 4},
+                    .sampleRate = 10.0,
+            },
+            {
+                    .propId = 1,
+                    .areaIds = {0},
+                    .sampleRate = 10.0,
+            },
+    };
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    result = getManager()->unsubscribe(getCallbackClient()->asBinder().get(),
+                                       std::vector<int32_t>({0}));
+    ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
+
+    // Wait for the last events to come.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    clearEvents();
+
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+
+    // Theoretically trigger 10 times, but check for at least 9 times to be stable.
+    EXPECT_GE(getEvents().size(), static_cast<size_t>(9));
+
+    for (const auto& event : getEvents()) {
+        EXPECT_EQ(event.prop, 1);
+    }
+}
+
+TEST_F(SubscriptionManagerTest, testUnsubscribeByCallback) {
+    std::vector<SubscribeOptions> options = {
+            {
+                    .propId = 0,
+                    .areaIds = {0, 1, 2, 3, 4},
+                    .sampleRate = 10.0,
+            },
+            {
+                    .propId = 1,
+                    .areaIds = {0},
+                    .sampleRate = 10.0,
+            },
+    };
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    result = getManager()->unsubscribe(getCallbackClient()->asBinder().get());
+    ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
+
+    // Wait for the last events to come.
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+    clearEvents();
+
+    std::this_thread::sleep_for(std::chrono::seconds(1));
+
+    EXPECT_TRUE(getEvents().empty());
+}
+
+TEST_F(SubscriptionManagerTest, testUnsubscribeUnsubscribedPropId) {
+    std::vector<SubscribeOptions> options = {
+            {
+                    .propId = 0,
+                    .areaIds = {0, 1, 2, 3, 4},
+            },
+            {
+                    .propId = 1,
+                    .areaIds = {0},
+            },
+    };
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, false);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    // Property ID: 2 was not subscribed.
+    result = getManager()->unsubscribe(getCallbackClient()->asBinder().get(),
+                                       std::vector<int32_t>({0, 1, 2}));
+    ASSERT_TRUE(result.ok()) << "unsubscribe an unsubscribed property must do nothing";
+
+    std::vector<VehiclePropValue> updatedValues = {
+            {
+                    .prop = 0,
+                    .areaId = 0,
+            },
+            {
+                    .prop = 1,
+                    .areaId = 0,
+            },
+    };
+    auto clients = getManager()->getSubscribedClients(std::vector<VehiclePropValue>(updatedValues));
+
+    ASSERT_EQ(clients.size(), 0u) << "all subscribed properties must be unsubscribed";
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribeOnchange) {
+    std::vector<SubscribeOptions> options1 = {
+            {
+                    .propId = 0,
+                    .areaIds = {0, 1},
+            },
+            {
+                    .propId = 1,
+                    .areaIds = {0},
+            },
+    };
+    std::vector<SubscribeOptions> options2 = {
+            {
+                    .propId = 0,
+                    .areaIds = {0},
+            },
+    };
+
+    SpAIBinder binder1 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client1 = IVehicleCallback::fromBinder(binder1);
+    SpAIBinder binder2 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client2 = IVehicleCallback::fromBinder(binder2);
+    auto result = getManager()->subscribe(client1, options1, false);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+    result = getManager()->subscribe(client2, options2, false);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+    ASSERT_THAT(getHardware()->getSubscribedOnChangePropIdAreaIds(),
+                UnorderedElementsAre(std::pair<int32_t, int32_t>(0, 0),
+                                     std::pair<int32_t, int32_t>(0, 1),
+                                     std::pair<int32_t, int32_t>(1, 0)));
+    ASSERT_EQ(getHardware()->getSubscribedContinuousPropIdAreaIds().size(), 0u);
+
+    std::vector<VehiclePropValue> updatedValues = {
+            {
+                    .prop = 0,
+                    .areaId = 0,
+            },
+            {
+                    .prop = 0,
+                    .areaId = 1,
+            },
+            {
+                    .prop = 1,
+                    .areaId = 0,
+            },
+            {
+                    .prop = 1,
+                    .areaId = 1,
+            },
+    };
+    auto clients = getManager()->getSubscribedClients(std::vector<VehiclePropValue>(updatedValues));
+
+    ASSERT_THAT(clients[client1],
+                UnorderedElementsAre(updatedValues[0], updatedValues[1], updatedValues[2]));
+    ASSERT_THAT(clients[client2], ElementsAre(updatedValues[0]));
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribeInvalidOption) {
+    std::vector<SubscribeOptions> options = {
+            {
+                    .propId = 0,
+                    .areaIds = {0, 1, 2, 3, 4},
+                    // invalid sample rate.
+                    .sampleRate = 0.0,
+            },
+            {
+                    .propId = 1,
+                    .areaIds = {0},
+                    .sampleRate = 10.0,
+            },
+    };
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_FALSE(result.ok()) << "subscribe with invalid sample rate must fail";
+    ASSERT_TRUE(getManager()
+                        ->getSubscribedClients({{
+                                                        .prop = 0,
+                                                        .areaId = 0,
+                                                },
+                                                {
+                                                        .prop = 1,
+                                                        .areaId = 0,
+                                                }})
+                        .empty())
+            << "no property should be subscribed if error is returned";
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribeNoAreaIds) {
+    std::vector<SubscribeOptions> options = {
+            {
+                    .propId = 0,
+                    .areaIds = {},
+                    .sampleRate = 1.0,
+            },
+            {
+                    .propId = 1,
+                    .areaIds = {0},
+                    .sampleRate = 10.0,
+            },
+    };
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_FALSE(result.ok()) << "subscribe with invalid sample rate must fail";
+    ASSERT_TRUE(getManager()
+                        ->getSubscribedClients({{
+                                .prop = 1,
+                                .areaId = 0,
+                        }})
+                        .empty())
+            << "no property should be subscribed if error is returned";
+}
+
+TEST_F(SubscriptionManagerTest, testUnsubscribeOnchange) {
+    std::vector<SubscribeOptions> options = {
+            {
+                    .propId = 0,
+                    .areaIds = {0, 1},
+            },
+            {
+                    .propId = 1,
+                    .areaIds = {0},
+            },
+    };
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, false);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    result = getManager()->unsubscribe(getCallbackClient()->asBinder().get(),
+                                       std::vector<int32_t>({0}));
+    ASSERT_TRUE(result.ok()) << "failed to unsubscribe: " << result.error().message();
+
+    std::vector<VehiclePropValue> updatedValues = {
+            {
+                    .prop = 0,
+                    .areaId = 0,
+            },
+            {
+                    .prop = 1,
+                    .areaId = 0,
+            },
+    };
+    auto clients = getManager()->getSubscribedClients(std::vector<VehiclePropValue>(updatedValues));
+
+    ASSERT_THAT(clients[getCallbackClient()], ElementsAre(updatedValues[1]));
+    ASSERT_THAT(getHardware()->getSubscribedOnChangePropIdAreaIds(),
+                UnorderedElementsAre(std::pair<int32_t, int32_t>(1, 0)));
+}
+
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzValid) {
+    ASSERT_TRUE(SubscriptionManager::checkSampleRateHz(1.0));
+}
+
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzInvalidTooSmall) {
+    ASSERT_FALSE(SubscriptionManager::checkSampleRateHz(FLT_MIN));
+}
+
+TEST_F(SubscriptionManagerTest, testCheckSampleRateHzInvalidZero) {
+    ASSERT_FALSE(SubscriptionManager::checkSampleRateHz(0));
+}
+
+TEST_F(SubscriptionManagerTest, testCheckResolutionValid) {
+    ASSERT_TRUE(SubscriptionManager::checkResolution(0.0));
+    ASSERT_TRUE(SubscriptionManager::checkResolution(0.1));
+    ASSERT_TRUE(SubscriptionManager::checkResolution(1.0));
+}
+
+TEST_F(SubscriptionManagerTest, testCheckResolutionInvalid) {
+    ASSERT_FALSE(SubscriptionManager::checkResolution(2.0));
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribe_enableVur) {
+    std::vector<SubscribeOptions> options = {{
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 10.0,
+            .enableVariableUpdateRate = true,
+    }};
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(), ElementsAre(options[0]));
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribe_VurStateChange) {
+    std::vector<SubscribeOptions> options = {{
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 10.0,
+            .enableVariableUpdateRate = true,
+    }};
+
+    auto result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(), ElementsAre(options[0]));
+
+    getHardware()->clearSubscribeOptions();
+    result = getManager()->subscribe(getCallbackClient(), options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_TRUE(getHardware()->getSubscribeOptions().empty());
+
+    std::vector<SubscribeOptions> newOptions = {{
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 10.0,
+            .enableVariableUpdateRate = false,
+    }};
+    result = getManager()->subscribe(getCallbackClient(), newOptions, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(), ElementsAre(newOptions[0]));
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribe_enableVur_filterUnchangedEvents) {
+    SpAIBinder binder1 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client1 = IVehicleCallback::fromBinder(binder1);
+    SpAIBinder binder2 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client2 = IVehicleCallback::fromBinder(binder2);
+    SubscribeOptions client1Option = {
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 10.0,
+            .enableVariableUpdateRate = false,
+    };
+    auto result = getManager()->subscribe(client1, {client1Option}, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(), UnorderedElementsAre(client1Option));
+
+    getHardware()->clearSubscribeOptions();
+    SubscribeOptions client2Option = {
+            .propId = 0,
+            .areaIds = {0, 1},
+            .sampleRate = 20.0,
+            .enableVariableUpdateRate = true,
+    };
+
+    result = getManager()->subscribe(client2, {client2Option}, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(),
+                UnorderedElementsAre(
+                        SubscribeOptions{
+                                .propId = 0,
+                                .areaIds = {0},
+                                .sampleRate = 20.0,
+                                // This is enabled for client2, but disabled for client1.
+                                .enableVariableUpdateRate = false,
+                        },
+                        SubscribeOptions{
+                                .propId = 0,
+                                .areaIds = {1},
+                                .sampleRate = 20.0,
+                                .enableVariableUpdateRate = true,
+                        }));
+
+    std::vector<VehiclePropValue> propertyEvents = {{
+                                                            .prop = 0,
+                                                            .areaId = 0,
+                                                            .value = {.int32Values = {0}},
+                                                            .timestamp = 1,
+                                                    },
+                                                    {
+                                                            .prop = 0,
+                                                            .areaId = 1,
+                                                            .value = {.int32Values = {1}},
+                                                            .timestamp = 1,
+                                                    }};
+    auto clients =
+            getManager()->getSubscribedClients(std::vector<VehiclePropValue>(propertyEvents));
+
+    ASSERT_THAT(clients[client1], UnorderedElementsAre(propertyEvents[0]));
+    ASSERT_THAT(clients[client2], UnorderedElementsAre(propertyEvents[0], propertyEvents[1]));
+
+    // If the same property events happen again with a new timestamp.
+    // VUR is disabled for client1, enabled for client2.
+    clients = getManager()->getSubscribedClients({{
+            .prop = 0,
+            .areaId = 0,
+            .value = {.int32Values = {0}},
+            .timestamp = 2,
+    }});
+
+    ASSERT_FALSE(clients.find(client1) == clients.end())
+            << "Must not filter out property events if VUR is not enabled";
+    ASSERT_TRUE(clients.find(client2) == clients.end())
+            << "Must filter out property events if VUR is enabled";
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribe_enableVur_filterUnchangedEvents_withResolution) {
+    SpAIBinder binder1 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client1 = IVehicleCallback::fromBinder(binder1);
+    SpAIBinder binder2 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client2 = IVehicleCallback::fromBinder(binder2);
+    SubscribeOptions client1Option = {
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 10.0,
+            .resolution = 0.01,
+            .enableVariableUpdateRate = false,
+    };
+    auto result = getManager()->subscribe(client1, {client1Option}, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(), UnorderedElementsAre(client1Option));
+
+    getHardware()->clearSubscribeOptions();
+    SubscribeOptions client2Option = {
+            .propId = 0,
+            .areaIds = {0, 1},
+            .sampleRate = 20.0,
+            .resolution = 0.1,
+            .enableVariableUpdateRate = true,
+    };
+
+    result = getManager()->subscribe(client2, {client2Option}, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(),
+                UnorderedElementsAre(
+                        SubscribeOptions{
+                                .propId = 0,
+                                .areaIds = {0},
+                                .sampleRate = 20.0,
+                                .resolution = 0.01,
+                                // This is enabled for client2, but disabled for client1.
+                                .enableVariableUpdateRate = false,
+                        },
+                        SubscribeOptions{
+                                .propId = 0,
+                                .areaIds = {1},
+                                .sampleRate = 20.0,
+                                .resolution = 0.1,
+                                .enableVariableUpdateRate = true,
+                        }));
+
+    std::vector<VehiclePropValue> propertyEvents = {{
+                                                            .prop = 0,
+                                                            .areaId = 0,
+                                                            .value = {.floatValues = {1.0}},
+                                                            .timestamp = 1,
+                                                    },
+                                                    {
+                                                            .prop = 0,
+                                                            .areaId = 1,
+                                                            .value = {.floatValues = {1.0}},
+                                                            .timestamp = 1,
+                                                    }};
+    auto clients =
+            getManager()->getSubscribedClients(std::vector<VehiclePropValue>(propertyEvents));
+
+    ASSERT_THAT(clients[client1], UnorderedElementsAre(propertyEvents[0]));
+    ASSERT_THAT(clients[client2], UnorderedElementsAre(propertyEvents[0], propertyEvents[1]));
+
+    clients = getManager()->getSubscribedClients({{
+            .prop = 0,
+            .areaId = 0,
+            .value = {.floatValues = {1.01}},
+            .timestamp = 2,
+    }});
+
+    ASSERT_FALSE(clients.find(client1) == clients.end())
+            << "Must not filter out property events if VUR is not enabled";
+    ASSERT_TRUE(clients.find(client2) == clients.end())
+            << "Must filter out property events if VUR is enabled and change is too small";
+    ASSERT_TRUE(abs(clients[client1][0].value.floatValues[0] - 1.01) < 0.0000001)
+            << "Expected property value == 1.01, instead got "
+            << clients[client1][0].value.floatValues[0];
+
+    clients = getManager()->getSubscribedClients({{
+            .prop = 0,
+            .areaId = 1,
+            .value = {.floatValues = {1.06}},
+            .timestamp = 3,
+    }});
+
+    ASSERT_TRUE(clients.find(client1) == clients.end())
+            << "Must not get property events for an areaId that the client hasn't subscribed to";
+    ASSERT_FALSE(clients.find(client2) == clients.end())
+            << "Must get property events significant changes";
+    ASSERT_TRUE(abs(clients[client2][0].value.floatValues[0] - 1.1) < 0.0000001)
+            << "Expected property value == 1.1, instead got "
+            << clients[client2][0].value.floatValues[0];
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribe_enableVur_mustNotFilterStatusChange) {
+    SpAIBinder binder1 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client1 = IVehicleCallback::fromBinder(binder1);
+    SpAIBinder binder2 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client2 = IVehicleCallback::fromBinder(binder2);
+    SubscribeOptions client1Option = {
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 10.0,
+            .enableVariableUpdateRate = false,
+    };
+    auto result = getManager()->subscribe(client1, {client1Option}, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(), UnorderedElementsAre(client1Option));
+
+    getHardware()->clearSubscribeOptions();
+    SubscribeOptions client2Option = {
+            .propId = 0,
+            .areaIds = {0, 1},
+            .sampleRate = 20.0,
+            .enableVariableUpdateRate = true,
+    };
+
+    result = getManager()->subscribe(client2, {client2Option}, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    ASSERT_THAT(getHardware()->getSubscribeOptions(),
+                UnorderedElementsAre(
+                        SubscribeOptions{
+                                .propId = 0,
+                                .areaIds = {0},
+                                .sampleRate = 20.0,
+                                // This is enabled for client2, but disabled for client1.
+                                .enableVariableUpdateRate = false,
+                        },
+                        SubscribeOptions{
+                                .propId = 0,
+                                .areaIds = {1},
+                                .sampleRate = 20.0,
+                                .enableVariableUpdateRate = true,
+                        }));
+
+    VehiclePropValue propValue1 = {
+            .prop = 0,
+            .areaId = 0,
+            .value = {.int32Values = {0}},
+            .timestamp = 1,
+    };
+    auto clients = getManager()->getSubscribedClients(std::vector<VehiclePropValue>({propValue1}));
+
+    ASSERT_THAT(clients[client1], UnorderedElementsAre(propValue1));
+
+    // A new event with the same value, but different status must not be filtered out.
+    VehiclePropValue propValue2 = {
+            .prop = 0,
+            .areaId = 0,
+            .value = {.int32Values = {0}},
+            .status = VehiclePropertyStatus::UNAVAILABLE,
+            .timestamp = 2,
+    };
+    clients = getManager()->getSubscribedClients({propValue2});
+
+    ASSERT_THAT(clients[client1], UnorderedElementsAre(propValue2))
+            << "Must not filter out property events that has status change";
+}
+
+TEST_F(SubscriptionManagerTest, testSubscribe_enableVur_timestampUpdated_filterOutdatedEvent) {
+    SpAIBinder binder1 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client1 = IVehicleCallback::fromBinder(binder1);
+    SpAIBinder binder2 = ndk::SharedRefBase::make<PropertyCallback>()->asBinder();
+    std::shared_ptr<IVehicleCallback> client2 = IVehicleCallback::fromBinder(binder2);
+    std::vector<SubscribeOptions> options = {{
+            .propId = 0,
+            .areaIds = {0},
+            .sampleRate = 10.0,
+            .enableVariableUpdateRate = true,
+    }};
+
+    // client1 subscribe with VUR enabled.
+    auto result = getManager()->subscribe(client1, options, true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    // Let client2 subscribe with VUR disabled so that we enabled VUR in DefaultVehicleHal layer.
+    result = getManager()->subscribe(client2,
+                                     {{
+                                             .propId = 0,
+                                             .areaIds = {0},
+                                             .sampleRate = 10.0,
+                                             .enableVariableUpdateRate = false,
+                                     }},
+                                     true);
+    ASSERT_TRUE(result.ok()) << "failed to subscribe: " << result.error().message();
+
+    VehiclePropValue value0 = {
+            .prop = 0,
+            .areaId = 0,
+            .value = {.int32Values = {0}},
+            .timestamp = 1,
+    };
+    auto clients = getManager()->getSubscribedClients({value0});
+
+    ASSERT_THAT(clients[client1], UnorderedElementsAre(value0));
+
+    // A new event with the same value arrived. This must update timestamp to 3.
+    VehiclePropValue value1 = {
+            .prop = 0,
+            .areaId = 0,
+            .value = {.int32Values = {0}},
+            .timestamp = 3,
+    };
+    clients = getManager()->getSubscribedClients({value1});
+
+    ASSERT_TRUE(clients.find(client1) == clients.end())
+            << "Must filter out duplicate property events if VUR is enabled";
+
+    // The latest timestamp is 3, so even though the value is not the same, this is outdated and
+    // must be ignored.
+    VehiclePropValue value2 = {
+            .prop = 0,
+            .areaId = 0,
+            .value = {.int32Values = {1}},
+            .timestamp = 2,
+    };
+    clients = getManager()->getSubscribedClients({value1});
+
+    ASSERT_TRUE(clients.find(client1) == clients.end())
+            << "Must filter out outdated property events if VUR is enabled";
+}
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/aidl/impl/current/vhal/vhal-default-service.rc b/automotive/vehicle/aidl/impl/current/vhal/vhal-default-service.rc
new file mode 100644
index 0000000..761053f
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/vhal/vhal-default-service.rc
@@ -0,0 +1,4 @@
+service vendor.vehicle-hal-default /vendor/bin/hw/android.hardware.automotive.vehicle@V4-default-service
+    class early_hal
+    user vehicle_network
+    group system inet
diff --git a/automotive/vehicle/aidl/impl/current/vhal/vhal-default-service.xml b/automotive/vehicle/aidl/impl/current/vhal/vhal-default-service.xml
new file mode 100644
index 0000000..4695bf7
--- /dev/null
+++ b/automotive/vehicle/aidl/impl/current/vhal/vhal-default-service.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.vehicle</name>
+        <version>4</version>
+        <fqname>IVehicle/default</fqname>
+    </hal>
+</manifest>
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop.json b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop.json
deleted file mode 100644
index b881109..0000000
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop.json
+++ /dev/null
@@ -1,26 +0,0 @@
-[
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": 8,
-    "prop": 289408000
-  },
-  {
-    "timestamp": 2000000,
-    "areaId": 0,
-    "value": 4,
-    "prop": 289408000
-  },
-  {
-    "timestamp": 3000000,
-    "areaId": 0,
-    "value": 16,
-    "prop": 289408000
-  },
-  {
-    "timestamp": 4000000,
-    "areaId": 0,
-    "value": 10,
-    "prop": 289408000
-  }
-]
diff --git a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_different_types.json b/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_different_types.json
deleted file mode 100644
index 0363ebd..0000000
--- a/automotive/vehicle/aidl/impl/fake_impl/GeneratorHub/test/prop_different_types.json
+++ /dev/null
@@ -1,58 +0,0 @@
-[
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": 1,
-    "prop": 287310600
-  },
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": 2,
-    "prop": 289408000
-  },
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": 3.3,
-    "prop": 291504905
-  },
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": 4,
-    "prop": 290457096
-  },
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": "test",
-    "prop": 286265094
-  },
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": [1, 2],
-    "prop": 289476368
-  },
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": {
-      "int32Values": [1, 2],
-      "int64Values": [3, 4],
-      "floatValues": [5.5, 6.6],
-      "stringValue": "test"
-    },
-    "prop": 299896626
-  },
-  {
-    "timestamp": 1000000,
-    "areaId": 0,
-    "value": {
-      "int32Values": [1],
-      "floatValues": [1]
-    },
-    "prop": 299896064
-  }
-]
\ No newline at end of file
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
index b469578..768e97e 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/EvConnectorType.aidl
@@ -46,5 +46,7 @@
   TESLA_SUPERCHARGER = 9,
   GBT_AC = 10,
   GBT_DC = 11,
+  SAE_J3400_AC = 8,
+  SAE_J3400_DC = 9,
   OTHER = 101,
 }
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index 4c5dad2..6188dd9 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -48,11 +48,15 @@
   INFO_DRIVER_SEAT = (((0x010A + 0x10000000) + 0x05000000) + 0x00400000) /* 356516106 */,
   INFO_EXTERIOR_DIMENSIONS = (((0x010B + 0x10000000) + 0x01000000) + 0x00410000) /* 289472779 */,
   INFO_MULTI_EV_PORT_LOCATIONS = (((0x010C + 0x10000000) + 0x01000000) + 0x00410000) /* 289472780 */,
+  INFO_MODEL_TRIM = (((0x010D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.STRING) /* 286261517 */,
+  INFO_VEHICLE_SIZE_CLASS = (((0x010E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 289472782 */,
   PERF_ODOMETER = (((0x0204 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504644 */,
   PERF_VEHICLE_SPEED = (((0x0207 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504647 */,
   PERF_VEHICLE_SPEED_DISPLAY = (((0x0208 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504648 */,
   PERF_STEERING_ANGLE = (((0x0209 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504649 */,
   PERF_REAR_STEERING_ANGLE = (((0x0210 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504656 */,
+  INSTANTANEOUS_FUEL_ECONOMY = (((0x0211 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504657 */,
+  INSTANTANEOUS_EV_EFFICIENCY = (((0x0212 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504658 */,
   ENGINE_COOLANT_TEMP = (((0x0301 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504897 */,
   ENGINE_OIL_LEVEL = (((0x0303 + 0x10000000) + 0x01000000) + 0x00400000) /* 289407747 */,
   ENGINE_OIL_TEMP = (((0x0304 + 0x10000000) + 0x01000000) + 0x00600000) /* 291504900 */,
@@ -69,8 +73,14 @@
   EV_BATTERY_AVERAGE_TEMPERATURE = (((0x030E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504910 */,
   TIRE_PRESSURE = (((0x0309 + 0x10000000) + 0x07000000) + 0x00600000) /* 392168201 */,
   CRITICALLY_LOW_TIRE_PRESSURE = (((0x030A + 0x10000000) + 0x07000000) + 0x00600000) /* 392168202 */,
+  ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE = (((0x030F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504911 */,
+  BRAKE_PEDAL_COMPRESSION_PERCENTAGE = (((0x0310 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 291504912 */,
+  BRAKE_PAD_WEAR_PERCENTAGE = (((0x0311 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WHEEL) + android.hardware.automotive.vehicle.VehiclePropertyType.FLOAT) /* 392168209 */,
+  BRAKE_FLUID_LEVEL_LOW = (((0x0312 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310610 */,
+  VEHICLE_PASSIVE_SUSPENSION_HEIGHT = (((0x0313 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.WHEEL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 390071059 */,
   ENGINE_IDLE_AUTO_STOP_ENABLED = (((0x0320 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310624 */,
   IMPACT_DETECTED = (((0x0330 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289407792 */,
+  VEHICLE_HORN_ENGAGED = (((0x0340 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310656 */,
   GEAR_SELECTION = (((0x0400 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408000 */,
   CURRENT_GEAR = (((0x0401 + 0x10000000) + 0x01000000) + 0x00400000) /* 289408001 */,
   PARKING_BRAKE_ON = (((0x0402 + 0x10000000) + 0x01000000) + 0x00200000) /* 287310850 */,
@@ -85,6 +95,8 @@
   EV_STOPPING_MODE = (((0x040D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408013 */,
   ELECTRONIC_STABILITY_CONTROL_ENABLED = (((0x040E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287310862 */,
   ELECTRONIC_STABILITY_CONTROL_STATE = (((0x040F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408015 */,
+  TURN_SIGNAL_LIGHT_STATE = (((0x0410 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408016 */,
+  TURN_SIGNAL_SWITCH = (((0x0411 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289408017 */,
   HVAC_FAN_SPEED = (((0x0500 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517120 */,
   HVAC_FAN_DIRECTION = (((0x0501 + 0x10000000) + 0x05000000) + 0x00400000) /* 356517121 */,
   HVAC_TEMPERATURE_CURRENT = (((0x0502 + 0x10000000) + 0x05000000) + 0x00600000) /* 358614274 */,
@@ -261,6 +273,7 @@
   VEHICLE_IN_USE = (((0x0F4A + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313738 */,
   CLUSTER_HEARTBEAT = (((0x0F4B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 299896651 */,
   VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL = (((0x0F4C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410892 */,
+  VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL = (((0x0F4F + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410895 */,
   CAMERA_SERVICE_CURRENT_STATE = (((0x0F4D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 289476429 */,
   PER_DISPLAY_MAX_BRIGHTNESS = (((0x0F4E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 289476430 */,
   AUTOMATIC_EMERGENCY_BRAKING_ENABLED = (((0x1000 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313920 */,
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleSizeClass.aidl
similarity index 61%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleSizeClass.aidl
index a5eda52..6817124 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleSizeClass.aidl
@@ -31,9 +31,42 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.automotive.vehicle;
+@Backing(type="int") @VintfStability
+enum VehicleSizeClass {
+  EPA_TWO_SEATER = 0x100,
+  EPA_MINICOMPACT = 0x101,
+  EPA_SUBCOMPACT = 0x102,
+  EPA_COMPACT = 0x103,
+  EPA_MIDSIZE = 0x104,
+  EPA_LARGE = 0x105,
+  EPA_SMALL_STATION_WAGON = 0x106,
+  EPA_MIDSIZE_STATION_WAGON = 0x107,
+  EPA_LARGE_STATION_WAGON = 0x108,
+  EPA_SMALL_PICKUP_TRUCK = 0x109,
+  EPA_STANDARD_PICKUP_TRUCK = 0x10A,
+  EPA_VAN = 0x10B,
+  EPA_MINIVAN = 0x10C,
+  EPA_SMALL_SUV = 0x10D,
+  EPA_STANDARD_SUV = 0x10E,
+  EU_A_SEGMENT = 0x200,
+  EU_B_SEGMENT = 0x201,
+  EU_C_SEGMENT = 0x202,
+  EU_D_SEGMENT = 0x203,
+  EU_E_SEGMENT = 0x204,
+  EU_F_SEGMENT = 0x205,
+  EU_J_SEGMENT = 0x206,
+  EU_M_SEGMENT = 0x207,
+  EU_S_SEGMENT = 0x208,
+  JPN_KEI = 0x300,
+  JPN_SMALL_SIZE = 0x301,
+  JPN_NORMAL_SIZE = 0x302,
+  US_GVWR_CLASS_1_CV = 0x400,
+  US_GVWR_CLASS_2_CV = 0x401,
+  US_GVWR_CLASS_3_CV = 0x402,
+  US_GVWR_CLASS_4_CV = 0x403,
+  US_GVWR_CLASS_5_CV = 0x404,
+  US_GVWR_CLASS_6_CV = 0x405,
+  US_GVWR_CLASS_7_CV = 0x406,
+  US_GVWR_CLASS_8_CV = 0x407,
 }
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
index 7891dd9..5738d21 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
@@ -72,12 +72,15 @@
     TESLA_ROADSTER = 7,
     /**
      * DO NOT USE
-     * Use TESLA_SUPERCHARGER instead.
+     * Use SAE_J3400_AC instead.
      *
      * High Power Wall Charger of Tesla.
      */
     TESLA_HPWC = 8,
     /**
+     * DO NOT USE
+     * Use SAE_J3400_DC instead.
+     *
      * SAE J3400 connector
      *
      * Also known as the "North American Charging Standard" (NACS)
@@ -89,6 +92,32 @@
     /** GBT_DC Fast Charging Standard */
     GBT_DC = 11,
     /**
+     * SAE J3400 connector - AC Charging.
+     *
+     * Also known as the "North American Charging Standard" (NACS).
+     *
+     * This enum must be used if the vehicle specifically supports AC charging. If the vehicle
+     * supports both AC and DC, INFO_EV_CONNECTOR_TYPE should be populated with both SAE_J3400_AC
+     * and SAE_J3400_DC. If the vehicle only supports AC charging, it should only be populated with
+     * SAE_J3400_AC.
+     *
+     * This is equivalent to TESLA_HPWC enum.
+     */
+    SAE_J3400_AC = 8,
+    /**
+     * SAE J3400 connector - DC Charging.
+     *
+     * Also known as the "North American Charging Standard" (NACS).
+     *
+     * This enum must be used if the vehicle specifically supports DC charging. If the vehicle
+     * supports both AC and DC, INFO_EV_CONNECTOR_TYPE should be populated with both SAE_J3400_AC
+     * and SAE_J3400_DC. If the vehicle only supports DC charging, it should only be populated with
+     * SAE_J3400_DC.
+     *
+     * This is equivalent to TESLA_SUPERCHARGER enum.
+     */
+    SAE_J3400_DC = 9,
+    /**
      * Connector type to use when no other types apply. Before using this
      * value, work with Google to see if the EvConnectorType enum can be
      * extended with an appropriate value.
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 e5c09b0..f8cce1a 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -232,6 +232,45 @@
     INFO_MULTI_EV_PORT_LOCATIONS = 0x010C + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
     /**
+     * Public trim name of the vehicle.
+     *
+     * This property must communicate the vehicle's public trim name.
+     *
+     * For example, say an OEM manufactures two different versions of a vehicle model:
+     *   "makeName modelName" and
+     *   "makeName modelName Sport"
+     * This property must be empty for the first vehicle (i.e. base model), and set to "Sport" for
+     * the second vehicle.
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    INFO_MODEL_TRIM =
+            0x010D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.STRING,
+    /**
+     * Vehicle Size Class.
+     *
+     * This property must communicate an integer array that contains the size classifications
+     * followed by the vehicle as enumerated in VehicleSizeClass.aidl. If the vehicle follows a
+     * single standard, then the array size of the property's value should be 1. If the vehicle
+     * follows multiple standards that the OEM wants to communicate, this may be communicated as
+     * additional values in the array.
+     *
+     * For example, suppose a vehicle model follows the VehicleSizeClass.EU_A_SEGMENT standard in
+     * the EU and the VehicleSizeClass.JPN_KEI standard in Japan. In this scenario this property
+     * must return an intArray = [VehicleSizeClass.EU_A_SEGMENT, VehicleSizeClass.JPN_KEI]. If this
+     * vehicle only followed the VehicleSizeClass.EU_A_SEGMENT standard, then we expect intArray =
+     * [VehicleSizeClass.EU_A_SEGMENT].
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleSizeClass
+     * @version 4
+     */
+    INFO_VEHICLE_SIZE_CLASS = 0x010E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL
+            + VehiclePropertyType.INT32_VEC,
+    /**
      * Current odometer value of the vehicle
      *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
@@ -303,6 +342,38 @@
     PERF_REAR_STEERING_ANGLE = 0x0210 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
     /**
+     * Instantaneous Fuel Economy in L/100km.
+     *
+     * This property must communicate the instantaneous fuel economy of the vehicle in units of
+     * L/100km. The property's value is independent of DISTANCE_DISPLAY_UNITS,
+     * FUEL_VOLUME_DISPLAY_UNITS, and FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME property i.e. this
+     * property must always communicate the value in L/100km.
+     *
+     * For the EV version of this property, see INSTANTANEOUS_EV_EFFICIENCY.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    INSTANTANEOUS_FUEL_ECONOMY =
+            0x0211 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+    /**
+     * Instantaneous EV efficiency in km/kWh.
+     *
+     * This property must communicate the instantaneous EV battery efficiency of the vehicle in
+     * units of km/kWh. The property's value is independent of the DISTANCE_DISPLAY_UNITS and
+     * EV_BATTERY_DISPLAY_UNITS properties i.e. this property must always communicate the value in
+     * km/kWh.
+     *
+     * For the fuel version of this property, see INSTANTANEOUS_FUEL_ECONOMY.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    INSTANTANEOUS_EV_EFFICIENCY =
+            0x0212 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+    /**
      * Temperature of engine coolant
      *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
@@ -525,26 +596,52 @@
     /**
      * Tire pressure
      *
-     * Each tires is identified by its areaConfig.areaId config and their
-     * minFloatValue/maxFloatValue are used to store OEM recommended pressure
-     * range. The minFloatValue and maxFloatValue in VehicleAreaConfig must be defined.
-     * The minFloatValue in the areaConfig data represents the lower bound of
-     * the recommended tire pressure.
-     * The maxFloatValue in the areaConfig data represents the upper bound of
-     * the recommended tire pressure.
+     * Each tire is identified by its areaConfig.areaId config and its minFloatValue/maxFloatValue
+     * are used to store OEM recommended pressure range.
+     *
+     * The minFloatValue and maxFloatValue in VehicleAreaConfig must be defined.
+     *
+     * The minFloatValue in the areaConfig data represents the lower bound of the recommended tire
+     * pressure.
+     *
+     * The maxFloatValue in the areaConfig data represents the upper bound of the recommended tire
+     * pressure.
+     *
      * For example:
+     *
      * The following areaConfig indicates the recommended tire pressure
-     * of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL.
+     * of the left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL.
      * .areaConfigs = {
      *      VehicleAreaConfig {
      *          .areaId = VehicleAreaWheel::LEFT_FRONT,
      *          .minFloatValue = 200.0,
      *          .maxFloatValue = 240.0,
      *      }
-     * },
+     * }
+     *
+     * If {@code HasSupportedValueInfo} for a specific area ID is not {@code null}:
+     *
+     * {@code HasSupportedValueInfo.hasMinSupportedValue} and
+     * {@code HasSupportedValueInfo.hasMaxSupportedValue} must be {@code true} for the area ID.
+     *
+     * {@code MinMaxSupportedValueResult.minSupportedValue} represents the lower bound of the
+     * recommended tire pressure for the tire at the specified area ID.
+     *
+     * {@code MinMaxSupportedValueResult.maxSupportedValue} represents the upper bound of the
+     * recommended tire pressure for the tire at the specified area ID.
+     *
+     * For example, if the recommended tire pressure of left_front tire is from 200.0 KILOPASCAL to
+     * 240.0 KILOPASCAL, {@code getMinMaxSupportedValue} for
+     * [propId=TIRE_PRESSURE, areaId=VehicleAreaWheel::LEFT_FRONT] must return a
+     * {@code MinMaxSupportedValueResult} with OK status, 200.0 as minSupportedValue, 240.0 as
+     * maxSupportedValue.
+     *
+     * At boot, minFloatValue is equal to minSupportedValue, maxFloatValue is equal to
+     * maxSupportedValue.
      *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
+     * @require_min_max_supported_value
      * @unit VehicleUnit.KILOPASCAL
      * @version 2
      */
@@ -567,6 +664,100 @@
     CRITICALLY_LOW_TIRE_PRESSURE = 0x030A + 0x10000000 + 0x07000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
     /**
+     * Accelerator pedal compression percentage.
+     *
+     * This property must communicate the percentage that the physical accelerator pedal in the
+     * vehicle is compressed. This property must return a float value from 0 to 100.
+     *
+     * 0 indicates the pedal is not compressed.
+     * 100 indicates the pedal is maximally compressed.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE =
+            0x030F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+    /**
+     * Brake pedal compression percentage.
+     *
+     * This property must communicate the percentage that the physical brake pedal in the vehicle is
+     * compressed. This property must return a float value from 0 to 100.
+     *
+     * 0 indicates the pedal is not compressed.
+     * 100 indicates the pedal is maximally compressed.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    BRAKE_PEDAL_COMPRESSION_PERCENTAGE =
+            0x0310 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
+    /**
+     * Brake pad wear percentage.
+     *
+     * This property must communicate the amount of brake pad wear accumulated by the vehicle as a
+     * percentage. This property return a float value from 0 to 100.
+     *
+     * 0 indicates the brake pad has no wear.
+     * 100 indicates the brake pad is maximally worn.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    BRAKE_PAD_WEAR_PERCENTAGE =
+            0x0311 + VehiclePropertyGroup.SYSTEM + VehicleArea.WHEEL + VehiclePropertyType.FLOAT,
+    /**
+     * Brake fluid low.
+     *
+     * This property must communicate that the brake fluid level in the vehicle is low according to
+     * the OEM. This property must match the vehicle's brake fluid level status as displayed on the
+     * instrument cluster. If the brake fluid level is low, this property must be set to true. If
+     * not, it must be set to false.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    BRAKE_FLUID_LEVEL_LOW =
+            0x0312 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+    /**
+     * Vehicle Passive Suspension Height in mm.
+     *
+     * This property must communicate the real-time suspension displacement of the vehicle relative
+     * to its neutral position, given in mm. In other words, the displacement of the suspension at
+     * any given point in time relative to the suspension's position when the vehicle is on a flat
+     * surface with no passengers or cargo. When the suspension is compressed in comparison to the
+     * neutral position, the value should be negative. When the suspension is decompressed in
+     * comparison to the neutral position, the value should be positive.
+     *
+     * Examples for further clarity:
+     *   1) Suppose the user is driving on a smooth flat surface, and all wheels are currently
+     *   compressed by 2 cm in comparison to the default suspension height. In this scenario, this
+     *   property must be set to -20 for all wheels.
+     *   2) Suppose the user drives over a pothole. While the front left wheel is over the pothole,
+     *   it's decompressed by 3 cm in comparison to the rest of the wheels, or 1 cm in comparison to
+     *   the default suspension height. All the others are still compressed by 2 cm. In this
+     *   scenario, this property must be set to -20 for all wheels except for the front left, which
+     *   must be set to 10.
+     *
+     * HasSupportedValueInfo.hasMinSupportedValue and HasSupportedValueInfo.hasMaxSupportedValue
+     * must be true for all areas.
+     *
+     * MinMaxSupportedValueResult.minSupportedValue represents the lower bound of the suspension
+     * height for the wheel at the specified area ID.
+     *
+     * MinMaxSupportedValueResult.maxSupportedValue represents the upper bound of the suspension
+     * height for the wheel at the specified area ID.
+     *
+     * @change_mode VehiclePropertyChangeMode.CONTINUOUS
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    VEHICLE_PASSIVE_SUSPENSION_HEIGHT =
+            0x0313 + VehiclePropertyGroup.SYSTEM + VehicleArea.WHEEL + VehiclePropertyType.INT32,
+    /**
      * Represents feature for engine idle automatic stop.
      *
      * If true, the vehicle may automatically shut off the engine when it is not needed and then
@@ -592,6 +783,13 @@
      * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
      * unless all bit flags of ImpactSensorLocation are supported.
      *
+     * If {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):
+     *
+     * {@code getSupportedValuesList} must return a {@code SupportedValuesListResult} that contains
+     * supported values unless all bit flags of ImpactSensorLocation are supported.
+     *
+     * At boot, supportedEnumValues is equal to the supported values list.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum ImpactSensorLocation
@@ -600,22 +798,56 @@
     IMPACT_DETECTED =
             0x0330 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
     /**
+     * Vehicle horn engaged.
+     *
+     * This property must communicate if the vehicle's horn is currently engaged or not. If true,
+     * the horn is engaged. If false, the horn is disengaged.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @access VehiclePropertyAccess.READ
+     * @version 4
+     */
+    VEHICLE_HORN_ENGAGED =
+            0x0340 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
+    /**
      * Currently selected gear
      *
      * This is the gear selected by the user.
      *
-     * Values in the config data must represent the list of supported gears for this vehicle. For
-     * example, config data for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE,
-     * GEAR_PARK, GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual transmission the list must be
-     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}
+     * Values in the config array must represent the list of supported gears for this vehicle at
+     * boot time. For example, config array for an automatic transmission must contain
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual
+     * transmission the list must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}
      *
      * In the case of an automatic transmission vehicle that allows the driver to select specific
      * gears on demand (i.e. "manual mode"), GEAR_SELECTION's value must be set to the specific gear
      * selected by the driver instead of simply GEAR_DRIVE.
      *
+     * If {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):
+     *
+     * {@code VehicleAreaConfig.HasSupportedValueInfo.hasSupportedValuesList} for the global area ID
+     * (0) must be {@code true}.
+     *
+     * {@code getSupportedValuesList} for [GEAR_SELECTION, areaId=0] must return a
+     * {@code SupportedValuesListResult} that contains non-null {@code supportedValuesList}.
+     *
+     * The supportedValues must represent the list of supported gears for this vehicle. For example,
+     * for an automatic transmission, the list can be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK,
+     * GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual transmission it can be {GEAR_NEUTRAL,
+     * GEAR_REVERSE, GEAR_1, GEAR_2,...}.
+     *
+     * In the case of an automatic transmission vehicle that allows the driver to select specific
+     * gears on demand (i.e. "manual mode"), the GEAR_SELECTION property value must be set to the
+     * specific gear selected by the driver instead of simply GEAR_DRIVE.
+     *
+     * At boot, the config array's values are equal to the supported values list.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleGear
+     * @require_supported_values_list
+     * @legacy_supported_values_in_config
      * @version 2
      */
     GEAR_SELECTION = 0x0400 + 0x10000000 + 0x01000000
@@ -626,16 +858,35 @@
      * the current gear will be one of GEAR_1, GEAR_2 etc, which reflects
      * the actual gear the transmission is currently running in.
      *
-     * Values in the config data must represent the list of supported gears
-     * for this vehicle.  For example, config data for an automatic transmission
+     * Values in the config array must represent the list of supported gears
+     * for this vehicle at boot time.  For example, config array for an automatic transmission
      * must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...}
-     * and for manual transmission the list must be
+     * and for manual transmission the list must contain
      * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the
      * same as that of the supported gears reported in GEAR_SELECTION.
      *
+     * If {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):
+     *
+     * {@code VehicleAreaConfig.HasSupportedValueInfo.hasSupportedValuesList} for the global area ID
+     * (0) must be {@code true}.
+     *
+     * {@code getSupportedValuesList} for [GEAR_SELECTION, areaId=0] must return a
+     * {@code SupportedValuesListResult} that contains non-null {@code supportedValuesList}.
+     *
+     * The supported values list must represent the list of supported gears
+     * for this vehicle.  For example, for an automatic transmission, this list can be
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...}
+     * and for manual transmission the list can be
+     * {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the
+     * same as that of the supported gears reported in GEAR_SELECTION.
+     *
+     * At boot, the config array's values are equal to the supported values list.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleGear
+     * @require_supported_values_list
+     * @legacy_supported_values_in_config
      * @version 2
      */
     CURRENT_GEAR = 0x0401 + 0x10000000 + 0x01000000
@@ -673,11 +924,30 @@
     /**
      * Regenerative braking level of a electronic vehicle
      *
-     * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
-     * minInt32Value and maxInt32Value must be supported. The minInt32Value must be 0.
+     * The minInt32Value and maxInt32Value in VehicleAreaConfig must be defined. All values between
+     * minInt32Value and maxInt32Value must be supported.
+     *
+     * The minInt32Value indicates the setting for no regenerative braking, must be 0.
      *
      * The maxInt32Value indicates the setting for the maximum amount of energy regenerated from
-     * braking. The minInt32Value indicates the setting for no regenerative braking.
+     * braking.
+     *
+     * All values between min and max supported value must be supported.
+     *
+     * If {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):
+     *
+     * {@code HasSupportedValueInfo.hasMinSupportedValue} and
+     * {@code HasSupportedValueInfo.hasMaxSupportedValue} must be {@code true} for global area ID(0)
+     *
+     * {@code MinMaxSupportedValueResult.minSupportedValue} must be 0.
+     *
+     * {@code MinMaxSupportedValueResult.maxSupportedValue} indicates the setting for the maximum
+     * amount of energy regenerated from braking. The minSupportedValue indicates the setting for no
+     * regenerative braking.
+     *
+     * At boot, minInt32Value is equal to minSupportedValue, maxInt32Value is equal to
+     * maxSupportedValue.
+     *
      *
      * This property is a more granular form of EV_REGENERATIVE_BRAKING_STATE. It allows the user to
      * set a more specific level of regenerative braking if the states in EvRegenerativeBrakingState
@@ -689,6 +959,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @require_min_max_supported_value
      * @version 2
      */
     EV_BRAKE_REGENERATION_LEVEL =
@@ -726,7 +997,12 @@
     NIGHT_MODE = 0x0407 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
     /**
-     * State of the vehicles turn signals
+     * (Deprecated) State of the vehicles turn signals
+     *
+     * This property has been deprecated as it ambiguously defines the state of the vehicle turn
+     * signals without making clear if it means the state of the turn signal lights or the state of
+     * the turn signal switch. The introduction of TURN_SIGNAL_LIGHT_STATE and TURN_SIGNAL_SWITCH
+     * rectifies this problem.
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
@@ -777,6 +1053,15 @@
      * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless
      * all enum values of EvStoppingMode are supported.
      *
+     * If {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):
+     *
+     * For the global area ID (0), {@code getSupportedValuesList}
+     * must return a {@code SupportedValuesListResult} that contains supported values unless all
+     * enum values of EvStoppingMode are supported.
+     *
+     * At boot, supportedEnumValues is equal to the supported values list.
+     *
+     *
      * The EvStoppingMode enum may be extended to include more states in the future.
      *
      * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
@@ -823,6 +1108,15 @@
      * unless all states of both ElectronicStabilityControlState (including OTHER, which is not
      * recommended) and ErrorState are supported.
      *
+     * If {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):
+     *
+     * For the global area ID (0), {@code getSupportedValuesList}
+     * must return a {@code SupportedValuesListResult} that contains supported values unless all
+     * states of both ElectronicStabilityControlState (including OTHER, which is not
+     * recommended) and ErrorState are supported.
+     *
+     * At boot, supportedEnumValues is equal to the supported values list.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum ElectronicStabilityControlState
@@ -832,6 +1126,60 @@
     ELECTRONIC_STABILITY_CONTROL_STATE =
             0x040F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
     /**
+     * Turn signal light state.
+     *
+     * This property must communicate the actual state of the turn signal lights.
+     *
+     * Examples:
+     *   1) Left turn signal light is currently pulsing, right turn signal light is currently off.
+     *   This property must return VehicleTurnSignal.LEFT while the light is on during the pulse,
+     *   and VehicleTurnSignal.NONE when it is off during the pulse.
+     *   2) Right turn signal light is currently pulsing, left turn signal light is currently off.
+     *   This property must return VehicleTurnSignal.RIGHT while the light is on during the pulse,
+     *   and VehicleTurnSignal.NONE when it is off during the pulse.
+     *   3) Both turn signal lights are currently pulsing (e.g. when hazard lights switch is on).
+     *   This property must return VehicleTurnSignal.LEFT | VehicleTurnSignal.RIGHT while the lights
+     *   are on during the pulse, and VehicleTurnSignal.NONE when they are off during the pulse.
+     *
+     * Note that this property uses VehicleTurnSignal as a bit flag, unlike TURN_SIGNAL_SWITCH,
+     * which uses it like a regular enum. This means this property can support ORed together values
+     * in VehicleTurnSignal.
+     *
+     * This is different from the function of TURN_SIGNAL_SWITCH, which must communicate the state
+     * of the turn signal lever/switch.
+     *
+     * This property is a replacement to the TURN_SIGNAL_STATE property, which is now deprecated.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleTurnSignal
+     * @version 4
+     */
+    TURN_SIGNAL_LIGHT_STATE =
+            0x0410 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
+     * Turn signal switch.
+     *
+     * This property must communicate the state of the turn signal lever/switch. This is different
+     * from the function of TURN_SIGNAL_LIGHT_STATE, which must communicate the actual state of the
+     * turn signal lights.
+     *
+     * Note that this property uses VehicleTurnSignal as a regular enum, unlike
+     * TURN_SIGNAL_LIGHT_STATE, which uses it like a bit flag. This means this property cannot
+     * support ORed together values in VehicleTurnSignal.
+     *
+     * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
+     * implement it as VehiclePropertyAccess.READ only.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ_WRITE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleTurnSignal
+     * @version 4
+     */
+    TURN_SIGNAL_SWITCH =
+            0x0411 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
+    /**
      * HVAC Properties
      *
      * Additional rules for mapping non-GLOBAL VehicleArea type HVAC properties
@@ -904,6 +1252,10 @@
      * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
      * implement it as VehiclePropertyAccess.READ only.
      *
+     * The supported hvac fan direction is exposed through {@code HVAC_FAN_DIRECTION_AVAILABLE}
+     * property. Caller should not call {@code getSupportedValuesList}, or use
+     * {@code VehicleAreaConfig#supportedEnumValues}.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
@@ -1550,6 +1902,18 @@
      *              configArray[1] = MILES_PER_HOUR
      *              configArray[2] = KILOMETERS_PER_HOUR
      *
+     * If {@code HasSupportedValueInfo} is not {@code null} for the global area ID (0):
+     *
+     * {@code VehicleAreaConfig.HasSupportedValueInfo.hasSupportedValuesList} for the global area ID
+     * (0) must be {@code true}.
+     *
+     * {@code getSupportedValuesLists} for [VEHICLE_SPEED_DISPLAY_UNITS, areaId=0] must return a
+     * {@code SupportedValuesListResult} that contains non-null {@code supportedValuesList},
+     * e.g. [METER_PER_SEC, MILES_PER_HOUR, KILOMETERS_PER_HOUR].
+     *
+     * At boot, the values in the config array are equal to the supported values list.
+     *
+     *
      * If updating VEHICLE_SPEED_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS
      * properties, then their values must be updated and communicated to the AAOS framework as well.
      *
@@ -1559,6 +1923,9 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleUnit
+     * @require_supported_values_list
+     * @legacy_supported_values_in_config
      * @version 2
      */
     VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000
@@ -5187,9 +5554,7 @@
      *
      * Defines the level of autonomy currently engaged in the vehicle from the J3016_202104 revision
      * of the SAE standard levels 0-5, with 0 representing no autonomy and 5 representing full
-     * driving automation. These levels should be used in accordance with the standards defined in
-     * https://www.sae.org/standards/content/j3016_202104/ and
-     * https://www.sae.org/blog/sae-j3016-update
+     * driving automation.
      *
      * For the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined
      * unless all states of VehicleAutonomousState are supported.
@@ -5201,7 +5566,35 @@
      */
     VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL =
             0x0F4C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
-
+    /**
+     * Target state of vehicle autonomy.
+     *
+     * Defines the level of autonomy being targeted by the vehicle from the J3016_202104 revision of
+     * the SAE standard levels 0-5, with 0 representing no autonomy and 5 representing full driving
+     * automation.
+     *
+     * For example, suppose the vehicle is currently in a Level 3 state of automation and wants to
+     * give the driver full manual control (i.e. Level 0) as soon as it's safe to do so. In this
+     * scenario, this property must be set to VehicleAutonomousState.LEVEL_0. Similarly, if the
+     * vehicle is currently in Level 1 state of automation and wants to go up to Level 2, this
+     * property must be set to VehicleAutonomousState.LEVEL_2. If the vehicle has already reached
+     * and is currently in the target level of autonomy, this property must be equal to the value of
+     * VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL.
+     *
+     * For the global area ID (0), the SupportedValuesListResult#supportedValuesList array must be
+     * defined unless all states of VehicleAutonomousState are supported. These values must match
+     * the values in supportedValuesList of VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL.
+     *
+     * For the property that communicates the current state of autonomy, see
+     * VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL.
+     *
+     * @change_mode VehiclePropertyChangeMode.ON_CHANGE
+     * @access VehiclePropertyAccess.READ
+     * @data_enum VehicleAutonomousState
+     * @version 4
+     */
+    VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL =
+            0x0F4F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
     /**
      * Reports current state of CarEvsService types.
      *
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSizeClass.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSizeClass.aidl
new file mode 100644
index 0000000..1915c4a
--- /dev/null
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSizeClass.aidl
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.vehicle;
+
+/**
+ * Used to enumerate the various size classes of vehicles.
+ *
+ * This enum can be extended in future releases to include additional values.
+ */
+@VintfStability
+@Backing(type="int")
+enum VehicleSizeClass {
+    /**
+     * Represents two-seaters as defined by the EPA standard of size classes for vehicles in the
+     * United States.
+     *
+     * The current implementation of EPA-standard enums follows the classification defined in
+     * Federal Regulation, Title 40—Protection of Environment, Section 600.315-08 "Classes of
+     * comparable automobiles".
+     */
+    EPA_TWO_SEATER = 0x100,
+    /**
+     * Represents minicompact cars as defined by the EPA standard of size classes for vehicles in
+     * the United States.
+     */
+    EPA_MINICOMPACT = 0x101,
+    /**
+     * Represents subcompact cars as defined by the EPA standard of size classes for vehicles in the
+     * United States.
+     */
+    EPA_SUBCOMPACT = 0x102,
+    /**
+     * Represents compact cars as defined by the EPA standard of size classes for vehicles in the
+     * United States.
+     */
+    EPA_COMPACT = 0x103,
+    /**
+     * Represents midsize cars as defined by the EPA standard of size classes for vehicles in the
+     * United States.
+     */
+    EPA_MIDSIZE = 0x104,
+    /**
+     * Represents large cars as defined by the EPA standard of size classes for vehicles in the
+     * United States.
+     */
+    EPA_LARGE = 0x105,
+    /**
+     * Represents small station wagons as defined by the EPA standard of size classes for vehicles
+     * in the United States.
+     */
+    EPA_SMALL_STATION_WAGON = 0x106,
+    /**
+     * Represents midsize station wagons as defined by the EPA standard of size classes for vehicles
+     * in the United States.
+     */
+    EPA_MIDSIZE_STATION_WAGON = 0x107,
+    /**
+     * Represents large station wagons as defined by the EPA standard of size classes for vehicles
+     * in the United States.
+     */
+    EPA_LARGE_STATION_WAGON = 0x108,
+    /**
+     * Represents small pickup trucks as defined by the EPA standard of size classes for vehicles
+     * in the United States.
+     */
+    EPA_SMALL_PICKUP_TRUCK = 0x109,
+    /**
+     * Represents standard pickup trucks as defined by the EPA standard of size classes for vehicles
+     * in the United States.
+     */
+    EPA_STANDARD_PICKUP_TRUCK = 0x10A,
+    /**
+     * Represents vans as defined by the EPA standard of size classes for vehicles in the United
+     * States.
+     */
+    EPA_VAN = 0x10B,
+    /**
+     * Represents minivans as defined by the EPA standard of size classes for vehicles in the United
+     * States.
+     */
+    EPA_MINIVAN = 0x10C,
+    /**
+     * Represents small sport utility vehicles (SUVs) as defined by the EPA standard of size classes
+     * for vehicles in the United States.
+     */
+    EPA_SMALL_SUV = 0x10D,
+    /**
+     * Represents standard sport utility vehicles (SUVs) as defined by the EPA standard of size
+     * classes for vehicles in the United States.
+     */
+    EPA_STANDARD_SUV = 0x10E,
+    /**
+     * Represents A-segment vehicle size class, commonly called "mini" cars or "city" cars, as
+     * classified in the EU.
+     *
+     * The current implementation of the EU Car Segment enums follows the classification first
+     * described in Case No COMP/M.1406 Hyundai / Kia Regulation (EEC) No 4064/89 Merger Procedure.
+     */
+    EU_A_SEGMENT = 0x200,
+    /**
+     * Represents B-segment vehicle size class, commonly called "small" cars, as classified in the
+     * EU.
+     */
+    EU_B_SEGMENT = 0x201,
+    /**
+     * Represents C-segment vehicle size class, commonly called "medium" cars, as classified in the
+     * EU.
+     */
+    EU_C_SEGMENT = 0x202,
+    /**
+     * Represents D-segment vehicle size class, commonly called "large" cars, as classified in the
+     * EU.
+     */
+    EU_D_SEGMENT = 0x203,
+    /**
+     * Represents E-segment vehicle size class, commonly called "executive" cars, as classified in
+     * the EU.
+     */
+    EU_E_SEGMENT = 0x204,
+    /**
+     * Represents F-segment vehicle size class, commonly called "luxury" cars, as classified in the
+     * EU.
+     */
+    EU_F_SEGMENT = 0x205,
+    /**
+     * Represents J-segment vehicle size class, commonly associated with SUVs and off-road vehicles,
+     * as classified in the EU.
+     */
+    EU_J_SEGMENT = 0x206,
+    /**
+     * Represents M-segment vehicle size class, commonly called "multi-purpose" cars, as classified
+     * in the EU.
+     */
+    EU_M_SEGMENT = 0x207,
+    /**
+     * Represents S-segment vehicle size class, commonly called "sports" cars, as classified in the
+     * EU.
+     */
+    EU_S_SEGMENT = 0x208,
+    /**
+     * Represents keijidosha or "kei" cars as defined by the Japanese standard of size classes for
+     * vehicles.
+     *
+     * The current implementation of Japan-standard enums follows the classification defined in the
+     * Japanese Government's Road Vehicle Act of 1951.
+     */
+    JPN_KEI = 0x300,
+    /**
+     * Represents small-size passenger vehicles as defined by the Japanese standard of size classes
+     * for vehicles.
+     */
+    JPN_SMALL_SIZE = 0x301,
+    /**
+     * Represents normal-size passenger vehicles as defined by the Japanese standard of size classes
+     * for vehicles.
+     */
+    JPN_NORMAL_SIZE = 0x302,
+    /**
+     * Represents Class 1 trucks following the US GVWR classification of commercial vehicles. This
+     * is classified under "Light duty" vehicles by the US Federal Highway Association.
+     */
+    US_GVWR_CLASS_1_CV = 0x400,
+    /**
+     * Represents Class 2 trucks following the US GVWR classification of commercial vehicles. This
+     * is classified under "Light duty" vehicles by the US Federal Highway Association.
+     */
+    US_GVWR_CLASS_2_CV = 0x401,
+    /**
+     * Represents Class 3 trucks following the US GVWR classification of commercial vehicles. This
+     * is classified under "Medium duty" vehicles by the US Federal Highway Association.
+     */
+    US_GVWR_CLASS_3_CV = 0x402,
+    /**
+     * Represents Class 4 trucks following the US GVWR classification of commercial vehicles. This
+     * is classified under "Medium duty" vehicles by the US Federal Highway Association.
+     */
+    US_GVWR_CLASS_4_CV = 0x403,
+    /**
+     * Represents Class 5 trucks following the US GVWR classification of commercial vehicles. This
+     * is classified under "Medium duty" vehicles by the US Federal Highway Association.
+     */
+    US_GVWR_CLASS_5_CV = 0x404,
+    /**
+     * Represents Class 6 trucks following the US GVWR classification of commercial vehicles. This
+     * is classified under "Medium duty" vehicles by the US Federal Highway Association.
+     */
+    US_GVWR_CLASS_6_CV = 0x405,
+    /**
+     * Represents Class 7 trucks following the US GVWR classification of commercial vehicles. This
+     * is classified under "Heavy duty" vehicles by the US Federal Highway Association.
+     */
+    US_GVWR_CLASS_7_CV = 0x406,
+    /**
+     * Represents Class 8 trucks following the US GVWR classification of commercial vehicles. This
+     * is classified under "Heavy duty" vehicles by the US Federal Highway Association.
+     */
+    US_GVWR_CLASS_8_CV = 0x407,
+}
diff --git a/automotive/vehicle/tools/translate_aidl_enums.py b/automotive/vehicle/tools/translate_aidl_enums.py
index a7c1808..53afef3 100644
--- a/automotive/vehicle/tools/translate_aidl_enums.py
+++ b/automotive/vehicle/tools/translate_aidl_enums.py
@@ -21,14 +21,16 @@
    ENUM_NAMETest.java files in cts/tests/tests/car/src/android/car/cts and
    packages/services/Car/tests/android_car_api_test/src/android/car/apitest
 
+   Also needs a flag name e.g. FLAG_ANDROID_VIC_VEHICLE_PROPERTIES
+
    Usage:
-   $ python translate_aidl_enums.py ENUM_NAME.aidl
+   $ python translate_aidl_enums.py ENUM_NAME.aidl FLAG_NAME
 """
 import os
 import sys
 
 LICENSE = """/*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -45,15 +47,20 @@
 """
 
 class EnumParser:
-    def __init__(self, file_path, file_name):
+    def __init__(self, file_path, file_name, flag_name):
         self.filePath = file_path
         self.fileName = file_name
+        self.flagName = flag_name
         self.lowerFileName = self.fileName[0].lower() + self.fileName[1:]
+        self.enumNames = []
         self.enums = []
         self.outputMsg = []
         self.outputMsg.append(LICENSE)
         self.outputMsg.append("\npackage android.car.hardware.property;\n")
         self.outputMsg.append("""
+import static android.car.feature.Flags.{};
+
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 
@@ -61,26 +68,61 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-""")
+""".format(self.flagName))
+
+        comment_block = []
+        in_comment = False
 
         with open(self.filePath, 'r') as f:
-            for line in f.readlines()[16:]:
-                if line in ["package android.hardware.automotive.vehicle;\n",
-                            "@VintfStability\n",
-                            '@Backing(type="int")\n']:
+            lines = f.readlines()
+            for line in lines:
+                line = line.rstrip('\n')
+                if line.strip() in ["package android.hardware.automotive.vehicle;",
+                                    "@VintfStability",
+                                    '@Backing(type="int")']:
                     continue
 
-                msg = line
+                if line.strip().startswith('/**') or line.strip().startswith('/*'):
+                    in_comment = True
+                    comment_block.append(line + '\n')
+                    continue
+                elif in_comment:
+                    comment_block.append(line + '\n')
+                    if line.strip().endswith('*/'):
+                        in_comment = False
+                    continue
+                elif line.strip().startswith('*'):
+                    comment_block.append(line + '\n')
+                    continue
+
+                msg = line + '\n'
                 msgSplit = msg.strip().split()
                 if len(msgSplit) > 0 and msgSplit[0] == "enum":
+                    if comment_block:
+                        self.outputMsg.extend(comment_block)
+                        comment_block = []
+                    self.outputMsg.append("@FlaggedApi({})\n".format(self.flagName))
                     msgSplit[0] = "public final class"
                     msg = " ".join(msgSplit) + "\n"
+                    self.outputMsg.append(msg)
                 elif len(msgSplit) > 1 and msgSplit[1] == '=':
+                    if comment_block:
+                        indented_comment_block = [line for line in comment_block]
+                        self.outputMsg.extend(indented_comment_block)
+                        comment_block = []
                     msgSplit.insert(0, "    public static final int")
-                    self.enums.append(msgSplit[1])
-                    msgSplit[-1] = msgSplit[-1][:-1] + ";\n"
-                    msg = " ".join(msgSplit)
-                elif msg == "}\n":
+                    enum_name = msgSplit[1].strip()
+                    self.enumNames.append(enum_name)
+                    enum = msgSplit[3].strip(",")
+                    self.enums.append(enum)
+                    if msgSplit[-1].endswith(','):
+                        msgSplit[-1] = msgSplit[-1][:-1] + ";"
+                    msg = " ".join(msgSplit) + "\n"
+                    self.outputMsg.append(msg)
+                elif line.strip() == '}':
+                    if comment_block:
+                        self.outputMsg.extend(comment_block)
+                        comment_block = []
                     self.outputMsg.append("""
     private {2}() {{}}
 
@@ -101,17 +143,23 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface {2}Int {{}}\n""".format(self.lowerFileName, "{" + ", ".join(self.enums) + "}",
                                               self.fileName))
-                self.outputMsg.append(msg)
-        self.outputMsg.append("TODO: delete this line and manually update this file with app-facing documentation and necessary tags.\n")
+        self.outputMsg.append("}")
 
         self.outputMsgApiTest = []
         self.outputMsgApiTest.append(LICENSE)
         self.outputMsgApiTest.append("""package android.car.apitest;
 
+import static android.car.feature.Flags.{1};
+
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+
 import androidx.test.filters.SmallTest;
 
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -122,6 +170,8 @@
 @SmallTest
 @RunWith(Parameterized.class)
 public class {0}Test {{
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
     private final int mJavaConstantValue;
     private final int mHalConstantValue;
 
@@ -133,56 +183,68 @@
     @Parameterized.Parameters
     public static Collection constantValues() {{
         return Arrays.asList(
-                new Object[][] {{""".format(self.fileName))
-        for enum in self.enums:
+                new Object[][] {{""".format(self.fileName, self.flagName))
+        for enum in self.enumNames:
             self.outputMsgApiTest.append("""
                         {{
                                 android.car.hardware.property.{0}.{1},
                                 android.hardware.automotive.vehicle.{0}.{1}
                         }},""".format(self.fileName, enum))
         self.outputMsgApiTest.append("""
-                });
-    }
+                }});
+    }}
 
     @Test
-    public void testMatchWithVehicleHal() {
+    @RequiresFlagsEnabled({})
+    public void testMatchWithVehicleHal() {{
         assertWithMessage("Java constant")
                 .that(mJavaConstantValue)
                 .isEqualTo(mHalConstantValue);
-    }
-}
-""")
+    }}
+}}
+""".format(self.flagName))
 
         self.outputMsgCtsTest = []
         self.outputMsgCtsTest.append(LICENSE)
         self.outputMsgCtsTest.append("""
 package android.car.cts;
 
+import static android.car.feature.Flags.{1};
+
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.car.cts.utils.VehiclePropertyUtils;
 import android.car.hardware.property.{0};
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 
+import org.junit.Rule;
 import org.junit.Test;
 
 import java.util.List;
 
 public class {0}Test {{
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
     @Test
-    public void testToString() {{""".format(self.fileName))
-        for enum in self.enums:
+    @RequiresFlagsEnabled({1})
+    public void testToString() {{""".format(self.fileName, self.flagName))
+        for enum in self.enumNames:
             self.outputMsgCtsTest.append("""
         assertThat({0}.toString(
                 {0}.{1}))
                 .isEqualTo("{1}");""".format(self.fileName, enum))
+        max_enum_value = len(self.enums)
         self.outputMsgCtsTest.append("""
         assertThat({0}.toString({1})).isEqualTo("{2}");
         assertThat({0}.toString(12)).isEqualTo("0xc");
     }}
 
     @Test
+    @RequiresFlagsEnabled({4})
     public void testAll{0}sAreMappedInToString() {{
         List<Integer> {3}s =
                 VehiclePropertyUtils.getIntegersFromDataEnums({0}.class);
@@ -194,11 +256,11 @@
         }}
     }}
 }}
-""".format(self.fileName, len(self.enums), hex(len(self.enums)), self.lowerFileName))
+""".format(self.fileName, len(self.enums), hex(len(self.enums)), self.lowerFileName, self.flagName))
 
 def main():
-    if len(sys.argv) != 2:
-        print("Usage: {} enum_aidl_file".format(sys.argv[0]))
+    if len(sys.argv) != 3:
+        print("Usage: {} enum_aidl_file ALL_CAPS_FLAG_NAME".format(sys.argv[0]))
         sys.exit(1)
     print("WARNING: This file only generates the base enum values in the framework layer. The "
           + "generated files must be reviewed by you and edited if any additional changes are "
@@ -207,12 +269,14 @@
           + "the new property is system API")
     file_path = sys.argv[1]
     file_name = file_path.split('/')[-1][:-5]
-    parser = EnumParser(file_path, file_name)
+    flag_name = sys.argv[2]
+    parser = EnumParser(file_path, file_name, flag_name)
 
     android_top = os.environ['ANDROID_BUILD_TOP']
     if not android_top:
         print('ANDROID_BUILD_TOP is not in environmental variable, please run source and lunch '
               + 'at the android root')
+        sys.exit(1)
 
     with open(android_top + "/packages/services/Car/car-lib/src/android/car/hardware/property/"
               + file_name + ".java", 'w') as f:
diff --git a/automotive/vehicle/vhal_static_cpp_lib.mk b/automotive/vehicle/vhal_static_cpp_lib.mk
index 9371453..7ab34f4 100644
--- a/automotive/vehicle/vhal_static_cpp_lib.mk
+++ b/automotive/vehicle/vhal_static_cpp_lib.mk
@@ -16,5 +16,5 @@
 # interface and VHAL properties.
 
 LOCAL_STATIC_LIBRARIES += \
-    android.hardware.automotive.vehicle-V3-ndk \
+    android.hardware.automotive.vehicle-V4-ndk \
     android.hardware.automotive.vehicle.property-V4-ndk
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index fb3c8cd..02a9830 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -1376,6 +1376,84 @@
                    VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
 }
 
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyInfoModelTrimConfig) {
+    verifyProperty(VehicleProperty::INFO_MODEL_TRIM, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::STRING);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyInfoVehicleSizeClassConfig) {
+    verifyProperty(VehicleProperty::INFO_VEHICLE_SIZE_CLASS, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::STATIC, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32_VEC);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyTurnSignalLightStateConfig) {
+    verifyProperty(VehicleProperty::TURN_SIGNAL_LIGHT_STATE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyTurnSignalSwitchConfig) {
+    verifyProperty(VehicleProperty::TURN_SIGNAL_SWITCH, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyInstantaneousFuelEconomyConfig) {
+    verifyProperty(VehicleProperty::INSTANTANEOUS_FUEL_ECONOMY, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::CONTINUOUS, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyInstantaneousEvEfficiencyConfig) {
+    verifyProperty(VehicleProperty::INSTANTANEOUS_EV_EFFICIENCY, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::CONTINUOUS, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyVehicleHornEngagedConfig) {
+    verifyProperty(VehicleProperty::VEHICLE_HORN_ENGAGED, VehiclePropertyAccess::READ_WRITE,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyVehicleDrivingAutomationTargetLevelConfig) {
+    verifyProperty(VehicleProperty::VEHICLE_DRIVING_AUTOMATION_TARGET_LEVEL,
+                   VehiclePropertyAccess::READ, VehiclePropertyChangeMode::ON_CHANGE,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::INT32);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyAcceleratorPedalCompressionPercentageConfig) {
+    verifyProperty(VehicleProperty::ACCELERATOR_PEDAL_COMPRESSION_PERCENTAGE,
+                   VehiclePropertyAccess::READ, VehiclePropertyChangeMode::CONTINUOUS,
+                   VehiclePropertyGroup::SYSTEM, VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyBrakePedalCompressionPercentageConfig) {
+    verifyProperty(VehicleProperty::BRAKE_PEDAL_COMPRESSION_PERCENTAGE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::CONTINUOUS, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyBrakePadWearPercentageConfig) {
+    verifyProperty(VehicleProperty::BRAKE_PAD_WEAR_PERCENTAGE, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::WHEEL, VehiclePropertyType::FLOAT);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyBrakeFluidLevelLowConfig) {
+    verifyProperty(VehicleProperty::BRAKE_FLUID_LEVEL_LOW, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::ON_CHANGE, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::GLOBAL, VehiclePropertyType::BOOLEAN);
+}
+
+TEST_P(VtsHalAutomotiveVehicleTargetTest, verifyVehiclePassiveSuspensionHeightConfig) {
+    verifyProperty(VehicleProperty::VEHICLE_PASSIVE_SUSPENSION_HEIGHT, VehiclePropertyAccess::READ,
+                   VehiclePropertyChangeMode::CONTINUOUS, VehiclePropertyGroup::SYSTEM,
+                   VehicleArea::WHEEL, VehiclePropertyType::INT32);
+}
+
 bool VtsHalAutomotiveVehicleTargetTest::checkIsSupported(int32_t propertyId) {
     auto result = mVhalClient->getPropConfigs({propertyId});
     return result.ok();
diff --git a/broadcastradio/aidl/Android.bp b/broadcastradio/aidl/Android.bp
index 82ee949..081bae3 100644
--- a/broadcastradio/aidl/Android.bp
+++ b/broadcastradio/aidl/Android.bp
@@ -51,12 +51,12 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 
 }
 
 // Note: This should always be one version ahead of the last frozen version
-latest_android_hardware_broadcastradio = "android.hardware.broadcastradio-V2"
+latest_android_hardware_broadcastradio = "android.hardware.broadcastradio-V3"
 
 cc_defaults {
     name: "latest_android_hardware_broadcastradio_ndk_static",
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Alert.aidl
similarity index 84%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Alert.aidl
index a5eda52..7e02f70 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Alert.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Alert {
+  android.hardware.broadcastradio.AlertStatus status;
+  android.hardware.broadcastradio.AlertMessageType messageType;
+  android.hardware.broadcastradio.AlertInfo[] infoArray;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertArea.aidl
similarity index 87%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertArea.aidl
index a5eda52..aa828d0 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertArea.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AlertArea {
+  android.hardware.broadcastradio.Polygon[] polygons;
+  android.hardware.broadcastradio.Geocode[] geocodes;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertCategory.aidl
similarity index 86%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertCategory.aidl
index a5eda52..f493e75 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertCategory.aidl
@@ -31,9 +31,19 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AlertCategory {
+  GEO,
+  MET,
+  SAFETY,
+  SECURITY,
+  RESCUE,
+  FIRE,
+  HEALTH,
+  ENV,
+  TRANSPORT,
+  INFRA,
+  CBRNE,
+  OTHER,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertCertainty.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertCertainty.aidl
index a5eda52..dcf283a 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertCertainty.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AlertCertainty {
+  OBSERVED,
+  LIKELY,
+  POSSIBLE,
+  UNLIKELY,
+  UNKNOWN,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertInfo.aidl
similarity index 77%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertInfo.aidl
index a5eda52..da08c9a 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertInfo.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable AlertInfo {
+  android.hardware.broadcastradio.AlertCategory[] categoryArray;
+  android.hardware.broadcastradio.AlertUrgency urgency;
+  android.hardware.broadcastradio.AlertSeverity severity;
+  android.hardware.broadcastradio.AlertCertainty certainty;
+  String description;
+  android.hardware.broadcastradio.AlertArea[] areas;
+  @nullable String language;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertMessageType.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertMessageType.aidl
index a5eda52..2b89c92 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertMessageType.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AlertMessageType {
+  ALERT,
+  UPDATE,
+  CANCEL,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertSeverity.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertSeverity.aidl
index a5eda52..5c91abd 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertSeverity.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AlertSeverity {
+  EXTREME,
+  SEVERE,
+  MODERATE,
+  MINOR,
+  UNKNOWN,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertStatus.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertStatus.aidl
index a5eda52..8ce69b5 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertStatus.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AlertStatus {
+  ACTUAL,
+  EXERCISE,
+  TEST,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertUrgency.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertUrgency.aidl
index a5eda52..fd0491d 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/AlertUrgency.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum AlertUrgency {
+  IMMEDIATE,
+  EXPECTED,
+  FUTURE,
+  PAST,
+  UNKNOWN,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Coordinate.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Coordinate.aidl
index a5eda52..b303986 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Coordinate.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Coordinate {
+  double latitude;
+  double longitude;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Geocode.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Geocode.aidl
index a5eda52..a07e1c0 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Geocode.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Geocode {
+  String valueName;
+  String value;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Polygon.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Polygon.aidl
index a5eda52..4d4d78d 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/Polygon.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.broadcastradio;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Polygon {
+  android.hardware.broadcastradio.Coordinate[] coordinates;
 }
diff --git a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl
index 997cdd7..dd57901 100644
--- a/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl
+++ b/broadcastradio/aidl/aidl_api/android.hardware.broadcastradio/current/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -42,6 +42,7 @@
   int signalQuality;
   android.hardware.broadcastradio.Metadata[] metadata;
   android.hardware.broadcastradio.VendorKeyValue[] vendorInfo;
+  @nullable android.hardware.broadcastradio.Alert emergencyAlert;
   const int FLAG_LIVE = (1 << 0) /* 1 */;
   const int FLAG_MUTED = (1 << 1) /* 2 */;
   const int FLAG_TRAFFIC_PROGRAM = (1 << 2) /* 4 */;
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Alert.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Alert.aidl
new file mode 100644
index 0000000..a307ccc
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Alert.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.AlertInfo;
+import android.hardware.broadcastradio.AlertMessageType;
+import android.hardware.broadcastradio.AlertStatus;
+
+/**
+ * Emergency Alert Message.
+ *
+ * <p>Alert message can be sent from a radio station of technologies such as HD radio to
+ * the radio users for some emergency events (see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable Alert {
+    /**
+     * The status of the alert message.
+     */
+    AlertStatus status;
+
+    /**
+     * The message type of the alert message.
+     */
+    AlertMessageType messageType;
+
+    /**
+     * Array of alert information.
+     */
+    AlertInfo[] infoArray;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertArea.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertArea.aidl
new file mode 100644
index 0000000..b3f07b3
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertArea.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.Geocode;
+import android.hardware.broadcastradio.Polygon;
+
+/**
+ * The geographic area that delineates the affected area of the alert message
+ *
+ * <p>(see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable AlertArea {
+    /**
+     * Polygons that delineate the affected area of the alert message.
+     */
+    Polygon[] polygons;
+
+    /**
+     * Geographic code delineating the affected area of the alert message.
+     */
+    Geocode[] geocodes;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertCategory.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertCategory.aidl
new file mode 100644
index 0000000..a24361a
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertCategory.aidl
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * The category of the subject event of the emergency alert message.
+ *
+ * <p>(see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum AlertCategory {
+    /**
+     * Alert category related to geophysical (inc. landslide).
+     */
+    GEO,
+
+    /**
+     * Alert category related to meteorological (inc. flood).
+     */
+    MET,
+
+    /**
+     * Alert category related to general emergency and public safety.
+     */
+    SAFETY,
+
+    /**
+     * Alert category related to law enforcement, military, homeland and local/private security.
+     */
+    SECURITY,
+
+    /**
+     * Alert category related to rescue and recovery.
+     */
+    RESCUE,
+
+    /**
+     * Alert category related to fire suppression and rescue.
+     */
+    FIRE,
+
+    /**
+     * Alert category related to medical and public health.
+     */
+    HEALTH,
+
+    /**
+     * Alert category related to pollution and other environmental.
+     */
+    ENV,
+
+    /**
+     * Alert category related to public and private transportation.
+     */
+    TRANSPORT,
+
+    /**
+     * Utility, telecommunication, other non-transport infrastructure.
+     */
+    INFRA,
+
+    /**
+     * Alert category related to chemical, biological, radiological, nuclear or high-yield
+     * explosive threat or attack.
+     */
+    CBRNE,
+
+    /**
+     * Alert category related to other events.
+     */
+    OTHER,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertCertainty.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertCertainty.aidl
new file mode 100644
index 0000000..11f069e
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertCertainty.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * The certainty of the subject event of the emergency alert message
+ *
+ * <p>(see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum AlertCertainty {
+    /**
+     * Certainty indicating that the event is determined to have occurred or to be ongoing.
+     */
+    OBSERVED,
+
+    /**
+     * Certainty indicating that the event is likely (probability > ~50%).
+     */
+    LIKELY,
+
+    /**
+     * Certainty indicating that the event is possible but not likely (probability <= ~50%).
+     */
+    POSSIBLE,
+
+    /**
+     * Certainty indicating that the event is not expected to occur (probability ~ 0).
+     */
+    UNLIKELY,
+
+    /**
+     * Unknown certainty.
+     */
+    UNKNOWN,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertInfo.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertInfo.aidl
new file mode 100644
index 0000000..ab2e6f7
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertInfo.aidl
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.AlertArea;
+import android.hardware.broadcastradio.AlertCategory;
+import android.hardware.broadcastradio.AlertCertainty;
+import android.hardware.broadcastradio.AlertSeverity;
+import android.hardware.broadcastradio.AlertUrgency;
+
+/**
+ * Alert information.
+ *
+ * <p>(see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable AlertInfo {
+    /**
+     * Array of categories of the subject event of the alert info.
+     *
+     * <p>According to ITU-T X.1303, a single alert info block may contains multiple categories.
+     */
+    AlertCategory[] categoryArray;
+
+    /**
+     * The urgency of the subject event of the alert info.
+     *
+     * <p>Urgency represents the time available to prepare for the alert.
+     */
+    AlertUrgency urgency;
+
+    /**
+     * The severity of the subject event of the alert info.
+     *
+     * <p>Severity represents the intensity of impact.
+     */
+    AlertSeverity severity;
+
+    /**
+     * The certainty of the subject event of the alert info.
+     *
+     * <p>Certainty represents confidence in the observation or prediction.
+     */
+    AlertCertainty certainty;
+
+    /**
+     * Textual descriptions of the subject event.
+     */
+    String description;
+
+    /**
+     * The array of geographic areas to which the alert info segment in which it appears applies.
+     */
+    AlertArea[] areas;
+
+    /**
+     * The IETF RFC 3066 language code donating the language of the alert message.
+     *
+     * <p>This field is optional.
+     */
+    @nullable String language;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertMessageType.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertMessageType.aidl
new file mode 100644
index 0000000..1dd4e2b
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertMessageType.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * The emergency alert message type
+ *
+ * <p>The message type indicates the emergency alert message nature.
+ * (see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum AlertMessageType {
+    /**
+     * Initial information requiring attention by targeted recipients.
+     */
+    ALERT,
+
+    /**
+     * Updates and supersedes the earlier message(s).
+     */
+    UPDATE,
+
+    /**
+     * Cancels the earlier message(s).
+     */
+    CANCEL,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertSeverity.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertSeverity.aidl
new file mode 100644
index 0000000..acc11c4
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertSeverity.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * The severity of the subject event of the emergency alert message
+ *
+ * <p>(see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum AlertSeverity {
+    /**
+     * Severity indicating extraordinary threat to life or property.
+     */
+    EXTREME,
+
+    /**
+     * Severity indicating significant threat to life or property.
+     */
+    SEVERE,
+
+    /**
+     * Severity indicating possible threat to life or property.
+     */
+    MODERATE,
+
+    /**
+     * Severity indicating minimal to no known threat to life or property.
+     */
+    MINOR,
+
+    /**
+     * Unknown severity.
+     */
+    UNKNOWN,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertStatus.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertStatus.aidl
new file mode 100644
index 0000000..8b0c917
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertStatus.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * The status of the alert message
+ *
+ * <p>Status is the appropriate handling of the alert message (see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum AlertStatus {
+    /**
+     * Actionable by all targeted recipients.
+     */
+    ACTUAL,
+
+    /**
+     * Actionable only by designated exercise participants.
+     */
+    EXERCISE,
+
+    /**
+     * Technical testing only, all recipients disregard.
+     */
+    TEST,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/AlertUrgency.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/AlertUrgency.aidl
new file mode 100644
index 0000000..c7bfdbc
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/AlertUrgency.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * The severity of the subject event of the emergency alert message.
+ *
+ * <p>(see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(equals=true, toString=true)
+enum AlertUrgency {
+    /**
+     * Urgency indicating that responsive action should be taken immediately.
+     */
+    IMMEDIATE,
+
+    /**
+     * Urgency indicating that responsive action should be taken soon.
+     */
+    EXPECTED,
+
+    /**
+     * Urgency indicating that responsive action should be taken in the near future.
+     */
+    FUTURE,
+
+    /**
+     * Urgency indicating that responsive action is no longer required.
+     */
+    PAST,
+
+    /**
+     * Unknown urgency.
+     */
+    UNKNOWN,
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Coordinate.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Coordinate.aidl
new file mode 100644
index 0000000..9c9680b
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Coordinate.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Coordinate reprensenting the geographic location in alert message
+ *
+ * <p>(see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable Coordinate {
+    /**
+     * Latitude of the cooridinate.
+     *
+     * <p>Latitude is in the range of -90 to 90.
+     */
+    double latitude;
+
+    /**
+     * Longitude of the cooridinate.
+     *
+     * <p>Longitude is in the range of -180 to 180.
+     */
+    double longitude;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Geocode.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Geocode.aidl
new file mode 100644
index 0000000..ca98154
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Geocode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+/**
+ * Geographic code reprensenting location in alert message.
+ *
+ * <p>Geocode is mainly for information display instead of parsing on radio application side. See
+ * ITU-T X.1303 bis for more info.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable Geocode {
+    /**
+     * Value name of a geographic code.
+     *
+     * <p>Value name are acronyms should be represented in all capital
+     * letters without periods (e.g., SAME, FIPS, ZIP).
+     */
+    String valueName;
+
+    /**
+     * Value of a geographic code.
+     */
+    String value;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/Polygon.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/Polygon.aidl
new file mode 100644
index 0000000..12bd2cd
--- /dev/null
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/Polygon.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.broadcastradio;
+
+import android.hardware.broadcastradio.Coordinate;
+
+/**
+ * The array of coordinates defining a polygon
+ *
+ * <p>(see ITU-T X.1303 bis for more info).
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable Polygon {
+    /**
+     * Cooridinates of points defining a polygon.
+     *
+     * <p>A minimum of 4 coordinates MUST be present and the first and last
+     * coordinates must be the same. See WGS 84 for more information.
+     */
+    Coordinate[] coordinates;
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
index d4ccd01..0b5abe2 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/ProgramInfo.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.broadcastradio;
 
+import android.hardware.broadcastradio.Alert;
 import android.hardware.broadcastradio.Metadata;
 import android.hardware.broadcastradio.ProgramIdentifier;
 import android.hardware.broadcastradio.ProgramSelector;
@@ -192,4 +193,12 @@
      * for example: paid-service=true; bitrate=320kbps.
      */
     VendorKeyValue[] vendorInfo;
+
+    /**
+     * Emergency alert message.
+     *
+     * <p>Alert message can be sent from a radio station of technologies such as HD radio to
+     * the radio users for some emergency events.
+     */
+    @nullable Alert emergencyAlert;
 }
diff --git a/broadcastradio/aidl/default/BroadcastRadio.cpp b/broadcastradio/aidl/default/BroadcastRadio.cpp
index 4d6d81d..015cae0 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.cpp
+++ b/broadcastradio/aidl/default/BroadcastRadio.cpp
@@ -17,11 +17,9 @@
 #include "BroadcastRadio.h"
 #include <broadcastradio-utils-aidl/Utils.h>
 #include <broadcastradio-utils-aidl/UtilsV2.h>
+#include <broadcastradio-utils-aidl/UtilsV3.h>
 #include "resources.h"
 
-#include <aidl/android/hardware/broadcastradio/IdentifierType.h>
-#include <aidl/android/hardware/broadcastradio/Result.h>
-
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 
@@ -47,6 +45,8 @@
 inline constexpr std::chrono::milliseconds kTuneDelayTimeMs = 150ms;
 inline constexpr std::chrono::seconds kListDelayTimeS = 1s;
 
+const string kAlertAreaDelimiter = "+";
+const string kAlertCoordinateGeocodeDelimiter = ",";
 // clang-format off
 const AmFmBandRange kFmFullBandRange = {65000, 108000, 10, 0};
 const AmFmBandRange kAmFullBandRange = {150, 30000, 1, 0};
@@ -142,6 +142,30 @@
     return info;
 }
 
+static Alert createSampleAlert() {
+    Polygon polygon = {{{-38.47, -120.14},
+                        {38.34, -119.95},
+                        {38.52, -119.74},
+                        {38.62, -119.89},
+                        {-38.47, -120.14}}};
+    AlertArea alertArea1 = {{polygon}, {{"SAME", "006109"}, {"SAME", "006209"}}};
+    AlertArea alertArea2 = {{}, {{"SAME", "006009"}}};
+    AlertInfo alertInfo;
+    alertInfo.categoryArray = {AlertCategory::GEO, AlertCategory::TRANSPORT};
+    alertInfo.urgency = AlertUrgency::FUTURE;
+    alertInfo.severity = AlertSeverity::SEVERE;
+    alertInfo.certainty = AlertCertainty::POSSIBLE;
+    alertInfo.description = "Sample radio alert.";
+    alertInfo.language = "en-US";
+    alertInfo.areas.push_back(alertArea1);
+    alertInfo.areas.push_back(alertArea2);
+    Alert alert;
+    alert.status = AlertStatus::ACTUAL;
+    alert.messageType = AlertMessageType::ALERT;
+    alert.infoArray.push_back(alertInfo);
+    return alert;
+}
+
 static bool checkDumpCallerHasWritePermissions(int fd) {
     uid_t uid = AIBinder_getCallingUid();
     if (uid == AID_ROOT || uid == AID_SHELL || uid == AID_SYSTEM) {
@@ -151,6 +175,87 @@
     return false;
 }
 
+static bool parseGeocode(int fd, const string& geocodeString, Geocode& parsedGeocode) {
+    vector<string> geocodeStringPair =
+            ::android::base::Split(geocodeString, kAlertCoordinateGeocodeDelimiter);
+    if (geocodeStringPair.size() != 2) {
+        dprintf(fd, "Geocode is not of \"VALUE_NAME,VALUE\" format: %s\n", geocodeString.c_str());
+        return false;
+    }
+    parsedGeocode.valueName = geocodeStringPair[0];
+    parsedGeocode.value = geocodeStringPair[1];
+    return true;
+}
+
+static bool parsePolygon(int fd, const string& polygonString, Polygon& parsedPolygon) {
+    vector<Coordinate> coordinates;
+    vector<string> coordinateStrings =
+            ::android::base::Split(polygonString, kAlertCoordinateGeocodeDelimiter);
+    if (coordinateStrings.size() % 2) {
+        dprintf(fd, "Incomplete \"LATITUDE,LONGITUDE\" coordinate pairs separated by \",\": %s\n",
+                polygonString.c_str());
+        return false;
+    }
+    for (size_t i = 0; i < coordinateStrings.size(); i += 2) {
+        double latitude;
+        double longitude;
+        if (!utils::parseArgDouble(coordinateStrings[i], &latitude) ||
+            !utils::parseArgDouble(coordinateStrings[i + 1], &longitude)) {
+            dprintf(fd, "Value of \"LATITUDE,LONGITUDE\" coordinate pair is not double-type: %s\n",
+                    coordinateStrings[i].c_str());
+            return false;
+        }
+        coordinates.push_back(Coordinate(latitude, longitude));
+    }
+    parsedPolygon.coordinates = coordinates;
+    return true;
+}
+
+static bool parseAreaString(int fd, const string& areaString, AlertArea& parsedAlertArea) {
+    vector<string> areaEntryStrings = ::android::base::Split(areaString, "_");
+    for (const auto& areaEntryString : areaEntryStrings) {
+        vector<string> areaTypeValuePair = ::android::base::Split(areaEntryString, ":");
+        if (areaTypeValuePair.size() != 2) {
+            dprintf(fd, "Area is not of \"<TYPE>:<VALUE>\" format: %s\n", areaEntryString.c_str());
+            return false;
+        }
+        if (EqualsIgnoreCase(areaTypeValuePair[0], "polygon")) {
+            Polygon parsedPolygon;
+            if (!parsePolygon(fd, areaTypeValuePair[1], parsedPolygon)) {
+                return false;
+            }
+            parsedAlertArea.polygons.push_back(parsedPolygon);
+        } else if (EqualsIgnoreCase(areaTypeValuePair[0], "geocode")) {
+            Geocode parsedGeocode;
+            if (!parseGeocode(fd, areaTypeValuePair[1], parsedGeocode)) {
+                return false;
+            }
+            parsedAlertArea.geocodes.push_back(parsedGeocode);
+        } else {
+            dprintf(fd, "Invalid area <TYPE> other than \"polygon\" and \"geocode\": %s\n",
+                    areaTypeValuePair[0].c_str());
+            return false;
+        }
+    }
+    return true;
+}
+
+static bool parseAreaListString(int fd, const string& areaListString,
+                                vector<AlertArea>& parsedAlertAreas) {
+    if (EqualsIgnoreCase(areaListString, kAlertAreaDelimiter)) {
+        return true;
+    }
+    vector<string> areaStrings = ::android::base::Split(areaListString, kAlertAreaDelimiter);
+    for (const auto& areaString : areaStrings) {
+        AlertArea parsedArea;
+        if (!parseAreaString(fd, areaString, parsedArea)) {
+            return false;
+        }
+        parsedAlertAreas.push_back(parsedArea);
+    }
+    return true;
+}
+
 }  // namespace
 
 BroadcastRadio::BroadcastRadio(const VirtualRadio& virtualRadio)
@@ -162,9 +267,9 @@
         ProgramSelector sel = utils::makeSelectorAmfm(ranges[0].lowerBound);
         VirtualProgram virtualProgram = {};
         if (mVirtualRadio.getProgram(sel, &virtualProgram)) {
-            mCurrentProgram = virtualProgram.selector;
+            mCurrentProgramSelector = virtualProgram.selector;
         } else {
-            mCurrentProgram = sel;
+            mCurrentProgramSelector = sel;
         }
         adjustAmFmRangeLocked();
     }
@@ -230,13 +335,13 @@
             isDigitalProgramAllowed(sel, isConfigFlagSetLocked(ConfigFlag::FORCE_ANALOG_FM),
                                     isConfigFlagSetLocked(ConfigFlag::FORCE_ANALOG_AM));
     if (isProgramAllowed && mVirtualRadio.getProgram(sel, &virtualProgram)) {
-        mCurrentProgram = virtualProgram.selector;
+        mCurrentProgramSelector = virtualProgram.selector;
         programInfo = virtualProgram;
     } else {
         if (!isProgramAllowed) {
-            mCurrentProgram = utils::makeSelectorAmfm(utils::getAmFmFrequency(sel));
+            mCurrentProgramSelector = utils::makeSelectorAmfm(utils::getAmFmFrequency(sel));
         } else {
-            mCurrentProgram = sel;
+            mCurrentProgramSelector = sel;
         }
         programInfo = makeSampleProgramInfo(sel);
     }
@@ -277,6 +382,10 @@
 void BroadcastRadio::handleProgramInfoUpdateRadioCallback(
         ProgramInfo programInfo, const std::shared_ptr<ITunerCallback>& callback) {
     callback->onCurrentProgramInfoChanged(programInfo);
+    {
+        lock_guard<mutex> lk(mMutex);
+        mCurrentProgramInfo = programInfo;
+    }
     if (programInfo.selector.primaryId.type != IdentifierType::HD_STATION_ID_EXT) {
         return;
     }
@@ -285,12 +394,14 @@
     programInfo.infoFlags |= ProgramInfo::FLAG_HD_SIS_ACQUISITION;
     auto sisAcquiredTask = [this, callback, programInfo, cancelTask]() {
         callback->onCurrentProgramInfoChanged(programInfo);
+        mCurrentProgramInfo = programInfo;
         auto audioAcquiredTask = [this, callback, programInfo]() {
             ProgramInfo hdProgramInfoWithAudio = programInfo;
             hdProgramInfoWithAudio.infoFlags |= ProgramInfo::FLAG_HD_AUDIO_ACQUISITION;
             callback->onCurrentProgramInfoChanged(hdProgramInfoWithAudio);
             lock_guard<mutex> lk(mMutex);
             mIsTuneCompleted = true;
+            mCurrentProgramInfo = hdProgramInfoWithAudio;
         };
         lock_guard<mutex> lk(mMutex);
         mTuningThread->schedule(audioAcquiredTask, cancelTask, kTuneDelayTimeMs);
@@ -481,7 +592,8 @@
     auto cancelTask = [callback]() { callback->onTuneFailed(Result::CANCELED, {}); };
 
     VirtualProgram nextProgram = {};
-    bool foundNext = findNextLocked(mCurrentProgram, directionUp, skipSubChannel, &nextProgram);
+    bool foundNext =
+            findNextLocked(mCurrentProgramSelector, directionUp, skipSubChannel, &nextProgram);
     mIsTuneCompleted = false;
     if (!foundNext) {
         auto task = [callback]() {
@@ -520,10 +632,10 @@
     cancelLocked();
 
     int64_t stepTo;
-    if (utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ)) {
-        stepTo = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY_KHZ);
-    } else if (mCurrentProgram.primaryId.type == IdentifierType::HD_STATION_ID_EXT) {
-        stepTo = utils::getHdFrequency(mCurrentProgram);
+    if (utils::hasId(mCurrentProgramSelector, IdentifierType::AMFM_FREQUENCY_KHZ)) {
+        stepTo = utils::getId(mCurrentProgramSelector, IdentifierType::AMFM_FREQUENCY_KHZ);
+    } else if (mCurrentProgramSelector.primaryId.type == IdentifierType::HD_STATION_ID_EXT) {
+        stepTo = utils::getHdFrequency(mCurrentProgramSelector);
     } else {
         LOG(WARNING) << __func__ << ": can't step in anything else than AM/FM";
         return ScopedAStatus::fromServiceSpecificErrorWithMessage(
@@ -568,7 +680,7 @@
     LOG(DEBUG) << __func__ << ": cancelling current tuning operations...";
 
     mTuningThread->cancelAll();
-    if (mCurrentProgram.primaryId.type != IdentifierType::INVALID) {
+    if (mCurrentProgramSelector.primaryId.type != IdentifierType::INVALID) {
         mIsTuneCompleted = true;
     }
 }
@@ -692,13 +804,13 @@
 
 bool BroadcastRadio::adjustAmFmRangeLocked() {
     bool hasBandBefore = mCurrentAmFmBandRange.has_value();
-    if (!utils::hasAmFmFrequency(mCurrentProgram)) {
+    if (!utils::hasAmFmFrequency(mCurrentProgramSelector)) {
         LOG(WARNING) << __func__ << ": current program does not has AMFM_FREQUENCY_KHZ identifier";
         mCurrentAmFmBandRange.reset();
         return hasBandBefore;
     }
 
-    int32_t freq = static_cast<int32_t>(utils::getAmFmFrequency(mCurrentProgram));
+    int32_t freq = static_cast<int32_t>(utils::getAmFmFrequency(mCurrentProgramSelector));
     for (const auto& range : mAmFmConfig.ranges) {
         if (range.lowerBound <= freq && range.upperBound >= freq) {
             bool isBandChanged = hasBandBefore ? *mCurrentAmFmBandRange != range : true;
@@ -711,6 +823,24 @@
     return !hasBandBefore;
 }
 
+void BroadcastRadio::updateCurrentProgramInfoWithAlert(std::optional<Alert>& alert) {
+    std::shared_ptr<ITunerCallback> callback;
+    ProgramInfo currentProgramInfo;
+    {
+        lock_guard<mutex> lk(mMutex);
+        if (mCallback == nullptr) {
+            return;
+        }
+        if (mCurrentProgramInfo.selector.primaryId.type == IdentifierType::INVALID) {
+            return;
+        }
+        callback = mCallback;
+        currentProgramInfo = mCurrentProgramInfo;
+    }
+    currentProgramInfo.emergencyAlert = alert.value();
+    callback->onCurrentProgramInfoChanged(currentProgramInfo);
+}
+
 ScopedAStatus BroadcastRadio::registerAnnouncementListener(
         [[maybe_unused]] const std::shared_ptr<IAnnouncementListener>& listener,
         const vector<AnnouncementType>& enabled, std::shared_ptr<ICloseHandle>* returnCloseHandle) {
@@ -745,6 +875,8 @@
         return cmdStartProgramListUpdates(fd, args, numArgs);
     } else if (EqualsIgnoreCase(option, "--stopProgramListUpdates")) {
         return cmdStopProgramListUpdates(fd, numArgs);
+    } else if (EqualsIgnoreCase(option, "--simulateAlert")) {
+        return cmdSimulateAlert(fd, args, numArgs);
     }
     dprintf(fd, "Invalid option: %s\n", option.c_str());
     return STATUS_BAD_VALUE;
@@ -767,7 +899,7 @@
     } else {
         dprintf(fd, "ITunerCallback registered\n");
     }
-    dprintf(fd, "CurrentProgram: %s \n", mCurrentProgram.toString().c_str());
+    dprintf(fd, "CurrentProgram: %s \n", mCurrentProgramSelector.toString().c_str());
     return STATUS_OK;
 }
 
@@ -798,13 +930,41 @@
             "excludeModifications (string, should be either \"true\" or \"false\")\n");
     dprintf(fd, "--stopProgramListUpdates: stop current pending program list updates\n");
     dprintf(fd,
-            "Note on <TYPE> for --startProgramList command: it is int for identifier type. "
+            "\t<TYPE>: it is int for identifier type. "
             "Please see broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl "
             "for its definition.\n");
     dprintf(fd,
-            "Note on <VALUE> for --startProgramList command: it is long type for identifier value. "
+            "\t<VALUE>: it is long type for identifier value. "
             "Please see broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl "
             "for its value.\n");
+    dprintf(fd,
+            "--simulateAlert <STATUS> <MESSAGE_TYPE> <CATEGORIES> <URGENCY> <SEVERITY> "
+            "<CERTAINTY> <DESCRIPTION> <LANGUAGE> <AREAS>: simulate emergency alert on current "
+            "program; if no arguments following \"--simulateAlert\", the default alert message"
+            "is applied.\n");
+    dprintf(fd, "\t<STATUS>: string representation of alert scope.\n");
+    dprintf(fd, "\t<MESSAGE_TYPE>: string representation of alert message type.\n");
+    dprintf(fd,
+            "\t<CATEGORIES>: string representation of alert categories separated by "
+            "\",\".\n");
+    dprintf(fd, "\t<URGENCY>: string representation of alert urgency type.\n");
+    dprintf(fd, "\t<SEVERITY>: string representation of alert severity type.\n");
+    dprintf(fd, "\t<CERTAINTY>: string representation of alert certainty type.\n");
+    dprintf(fd, "\t<DESCRIPTION>: description of alert message within quotation mark(\"\").\n");
+    dprintf(fd, "\t<LANGUAGE>: language code of alert message, \"null\" if unspecified.\n");
+    dprintf(fd,
+            "\t<AREAS>: <TYPE>:<VALUE>_<TYPE>:<VALUE>_...+<TYPE>:<VALUE>_<TYPE>:<VALUE>_... "
+            "which represents list of affected areas of the alert separated by \"|\". "
+            "If no area, this field should be: |\n"
+            "Each area may contains multiple entries separated by \";\" where "
+            "<TYPE> can be either \"polygon\" or \"geocode\". If <TYPE> is polygon, <VALUE> is a "
+            "series of coordinates of \"LATITUDE,LONGITUDE\" format separated by \",\"; if "
+            "<TYPE> is geocode, <VALUE> is of \"VALUE_NAME,VALUE\" format.\n");
+    dprintf(fd,
+            "Example: --simulateAlert actual alert geo,transport future severe"
+            " possible \"alert message for testing\" en-US geocode:SAME,006109_geocode:SAME,006209"
+            "_polygon:-38.47,-120.14,38.34,-119.95,38.52,-119.74,38.62,-119.89,-38.47,-120.14"
+            "+geocode:SAME,006009\n");
 
     return STATUS_OK;
 }
@@ -1038,4 +1198,71 @@
     return STATUS_OK;
 }
 
+binder_status_t BroadcastRadio::cmdSimulateAlert(int fd, const char** args, uint32_t numArgs) {
+    if (!checkDumpCallerHasWritePermissions(fd)) {
+        return STATUS_PERMISSION_DENIED;
+    }
+    std::optional<Alert> alertOpt;
+    if (numArgs == 1) {
+        alertOpt.emplace(createSampleAlert());
+        updateCurrentProgramInfoWithAlert(alertOpt);
+        return STATUS_OK;
+    }
+    if (numArgs != 10) {
+        dprintf(fd,
+                "Invalid number of arguments: please provide --simulateAlert "
+                "<STATUS> <MESSAGE_TYPE> <CATEGORIES> <URGENCY> "
+                "<SEVERITY> <CERTAINTY> <DESCRIPTION> <LANGUAGE> <AREAS>, provided: %d\n",
+                numArgs);
+        return STATUS_BAD_VALUE;
+    }
+    Alert parsedAlert;
+    if (!utils::parseAlertStatus(args[1], parsedAlert.status)) {
+        dprintf(fd, "Unknown alert status type: %s\n", args[2]);
+        return STATUS_BAD_VALUE;
+    }
+    if (!utils::parseAlertMessageType(args[2], parsedAlert.messageType)) {
+        dprintf(fd, "Unknown alert message type: %s\n", args[3]);
+        return STATUS_BAD_VALUE;
+    }
+    AlertInfo parsedAlertInfo;
+    vector<string> categoryStrings = ::android::base::Split(args[3], ",");
+    for (const auto& categoryString : categoryStrings) {
+        AlertCategory category;
+        if (!utils::parseAlertCategory(categoryString, category)) {
+            dprintf(fd, "Unknown alert category type: %s\n", args[3]);
+            return STATUS_BAD_VALUE;
+        }
+        parsedAlertInfo.categoryArray.push_back(category);
+    }
+    if (!utils::parseAlertUrgency(args[4], parsedAlertInfo.urgency)) {
+        dprintf(fd, "Unknown alert urgency type: %s\n", args[4]);
+        return STATUS_BAD_VALUE;
+    }
+    if (!utils::parseAlertSeverity(args[5], parsedAlertInfo.severity)) {
+        dprintf(fd, "Unknown alert severity type: %s\n", args[5]);
+        return STATUS_BAD_VALUE;
+    }
+    if (!utils::parseAlertCertainty(args[6], parsedAlertInfo.certainty)) {
+        dprintf(fd, "Unknown alert certainty type: %s\n", args[6]);
+        return STATUS_BAD_VALUE;
+    }
+    parsedAlertInfo.description = string(args[7]);
+    string languageStr = string(args[8]);
+    if (!EqualsIgnoreCase(languageStr, "null")) {
+        parsedAlertInfo.language.emplace(languageStr);
+    }
+    string areaListString = string(args[9]);
+    vector<AlertArea> areaList;
+    if (!parseAreaListString(fd, areaListString, areaList)) {
+        return STATUS_BAD_VALUE;
+    }
+    parsedAlertInfo.areas = areaList;
+    parsedAlert.infoArray = {parsedAlertInfo};
+    LOG(INFO) << "Simulate alert: " << parsedAlert.toString().c_str();
+    alertOpt.emplace(parsedAlert);
+    updateCurrentProgramInfoWithAlert(alertOpt);
+    return STATUS_OK;
+}
+
 }  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/aidl/default/BroadcastRadio.h b/broadcastradio/aidl/default/BroadcastRadio.h
index 60ea907..a4cba3b 100644
--- a/broadcastradio/aidl/default/BroadcastRadio.h
+++ b/broadcastradio/aidl/default/BroadcastRadio.h
@@ -78,7 +78,8 @@
             std::unique_ptr<::android::WorkerThread>(new ::android::WorkerThread());
     bool mIsTuneCompleted GUARDED_BY(mMutex) = true;
     Properties mProperties GUARDED_BY(mMutex);
-    ProgramSelector mCurrentProgram GUARDED_BY(mMutex) = {};
+    ProgramSelector mCurrentProgramSelector GUARDED_BY(mMutex) = {};
+    ProgramInfo mCurrentProgramInfo GUARDED_BY(mMutex) = {};
     std::vector<VirtualProgram> mProgramList GUARDED_BY(mMutex) = {};
     std::optional<AmFmBandRange> mCurrentAmFmBandRange GUARDED_BY(mMutex);
     std::shared_ptr<ITunerCallback> mCallback GUARDED_BY(mMutex);
@@ -99,6 +100,7 @@
     void jumpToFirstSubChannelLocked(std::vector<VirtualProgram>::const_iterator& it) const
             REQUIRES(mMutex);
     bool isConfigFlagSetLocked(ConfigFlag flag) const REQUIRES(mMutex);
+    void updateCurrentProgramInfoWithAlert(std::optional<Alert>& alert);
 
     binder_status_t cmdHelp(int fd) const;
     binder_status_t cmdTune(int fd, const char** args, uint32_t numArgs);
@@ -107,6 +109,7 @@
     binder_status_t cmdCancel(int fd, uint32_t numArgs);
     binder_status_t cmdStartProgramListUpdates(int fd, const char** args, uint32_t numArgs);
     binder_status_t cmdStopProgramListUpdates(int fd, uint32_t numArgs);
+    binder_status_t cmdSimulateAlert(int fd, const char** args, uint32_t numArgs);
 
     binder_status_t dumpsys(int fd) EXCLUDES(mMutex);
 };
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index ee0c639..1427744 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -16,6 +16,7 @@
 
 #define EGMOCK_VERBOSE 1
 
+#include <aidl/android/hardware/broadcastradio/Alert.h>
 #include <aidl/android/hardware/broadcastradio/BnAnnouncementListener.h>
 #include <aidl/android/hardware/broadcastradio/BnTunerCallback.h>
 #include <aidl/android/hardware/broadcastradio/ConfigFlag.h>
@@ -76,12 +77,13 @@
 
 constexpr int32_t kAidlVersion1 = 1;
 constexpr int32_t kAidlVersion2 = 2;
+constexpr int32_t kAidlVersion3 = 3;
 
 bool isValidAmFmFreq(int64_t freq, int aidlVersion) {
     ProgramIdentifier id = bcutils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, freq);
     if (aidlVersion == kAidlVersion1) {
         return bcutils::isValid(id);
-    } else if (aidlVersion == kAidlVersion2) {
+    } else if (aidlVersion >= kAidlVersion2) {
         return bcutils::isValidV2(id);
     }
     LOG(ERROR) << "Unknown AIDL version " << aidlVersion;
@@ -105,6 +107,41 @@
     return false;
 }
 
+void validateMetadata(const ProgramInfo& info, int32_t aidlVersion) {
+    for (const auto& metadataItem : info.metadata) {
+        bool validMetadata = false;
+        if (aidlVersion == kAidlVersion1) {
+            validMetadata = bcutils::isValidMetadata(metadataItem);
+        } else {
+            validMetadata = bcutils::isValidMetadataV2(metadataItem);
+        }
+        EXPECT_TRUE(validMetadata) << "Invalid metadata " << metadataItem.toString().c_str();
+    }
+}
+
+void validateAlert(const ProgramInfo& info, int32_t aidlVersion) {
+    if (aidlVersion < kAidlVersion3 || !info.emergencyAlert.has_value()) {
+        return;
+    }
+    Alert alert = info.emergencyAlert.value();
+    ASSERT_FALSE(alert.infoArray.empty());
+    for (const auto& alertInfo : alert.infoArray) {
+        ASSERT_FALSE(alertInfo.categoryArray.empty());
+        if (alertInfo.areas.empty()) {
+            continue;
+        }
+        for (const auto& area : alertInfo.areas) {
+            if (area.polygons.empty()) {
+                continue;
+            }
+            for (const auto& polygon : area.polygons) {
+                ASSERT_GE(polygon.coordinates.size(), 4);
+                EXPECT_EQ(polygon.coordinates.front(), polygon.coordinates.back());
+            }
+        }
+    }
+}
+
 }  // namespace
 
 class CallbackFlag final {
@@ -250,15 +287,9 @@
         }
     }
 
-    for (const auto& metadataItem : info.metadata) {
-        bool validMetadata = false;
-        if (mCallbackAidlVersion == kAidlVersion1) {
-            validMetadata = bcutils::isValidMetadata(metadataItem);
-        } else {
-            validMetadata = bcutils::isValidMetadataV2(metadataItem);
-        }
-        EXPECT_TRUE(validMetadata) << "Invalid metadata " << metadataItem.toString().c_str();
-    }
+    validateMetadata(info, mCallbackAidlVersion);
+
+    validateAlert(info, mCallbackAidlVersion);
 
     {
         std::lock_guard<std::mutex> lk(mLock);
@@ -349,7 +380,7 @@
     // get AIDL HAL version
     ASSERT_TRUE(mModule->getInterfaceVersion(&mAidlVersion).isOk());
     EXPECT_GE(mAidlVersion, kAidlVersion1);
-    EXPECT_LE(mAidlVersion, kAidlVersion2);
+    EXPECT_LE(mAidlVersion, kAidlVersion3);
 
     // set callback
     mCallback = SharedRefBase::make<TunerCallbackImpl>(mAidlVersion);
@@ -736,6 +767,7 @@
     }
 
     // try tuning
+    mCallback->reset();
     auto result = mModule->tune(hdSel);
 
     // expect a failure if it's not supported
@@ -812,7 +844,7 @@
     }
 
     // try tuning
-
+    mCallback->reset();
     auto result = mModule->tune(sel);
 
     // expect a failure if it's not supported
@@ -1122,12 +1154,22 @@
  * Verifies that:
  * - startProgramListUpdates either succeeds or returns NOT_SUPPORTED;
  * - the complete list is fetched within kProgramListScanTimeoutMs;
- * - stopProgramListUpdates does not crash.
+ * - stopProgramListUpdates does not crash;
+ * - metadata of program info in the program list is valid;
+ * - alert message is valid if it exists in the program list.
  */
 TEST_P(BroadcastRadioHalTest, GetProgramListFromEmptyFilter) {
     LOG(DEBUG) << "GetProgramListFromEmptyFilter Test";
 
-    getProgramList();
+    std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
+
+    if (!completeList || mAidlVersion < kAidlVersion3) {
+        return;
+    }
+    for (const auto& program : *completeList) {
+        validateMetadata(program, mAidlVersion);
+        validateAlert(program, mAidlVersion);
+    }
 }
 
 /**
diff --git a/broadcastradio/common/utilsaidl/Android.bp b/broadcastradio/common/utilsaidl/Android.bp
index d88081f..2245492 100644
--- a/broadcastradio/common/utilsaidl/Android.bp
+++ b/broadcastradio/common/utilsaidl/Android.bp
@@ -24,7 +24,7 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-cc_library_static {
+cc_library {
     name: "android.hardware.broadcastradio@common-utils-aidl-lib",
     defaults: [
         "BroadcastRadioUtilsDefaults",
@@ -34,7 +34,7 @@
     ],
 }
 
-cc_library_static {
+cc_library {
     name: "android.hardware.broadcastradio@common-utils-aidl-lib-V2",
     defaults: [
         "BroadcastRadioUtilsDefaults",
@@ -47,7 +47,21 @@
     ],
 }
 
-cc_library_static {
+cc_library {
+    name: "android.hardware.broadcastradio@common-utils-aidl-lib-V3",
+    defaults: [
+        "BroadcastRadioUtilsDefaults",
+    ],
+    srcs: [
+        "src/UtilsV2.cpp",
+        "src/UtilsV3.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.broadcastradio-V3-ndk",
+    ],
+}
+
+cc_library {
     name: "android.hardware.broadcastradio@common-utils-aidl-lib-latest",
     defaults: [
         "BroadcastRadioUtilsDefaults",
@@ -55,6 +69,7 @@
     ],
     srcs: [
         "src/UtilsV2.cpp",
+        "src/UtilsV3.cpp",
     ],
 }
 
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index a34ee10..f5b71b2 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -197,6 +197,8 @@
 
 bool parseArgLong(const std::string& s, long* out);
 
+bool parseArgDouble(const std::string& s, double* out);
+
 bool parseArgBool(const std::string& s, bool* out);
 
 bool parseArgDirection(const std::string& s, bool* out);
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV3.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV3.h
new file mode 100644
index 0000000..250e217
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/UtilsV3.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/broadcastradio/ProgramInfo.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace utils {
+
+bool parseAlertStatus(const std::string& s, AlertStatus& out);
+
+bool parseAlertMessageType(const std::string& s, AlertMessageType& out);
+
+bool parseAlertCategory(const std::string& s, AlertCategory& out);
+
+bool parseAlertUrgency(const std::string& s, AlertUrgency& out);
+
+bool parseAlertSeverity(const std::string& s, AlertSeverity& out);
+
+bool parseAlertCertainty(const std::string& s, AlertCertainty& out);
+}  // namespace utils
+}  // namespace aidl::android::hardware::broadcastradio
\ No newline at end of file
diff --git a/broadcastradio/common/utilsaidl/src/Utils.cpp b/broadcastradio/common/utilsaidl/src/Utils.cpp
index 3de1866..bfa93a5 100644
--- a/broadcastradio/common/utilsaidl/src/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/src/Utils.cpp
@@ -19,6 +19,7 @@
 #include "broadcastradio-utils-aidl/Utils.h"
 
 #include <android-base/logging.h>
+#include <android-base/parsedouble.h>
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
 
@@ -631,6 +632,10 @@
     return ::android::base::ParseInt(s, out);
 }
 
+bool parseArgDouble(const std::string& s, double* out) {
+    return ::android::base::ParseDouble(s, out);
+}
+
 bool parseArgBool(const std::string& s, bool* out) {
     if (EqualsIgnoreCase(s, "true")) {
         *out = true;
diff --git a/broadcastradio/common/utilsaidl/src/UtilsV3.cpp b/broadcastradio/common/utilsaidl/src/UtilsV3.cpp
new file mode 100644
index 0000000..bf694da
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/src/UtilsV3.cpp
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BcRadioAidlDef.utilsV3"
+
+#include "broadcastradio-utils-aidl/Utils.h"
+
+#include <android-base/strings.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace utils {
+
+namespace {
+
+using ::android::base::EqualsIgnoreCase;
+using ::std::vector;
+}  // namespace
+
+bool parseAlertStatus(const std::string& s, AlertStatus& out) {
+    if (EqualsIgnoreCase(s, toString(AlertStatus::ACTUAL))) {
+        out = AlertStatus::ACTUAL;
+    } else if (EqualsIgnoreCase(s, toString(AlertStatus::EXERCISE))) {
+        out = AlertStatus::EXERCISE;
+    } else if (EqualsIgnoreCase(s, toString(AlertStatus::TEST))) {
+        out = AlertStatus::TEST;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+bool parseAlertMessageType(const std::string& s, AlertMessageType& out) {
+    if (EqualsIgnoreCase(s, toString(AlertMessageType::ALERT))) {
+        out = AlertMessageType::ALERT;
+    } else if (EqualsIgnoreCase(s, toString(AlertMessageType::UPDATE))) {
+        out = AlertMessageType::UPDATE;
+    } else if (EqualsIgnoreCase(s, toString(AlertMessageType::CANCEL))) {
+        out = AlertMessageType::CANCEL;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+bool parseAlertCategory(const std::string& s, AlertCategory& out) {
+    if (EqualsIgnoreCase(s, toString(AlertCategory::GEO))) {
+        out = AlertCategory::GEO;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::MET))) {
+        out = AlertCategory::MET;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::SAFETY))) {
+        out = AlertCategory::SAFETY;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::SECURITY))) {
+        out = AlertCategory::SECURITY;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::RESCUE))) {
+        out = AlertCategory::RESCUE;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::FIRE))) {
+        out = AlertCategory::FIRE;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::HEALTH))) {
+        out = AlertCategory::HEALTH;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::ENV))) {
+        out = AlertCategory::ENV;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::TRANSPORT))) {
+        out = AlertCategory::TRANSPORT;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::INFRA))) {
+        out = AlertCategory::INFRA;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::CBRNE))) {
+        out = AlertCategory::CBRNE;
+    } else if (EqualsIgnoreCase(s, toString(AlertCategory::OTHER))) {
+        out = AlertCategory::OTHER;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+bool parseAlertUrgency(const std::string& s, AlertUrgency& out) {
+    if (EqualsIgnoreCase(s, toString(AlertUrgency::IMMEDIATE))) {
+        out = AlertUrgency::IMMEDIATE;
+    } else if (EqualsIgnoreCase(s, toString(AlertUrgency::EXPECTED))) {
+        out = AlertUrgency::EXPECTED;
+    } else if (EqualsIgnoreCase(s, toString(AlertUrgency::FUTURE))) {
+        out = AlertUrgency::FUTURE;
+    } else if (EqualsIgnoreCase(s, toString(AlertUrgency::PAST))) {
+        out = AlertUrgency::PAST;
+    } else if (EqualsIgnoreCase(s, toString(AlertUrgency::UNKNOWN))) {
+        out = AlertUrgency::UNKNOWN;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+bool parseAlertSeverity(const std::string& s, AlertSeverity& out) {
+    if (EqualsIgnoreCase(s, toString(AlertSeverity::EXTREME))) {
+        out = AlertSeverity::EXTREME;
+    } else if (EqualsIgnoreCase(s, toString(AlertSeverity::SEVERE))) {
+        out = AlertSeverity::SEVERE;
+    } else if (EqualsIgnoreCase(s, toString(AlertSeverity::MODERATE))) {
+        out = AlertSeverity::MODERATE;
+    } else if (EqualsIgnoreCase(s, toString(AlertSeverity::MINOR))) {
+        out = AlertSeverity::MINOR;
+    } else if (EqualsIgnoreCase(s, toString(AlertSeverity::UNKNOWN))) {
+        out = AlertSeverity::UNKNOWN;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+bool parseAlertCertainty(const std::string& s, AlertCertainty& out) {
+    if (EqualsIgnoreCase(s, toString(AlertCertainty::OBSERVED))) {
+        out = AlertCertainty::OBSERVED;
+    } else if (EqualsIgnoreCase(s, toString(AlertCertainty::LIKELY))) {
+        out = AlertCertainty::LIKELY;
+    } else if (EqualsIgnoreCase(s, toString(AlertCertainty::POSSIBLE))) {
+        out = AlertCertainty::POSSIBLE;
+    } else if (EqualsIgnoreCase(s, toString(AlertCertainty::UNLIKELY))) {
+        out = AlertCertainty::UNLIKELY;
+    } else if (EqualsIgnoreCase(s, toString(AlertCertainty::UNKNOWN))) {
+        out = AlertCertainty::UNKNOWN;
+    } else {
+        return false;
+    }
+    return true;
+}
+
+}  // namespace utils
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/camera/metadata/aidl/Android.bp b/camera/metadata/aidl/Android.bp
index a9c1a1a..d7303fc 100644
--- a/camera/metadata/aidl/Android.bp
+++ b/camera/metadata/aidl/Android.bp
@@ -13,7 +13,7 @@
     host_supported: true,
     vendor_available: true,
     srcs: ["android/hardware/camera/metadata/*.aidl"],
-    frozen: true,
+    frozen: false,
     stability: "vintf",
     backend: {
         cpp: {
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
index 138101b..49243dd 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -72,5 +72,7 @@
   ANDROID_AUTOMOTIVE_LENS,
   ANDROID_EXTENSION,
   ANDROID_JPEGR,
+  ANDROID_SHARED_SESSION,
+  ANDROID_DESKTOP_EFFECTS,
   VENDOR_SECTION = 0x8000,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
index 85eee08..588179f 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -72,5 +72,7 @@
   ANDROID_AUTOMOTIVE_LENS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_AUTOMOTIVE_LENS << 16) /* 2031616 */,
   ANDROID_EXTENSION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_EXTENSION << 16) /* 2097152 */,
   ANDROID_JPEGR_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_JPEGR << 16) /* 2162688 */,
+  ANDROID_SHARED_SESSION_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_SHARED_SESSION << 16) /* 2228224 */,
+  ANDROID_DESKTOP_EFFECTS_START = (android.hardware.camera.metadata.CameraMetadataSection.ANDROID_DESKTOP_EFFECTS << 16) /* 2293760 */,
   VENDOR_SECTION_START = (android.hardware.camera.metadata.CameraMetadataSection.VENDOR_SECTION << 16) /* -2147483648 */,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 9321ec0..c3cb3f7 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -43,6 +43,10 @@
   ANDROID_COLOR_CORRECTION_GAINS,
   ANDROID_COLOR_CORRECTION_ABERRATION_MODE,
   ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+  ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE,
+  ANDROID_COLOR_CORRECTION_COLOR_TINT,
+  ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE,
+  ANDROID_COLOR_CORRECTION_AVAILABLE_MODES,
   ANDROID_CONTROL_AE_ANTIBANDING_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_CONTROL_START /* 65536 */,
   ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION,
   ANDROID_CONTROL_AE_LOCK,
@@ -100,6 +104,8 @@
   ANDROID_CONTROL_AUTOFRAMING_STATE,
   ANDROID_CONTROL_LOW_LIGHT_BOOST_INFO_LUMINANCE_RANGE,
   ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
+  ANDROID_CONTROL_AE_PRIORITY_MODE = 65597,
+  ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES,
   ANDROID_DEMOSAIC_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DEMOSAIC_START /* 131072 */,
   ANDROID_EDGE_MODE = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_EDGE_START /* 196608 */,
   ANDROID_EDGE_STRENGTH,
@@ -343,14 +349,27 @@
   ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
   ANDROID_HEIC_AVAILABLE_HEIC_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
   ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION,
   ANDROID_HEIC_INFO_SUPPORTED = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_HEIC_INFO_START /* 1900544 */,
   ANDROID_HEIC_INFO_MAX_JPEG_APP_SEGMENTS_COUNT,
   ANDROID_AUTOMOTIVE_LOCATION = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_START /* 1966080 */,
   ANDROID_AUTOMOTIVE_LENS_FACING = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START /* 2031616 */,
+  ANDROID_EXTENSION_NIGHT_MODE_INDICATOR = 2097154,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_JPEGR_START /* 2162688 */,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
   ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+  ANDROID_DESKTOP_EFFECTS_CAPABILITIES = android.hardware.camera.metadata.CameraMetadataSectionStart.ANDROID_DESKTOP_EFFECTS_START /* 2293760 */,
+  ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODES,
+  ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE,
+  ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE,
+  ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_STRENGTH,
+  ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
index 2381605..69f0f5f 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ColorCorrectionMode.aidl
@@ -41,4 +41,5 @@
   ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX,
   ANDROID_COLOR_CORRECTION_MODE_FAST,
   ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY,
+  ANDROID_COLOR_CORRECTION_MODE_CCT,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePriorityMode.aidl
similarity index 79%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePriorityMode.aidl
index a5eda52..eac2147 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ControlAePriorityMode.aidl
@@ -12,6 +12,10 @@
  * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -31,9 +35,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ControlAePriorityMode {
+  ANDROID_CONTROL_AE_PRIORITY_MODE_OFF,
+  ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_SENSITIVITY_PRIORITY,
+  ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_EXPOSURE_TIME_PRIORITY,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsBackgroundBlurMode.aidl
similarity index 79%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsBackgroundBlurMode.aidl
index a5eda52..36da888 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsBackgroundBlurMode.aidl
@@ -12,6 +12,10 @@
  * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -31,9 +35,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DesktopEffectsBackgroundBlurMode {
+  ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_OFF,
+  ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_LIGHT,
+  ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_FULL,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsCapabilities.aidl
similarity index 79%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsCapabilities.aidl
index a5eda52..d16ef99 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsCapabilities.aidl
@@ -12,6 +12,10 @@
  * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -31,9 +35,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DesktopEffectsCapabilities {
+  ANDROID_DESKTOP_EFFECTS_CAPABILITIES_BACKGROUND_BLUR,
+  ANDROID_DESKTOP_EFFECTS_CAPABILITIES_FACE_RETOUCH,
+  ANDROID_DESKTOP_EFFECTS_CAPABILITIES_PORTRAIT_RELIGHT,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsFaceRetouchMode.aidl
similarity index 81%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsFaceRetouchMode.aidl
index a5eda52..8004b91 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsFaceRetouchMode.aidl
@@ -12,6 +12,10 @@
  * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -31,9 +35,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DesktopEffectsFaceRetouchMode {
+  ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_OFF,
+  ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_ON,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsPortraitRelightMode.aidl
similarity index 81%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsPortraitRelightMode.aidl
index a5eda52..abd06a7 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/DesktopEffectsPortraitRelightMode.aidl
@@ -12,6 +12,10 @@
  * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -31,9 +35,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum DesktopEffectsPortraitRelightMode {
+  ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_OFF,
+  ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_ON,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
similarity index 80%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
index a5eda52..6cfdc02 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
@@ -12,6 +12,10 @@
  * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -31,9 +35,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum ExtensionNightModeIndicator {
+  ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_UNKNOWN,
+  ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_OFF,
+  ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_ON,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
similarity index 79%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
index a5eda52..339d2fa 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
@@ -12,6 +12,10 @@
  * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -31,9 +35,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum HeicAvailableHeicUltraHdrStreamConfigurations {
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_OUTPUT,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_INPUT,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
similarity index 77%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
index a5eda52..7755069 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
@@ -12,6 +12,10 @@
  * 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.
+ *//*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
  */
 ///////////////////////////////////////////////////////////////////////////////
 // THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
@@ -31,9 +35,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.camera.metadata;
+@Backing(type="int") @VintfStability
+enum HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution {
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+  ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
 }
diff --git a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
index 35dc1a9..11be18e 100644
--- a/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
+++ b/camera/metadata/aidl/aidl_api/android.hardware.camera.metadata/current/android/hardware/camera/metadata/SensorReadoutTimestamp.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * 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.
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
index 73bcc12..b7edaf2 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSection.aidl
@@ -63,5 +63,7 @@
     ANDROID_AUTOMOTIVE_LENS,
     ANDROID_EXTENSION,
     ANDROID_JPEGR,
+    ANDROID_SHARED_SESSION,
+    ANDROID_DESKTOP_EFFECTS,
     VENDOR_SECTION = 0x8000,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
index 75e7915..b36a433 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataSectionStart.aidl
@@ -65,5 +65,7 @@
     ANDROID_AUTOMOTIVE_LENS_START = CameraMetadataSection.ANDROID_AUTOMOTIVE_LENS << 16,
     ANDROID_EXTENSION_START = CameraMetadataSection.ANDROID_EXTENSION << 16,
     ANDROID_JPEGR_START = CameraMetadataSection.ANDROID_JPEGR << 16,
+    ANDROID_SHARED_SESSION_START = CameraMetadataSection.ANDROID_SHARED_SESSION << 16,
+    ANDROID_DESKTOP_EFFECTS_START = CameraMetadataSection.ANDROID_DESKTOP_EFFECTS << 16,
     VENDOR_SECTION_START = CameraMetadataSection.VENDOR_SECTION << 16,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index 236bcaf..8b2ac72 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -70,6 +70,38 @@
      */
     ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
     /**
+     * android.colorCorrection.colorTemperature [dynamic, int32, public]
+     *
+     * <p>Specifies the color temperature for CCT mode in Kelvin
+     * to adjust the white balance of the image.</p>
+     */
+    ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE,
+    /**
+     * android.colorCorrection.colorTint [dynamic, int32, public]
+     *
+     * <p>Specifies the color tint for CCT mode to adjust the white
+     * balance of the image.</p>
+     */
+    ANDROID_COLOR_CORRECTION_COLOR_TINT,
+    /**
+     * android.colorCorrection.colorTemperatureRange [static, int32[], public]
+     *
+     * <p>The range of supported color temperature values for
+     * ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE.</p>
+     *
+     * @see ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE
+     */
+    ANDROID_COLOR_CORRECTION_COLOR_TEMPERATURE_RANGE,
+    /**
+     * android.colorCorrection.availableModes [static, byte[], public]
+     *
+     * <p>List of color correction modes for ANDROID_COLOR_CORRECTION_MODE that are
+     * supported by this camera device.</p>
+     *
+     * @see ANDROID_COLOR_CORRECTION_MODE
+     */
+    ANDROID_COLOR_CORRECTION_AVAILABLE_MODES,
+    /**
      * android.control.aeAntibandingMode [dynamic, enum, public]
      *
      * <p>The desired setting for the camera device's auto-exposure
@@ -502,6 +534,21 @@
      */
     ANDROID_CONTROL_LOW_LIGHT_BOOST_STATE,
     /**
+     * android.control.aePriorityMode [dynamic, enum, public]
+     *
+     * <p>Turn on AE priority mode.</p>
+     */
+    ANDROID_CONTROL_AE_PRIORITY_MODE = 65597,
+    /**
+     * android.control.aeAvailablePriorityModes [static, byte[], public]
+     *
+     * <p>List of auto-exposure priority modes for ANDROID_CONTROL_AE_PRIORITY_MODE
+     * that are supported by this camera device.</p>
+     *
+     * @see ANDROID_CONTROL_AE_PRIORITY_MODE
+     */
+    ANDROID_CONTROL_AE_AVAILABLE_PRIORITY_MODES,
+    /**
      * android.demosaic.mode [controls, enum, system]
      *
      * <p>Controls the quality of the demosaicing
@@ -2346,6 +2393,62 @@
      */
     ANDROID_HEIC_AVAILABLE_HEIC_STALL_DURATIONS_MAXIMUM_RESOLUTION,
     /**
+     * android.heic.availableHeicUltraHdrStreamConfigurations [static, enum[], ndk_public]
+     *
+     * <p>The available HEIC (ISO/IEC 23008-12/24) UltraHDR stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS,
+    /**
+     * android.heic.availableHeicUltraHdrMinFrameDurations [static, int64[], ndk_public]
+     *
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for HEIC UltraHDR output formats.</p>
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS,
+    /**
+     * android.heic.availableHeicUltraHdrStallDurations [static, int64[], ndk_public]
+     *
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for HEIC UltraHDR streams.</p>
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS,
+    /**
+     * android.heic.availableHeicUltraHdrStreamConfigurationsMaximumResolution [static, enum[], ndk_public]
+     *
+     * <p>The available HEIC (ISO/IEC 23008-12/24) UltraHDR stream
+     * configurations that this camera device supports
+     * (i.e. format, width, height, output/input stream) for CaptureRequests where
+     * ANDROID_SENSOR_PIXEL_MODE is set to
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION,
+    /**
+     * android.heic.availableHeicUltraHdrMinFrameDurationsMaximumResolution [static, int64[], ndk_public]
+     *
+     * <p>This lists the minimum frame duration for each
+     * format/size combination for HEIC UltraHDR output formats for CaptureRequests where
+     * ANDROID_SENSOR_PIXEL_MODE is set to
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_MIN_FRAME_DURATIONS_MAXIMUM_RESOLUTION,
+    /**
+     * android.heic.availableHeicUltraHdrStallDurationsMaximumResolution [static, int64[], ndk_public]
+     *
+     * <p>This lists the maximum stall duration for each
+     * output format/size combination for HEIC UltraHDR streams for CaptureRequests where
+     * ANDROID_SENSOR_PIXEL_MODE is set to
+     * <a href="https://developer.android.com/reference/android/hardware/camera2/CameraMetadata.html#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION">CameraMetadata#SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION</a>.</p>
+     *
+     * @see ANDROID_SENSOR_PIXEL_MODE
+     */
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+    /**
      * android.heic.info.supported [static, enum, system]
      *
      * <p>Whether this camera device can support identical set of stream combinations
@@ -2375,6 +2478,13 @@
      */
     ANDROID_AUTOMOTIVE_LENS_FACING = CameraMetadataSectionStart.ANDROID_AUTOMOTIVE_LENS_START,
     /**
+     * android.extension.nightModeIndicator [dynamic, enum, public]
+     *
+     * <p>Indicates when to activate Night Mode Camera Extension for high-quality
+     * still captures in low-light conditions.</p>
+     */
+    ANDROID_EXTENSION_NIGHT_MODE_INDICATOR = 2097154,
+    /**
      * android.jpegr.availableJpegRStreamConfigurations [static, enum[], ndk_public]
      *
      * <p>The available Jpeg/R stream
@@ -2426,4 +2536,50 @@
      * @see ANDROID_SENSOR_PIXEL_MODE
      */
     ANDROID_JPEGR_AVAILABLE_JPEG_R_STALL_DURATIONS_MAXIMUM_RESOLUTION,
+    /**
+     * android.desktopEffects.capabilities [static, enum[], system]
+     *
+     * <p>List of special effects supported by the camera device.</p>
+     */
+    ANDROID_DESKTOP_EFFECTS_CAPABILITIES = CameraMetadataSectionStart.ANDROID_DESKTOP_EFFECTS_START,
+    /**
+     * android.desktopEffects.backgroundBlurModes [static, byte[], system]
+     *
+     * <p>List of background blur modes supported by the camera device. The key will only exist
+     * if BACKGROUND_BLUR is listed by ANDROID_DESKTOP_EFFECTS_CAPABILITIES.</p>
+     *
+     * @see ANDROID_DESKTOP_EFFECTS_CAPABILITIES
+     */
+    ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODES,
+    /**
+     * android.desktopEffects.backgroundBlurMode [controls, enum, system]
+     *
+     * <p>Control how the background should be blurred. Supported modes are listed in
+     * ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODES by the camera device.</p>
+     *
+     * @see ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODES
+     */
+    ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE,
+    /**
+     * android.desktopEffects.faceRetouchMode [controls, enum, system]
+     *
+     * <p>Whether to enable face retouch effect.</p>
+     */
+    ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE,
+    /**
+     * android.desktopEffects.faceRetouchStrength [controls, byte, system]
+     *
+     * <p>Control the strength of face retouch applied to the frames. If
+     * ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE in ON without a faceRetouchStrength,
+     * a default will be set by the camera device.</p>
+     *
+     * @see ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE
+     */
+    ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_STRENGTH,
+    /**
+     * android.desktopEffects.portraitRelightMode [controls, enum, system]
+     *
+     * <p>Whether to enable portrait relighting effect.</p>
+     */
+    ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionMode.aidl
index 2a51bfc..f12b6f6 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionMode.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ColorCorrectionMode.aidl
@@ -33,4 +33,5 @@
     ANDROID_COLOR_CORRECTION_MODE_TRANSFORM_MATRIX,
     ANDROID_COLOR_CORRECTION_MODE_FAST,
     ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY,
+    ANDROID_COLOR_CORRECTION_MODE_CCT,
 }
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePriorityMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePriorityMode.aidl
new file mode 100644
index 0000000..fd4f531
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ControlAePriorityMode.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.control.aePriorityMode enumeration values
+ * @see ANDROID_CONTROL_AE_PRIORITY_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum ControlAePriorityMode {
+    ANDROID_CONTROL_AE_PRIORITY_MODE_OFF,
+    ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_SENSITIVITY_PRIORITY,
+    ANDROID_CONTROL_AE_PRIORITY_MODE_SENSOR_EXPOSURE_TIME_PRIORITY,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsBackgroundBlurMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsBackgroundBlurMode.aidl
new file mode 100644
index 0000000..e8b2180
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsBackgroundBlurMode.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.desktopEffects.backgroundBlurMode enumeration values
+ * @see ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum DesktopEffectsBackgroundBlurMode {
+    ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_OFF,
+    ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_LIGHT,
+    ANDROID_DESKTOP_EFFECTS_BACKGROUND_BLUR_MODE_FULL,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsCapabilities.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsCapabilities.aidl
new file mode 100644
index 0000000..45cb78e
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsCapabilities.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.desktopEffects.capabilities enumeration values
+ * @see ANDROID_DESKTOP_EFFECTS_CAPABILITIES
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum DesktopEffectsCapabilities {
+    ANDROID_DESKTOP_EFFECTS_CAPABILITIES_BACKGROUND_BLUR,
+    ANDROID_DESKTOP_EFFECTS_CAPABILITIES_FACE_RETOUCH,
+    ANDROID_DESKTOP_EFFECTS_CAPABILITIES_PORTRAIT_RELIGHT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsFaceRetouchMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsFaceRetouchMode.aidl
new file mode 100644
index 0000000..d8c8101
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsFaceRetouchMode.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.desktopEffects.faceRetouchMode enumeration values
+ * @see ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum DesktopEffectsFaceRetouchMode {
+    ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_OFF,
+    ANDROID_DESKTOP_EFFECTS_FACE_RETOUCH_MODE_ON,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsPortraitRelightMode.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsPortraitRelightMode.aidl
new file mode 100644
index 0000000..4a1d438
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/DesktopEffectsPortraitRelightMode.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.desktopEffects.portraitRelightMode enumeration values
+ * @see ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum DesktopEffectsPortraitRelightMode {
+    ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_OFF,
+    ANDROID_DESKTOP_EFFECTS_PORTRAIT_RELIGHT_MODE_ON,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
new file mode 100644
index 0000000..3c3bdf5
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/ExtensionNightModeIndicator.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.extension.nightModeIndicator enumeration values
+ * @see ANDROID_EXTENSION_NIGHT_MODE_INDICATOR
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum ExtensionNightModeIndicator {
+    ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_UNKNOWN,
+    ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_OFF,
+    ANDROID_EXTENSION_NIGHT_MODE_INDICATOR_ON,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
new file mode 100644
index 0000000..56761b9
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurations.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.heic.availableHeicUltraHdrStreamConfigurations enumeration values
+ * @see ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum HeicAvailableHeicUltraHdrStreamConfigurations {
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_OUTPUT,
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_INPUT,
+}
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
new file mode 100644
index 0000000..7fb19dc
--- /dev/null
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/*
+ * Autogenerated from camera metadata definitions in
+ * /system/media/camera/docs/metadata_definitions.xml
+ * *** DO NOT EDIT BY HAND ***
+ */
+
+package android.hardware.camera.metadata;
+
+/**
+ * android.heic.availableHeicUltraHdrStreamConfigurationsMaximumResolution enumeration values
+ * @see ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION
+ * See system/media/camera/docs/metadata_definitions.xml for details.
+ */
+@VintfStability
+@Backing(type="int")
+enum HeicAvailableHeicUltraHdrStreamConfigurationsMaximumResolution {
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_OUTPUT,
+    ANDROID_HEIC_AVAILABLE_HEIC_ULTRA_HDR_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION_INPUT,
+}
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index 9fa4df2..ec61eec 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -118,7 +118,8 @@
     ScopedAStatus ret = mProvider->setCallback(cb);
     ASSERT_TRUE(ret.isOk());
     ret = mProvider->setCallback(nullptr);
-    ASSERT_EQ(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT), ret.getServiceSpecificError());
+    ASSERT_TRUE(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT) == ret.getServiceSpecificError() ||
+                EX_NULL_POINTER == ret.getExceptionCode());
 }
 
 // Test if ICameraProvider::getCameraDeviceInterface returns Status::OK and non-null device
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 6ecd451..44af306 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -2590,8 +2590,7 @@
         return ret;
     }
 
-    if (flags::session_hal_buf_manager() &&
-        (bufferManagerType == BufferManagerType::SESSION && interfaceVersion >= 3)) {
+    if (bufferManagerType == BufferManagerType::SESSION && interfaceVersion >= 3) {
         ret = session->configureStreamsV2(config, &aidl_return);
     } else {
         ret = session->configureStreams(config, halStreams);
@@ -2599,12 +2598,11 @@
     if (!ret.isOk()) {
         return ret;
     }
-    if (flags::session_hal_buf_manager() && bufferManagerType == BufferManagerType::SESSION) {
+    if (bufferManagerType == BufferManagerType::SESSION) {
         *halStreams = std::move(aidl_return.halStreams);
     }
     for (const auto& halStream : *halStreams) {
-        if ((flags::session_hal_buf_manager() && bufferManagerType == BufferManagerType::SESSION &&
-             halStream.enableHalBufferManager) ||
+        if ((bufferManagerType == BufferManagerType::SESSION && halStream.enableHalBufferManager) ||
             bufferManagerType == BufferManagerType::HAL) {
             halBufManagedStreamIds->insert(halStream.id);
         }
diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp
index bfd1cd1..940b4af 100644
--- a/camera/provider/aidl/vts/device_cb.cpp
+++ b/camera/provider/aidl/vts/device_cb.cpp
@@ -421,12 +421,19 @@
     }
 
     for (const auto& buffer : results.outputBuffers) {
+        std::unique_lock<std::mutex> l(mLock);
         CameraAidlTest::InFlightRequest::StreamBufferAndTimestamp streamBufferAndTimestamp;
-        auto outstandingBuffers = mUseHalBufManager ? mOutstandingBufferIds :
+        auto& outstandingBuffers = mUseHalBufManager ? mOutstandingBufferIds :
             request->mOutstandingBufferIds;
         auto bufferId = mUseHalBufManager ? buffer.bufferId : results.frameNumber;
-        auto outputBuffer = outstandingBuffers.empty() ? ::android::makeFromAidl(buffer.buffer) :
-            outstandingBuffers[buffer.streamId][bufferId];
+        const native_handle_t *outputBuffer = nullptr;
+        if (outstandingBuffers.empty()) {
+           outputBuffer = ::android::makeFromAidl(buffer.buffer);
+        } else if (outstandingBuffers[buffer.streamId].contains(bufferId)) {
+            outputBuffer = outstandingBuffers[buffer.streamId][bufferId];
+        } else {
+            ALOGV("%s: Invalid bufferId: %" PRId64, __FUNCTION__, bufferId);
+        }
         streamBufferAndTimestamp.buffer = {buffer.streamId,
                                            bufferId,
                                            outputBuffer,
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 8338e13..8d5a50a 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -171,7 +171,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.broadcastradio</name>
-        <version>1-2</version>
+        <version>1-3</version>
         <interface>
             <name>IBroadcastRadio</name>
             <regex-instance>.*</regex-instance>
@@ -233,7 +233,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.gnss</name>
-        <version>2-4</version>
+        <version>2-5</version>
         <interface>
             <name>IGnss</name>
             <instance>default</instance>
@@ -257,7 +257,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.health</name>
-        <version>3</version>
+        <version>3-4</version>
         <interface>
             <name>IHealth</name>
             <instance>default</instance>
@@ -380,7 +380,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.power</name>
-        <version>5</version>
+        <version>5-6</version>
         <interface>
             <name>IPower</name>
             <instance>default</instance>
@@ -543,7 +543,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.sensors</name>
-        <version>2</version>
+        <version>2-3</version>
         <interface>
             <name>ISensors</name>
             <instance>default</instance>
@@ -567,7 +567,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.thermal</name>
-        <version>2</version>
+        <version>3</version>
         <interface>
             <name>IThermal</name>
             <instance>default</instance>
@@ -607,7 +607,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.tv.tuner</name>
-        <version>1-2</version>
+        <version>1-3</version>
         <interface>
             <name>ITuner</name>
             <instance>default</instance>
@@ -615,7 +615,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.tv.input</name>
-        <version>1-2</version>
+        <version>1-3</version>
         <interface>
             <name>ITvInput</name>
             <instance>default</instance>
@@ -671,7 +671,7 @@
     </hal>
     <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.wifi</name>
-        <version>1-2</version>
+        <version>2-3</version>
         <interface>
             <name>IWifi</name>
             <instance>default</instance>
@@ -701,6 +701,14 @@
             <instance>default</instance>
         </interface>
     </hal>
+    <hal format="aidl" optional="true">
+        <name>android.hardware.tv.mediaquality</name>
+        <version>1</version>
+        <interface>
+            <name>IMediaQuality</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
     <!-- The native mapper HAL must exist on the device -->
     <hal format="native">
         <name>mapper</name>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index eec5a75..57e039c 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -140,6 +140,7 @@
             "android.hardware.camera.common@",
             "android.hardware.common@",
             "android.hardware.common.fmq@",
+            "android.hardware.gnss.gnss_assistance@",
             "android.hardware.gnss.measurement_corrections@",
             "android.hardware.gnss.visibility_control@",
             "android.hardware.graphics.common@",
@@ -170,6 +171,7 @@
             "android.hardware.audio.core.sounddose@3",
             // This is only used by a trusty VM
             "android.hardware.security.see.authmgr@1",
+            "android.hardware.security.see.hdcp@1",
 
             // Deprecated HALs.
             "android.hardware.audio.sounddose@3",
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
index 93b8ff5..2646d15 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/IContextHub.aidl
@@ -54,7 +54,7 @@
   void registerEndpoint(in android.hardware.contexthub.EndpointInfo endpoint);
   void unregisterEndpoint(in android.hardware.contexthub.EndpointInfo endpoint);
   void registerEndpointCallback(in android.hardware.contexthub.IEndpointCallback callback);
-  int[] requestSessionIdRange(int size);
+  int[2] requestSessionIdRange(int size);
   void openEndpointSession(int sessionId, in android.hardware.contexthub.EndpointId destination, in android.hardware.contexthub.EndpointId initiator, in @nullable String serviceDescriptor);
   void sendMessageToEndpoint(int sessionId, in android.hardware.contexthub.Message msg);
   void sendMessageDeliveryStatusToEndpoint(int sessionId, in android.hardware.contexthub.MessageDeliveryStatus msgStatus);
diff --git a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Reason.aidl b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Reason.aidl
index a315438..b285337 100644
--- a/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Reason.aidl
+++ b/contexthub/aidl/aidl_api/android.hardware.contexthub/current/android/hardware/contexthub/Reason.aidl
@@ -43,4 +43,5 @@
   ENDPOINT_GONE,
   ENDPOINT_CRASHED,
   HUB_RESET,
+  PERMISSION_DENIED,
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
index 24192a1..eb6d051 100644
--- a/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/IContextHub.aidl
@@ -303,7 +303,7 @@
      * @throws EX_ILLEGAL_ARGUMENT if the size is invalid.
      * @throws EX_SERVICE_SPECIFIC if the id range requested cannot be allocated.
      */
-    int[] requestSessionIdRange(int size);
+    int[2] requestSessionIdRange(int size);
 
     /**
      * Request to open a session for communication between an endpoint previously registered by the
@@ -323,9 +323,6 @@
      *         (nullable). Null indicates a fully custom marshalling scheme. The value should match
      *         a published descriptor for both destination and initiator.
      *
-     * @return An integer identifying the session, the integer can be used to present
-     *         the tuple of (destination, initiator, serviceDescriptor).
-     *
      * @throws EX_ILLEGAL_ARGUMENT if any of the arguments are invalid, or the combination of the
      *         arguments is invalid.
      * @throws EX_SERVICE_SPECIFIC on other errors
diff --git a/contexthub/aidl/android/hardware/contexthub/Reason.aidl b/contexthub/aidl/android/hardware/contexthub/Reason.aidl
index 65d9f8a..8a86f94 100644
--- a/contexthub/aidl/android/hardware/contexthub/Reason.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/Reason.aidl
@@ -63,4 +63,9 @@
      * Hub was reset or is resetting.
      */
     HUB_RESET,
+
+    /**
+     * The caller does not have the required permissions.
+     */
+    PERMISSION_DENIED,
 }
diff --git a/contexthub/aidl/android/hardware/contexthub/Service.aidl b/contexthub/aidl/android/hardware/contexthub/Service.aidl
index fd748c3..e107193 100644
--- a/contexthub/aidl/android/hardware/contexthub/Service.aidl
+++ b/contexthub/aidl/android/hardware/contexthub/Service.aidl
@@ -16,6 +16,17 @@
 
 package android.hardware.contexthub;
 
+/**
+ * Services that are provided by an endpoint.
+ *
+ * To support testing, the following service is defined here:
+ *  1. Test echo service:
+ *     - This service responds to a received message back to the sender with a
+ *       message with identical content as the received message.
+ *     - Format:                Service::RpcFormat::CUSTOM
+ *     - Service descriptor:    android.hardware.contexthub.test.EchoService
+ *     - Major version:         1
+ */
 @VintfStability
 parcelable Service {
     /**
diff --git a/contexthub/aidl/default/Android.bp b/contexthub/aidl/default/Android.bp
index da173f9..c0b147c 100644
--- a/contexthub/aidl/default/Android.bp
+++ b/contexthub/aidl/default/Android.bp
@@ -30,6 +30,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
+        "liblog",
         "android.hardware.contexthub-V4-ndk",
     ],
     export_include_dirs: ["include"],
@@ -51,6 +52,7 @@
     shared_libs: [
         "libbase",
         "libbinder_ndk",
+        "liblog",
         "android.hardware.contexthub-V4-ndk",
     ],
     static_libs: [
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 5713a1b..80c9575 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -15,10 +15,60 @@
  */
 
 #include "contexthub-impl/ContextHub.h"
+#include "aidl/android/hardware/contexthub/IContextHubCallback.h"
+
+#ifndef LOG_TAG
+#define LOG_TAG "CHRE"
+#endif
+
+#include <inttypes.h>
+#include <log/log.h>
+#include <optional>
+#include <thread>
+
+using ::ndk::ScopedAStatus;
 
 namespace aidl::android::hardware::contexthub {
 
-using ::ndk::ScopedAStatus;
+namespace {
+
+constexpr uint64_t kMockVendorHubId = 0x1234567812345678;
+constexpr uint64_t kMockVendorHub2Id = 0x0EADBEEFDEADBEEF;
+
+// Mock endpoints for the default implementation.
+// These endpoints just echo back any messages sent to them.
+constexpr size_t kMockEndpointCount = 4;
+const EndpointInfo kMockEndpointInfos[kMockEndpointCount] = {
+        {
+                .id = {.hubId = kMockVendorHubId, .id = UINT64_C(0x1)},
+                .type = EndpointInfo::EndpointType::GENERIC,
+                .name = "Mock Endpoint 1",
+                .version = 1,
+        },
+        {
+                .id = {.hubId = kMockVendorHubId, .id = UINT64_C(0x2)},
+                .type = EndpointInfo::EndpointType::GENERIC,
+                .name = "Mock Endpoint 2",
+                .version = 2,
+        },
+        {
+                .id = {.hubId = kMockVendorHub2Id, .id = UINT64_C(0x1)},
+                .type = EndpointInfo::EndpointType::GENERIC,
+                .name = "Mock Endpoint 3",
+                .version = 1,
+        },
+        {
+                .id = {.hubId = kMockVendorHub2Id, .id = UINT64_C(0x2)},
+                .type = EndpointInfo::EndpointType::GENERIC,
+                .name = "Mock Endpoint 4",
+                .version = 2,
+        },
+};
+
+//! Mutex used to ensure callbacks are called after the initial function returns.
+std::mutex gCallbackMutex;
+
+}  // anonymous namespace
 
 ScopedAStatus ContextHub::getContextHubs(std::vector<ContextHubInfo>* out_contextHubInfos) {
     ContextHubInfo hub = {};
@@ -112,7 +162,13 @@
     }
 }
 
-ScopedAStatus ContextHub::setTestMode(bool /* enable */) {
+ScopedAStatus ContextHub::setTestMode(bool enable) {
+    if (enable) {
+        std::unique_lock<std::mutex> lock(mEndpointMutex);
+        mEndpoints.clear();
+        mEndpointSessions.clear();
+        mEndpointCallback = nullptr;
+    }
     return ScopedAStatus::ok();
 }
 
@@ -137,6 +193,10 @@
 }
 
 ScopedAStatus ContextHub::getHubs(std::vector<HubInfo>* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
     ContextHubInfo hub = {};
     hub.name = "Mock Context Hub";
     hub.vendor = "AOSP";
@@ -158,61 +218,232 @@
     vendorHub.version = 42;
 
     HubInfo hubInfo2 = {};
-    hubInfo1.hubId = UINT64_C(0x1234567812345678);
-    hubInfo1.hubDetails =
+    hubInfo2.hubId = kMockVendorHubId;
+    hubInfo2.hubDetails =
             HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub);
 
+    VendorHubInfo vendorHub2 = {};
+    vendorHub2.name = "Mock Vendor Hub 2";
+    vendorHub2.version = 24;
+
+    HubInfo hubInfo3 = {};
+    hubInfo3.hubId = kMockVendorHub2Id;
+    hubInfo3.hubDetails =
+            HubInfo::HubDetails::make<HubInfo::HubDetails::Tag::vendorHubInfo>(vendorHub2);
+
     _aidl_return->push_back(hubInfo1);
     _aidl_return->push_back(hubInfo2);
+    _aidl_return->push_back(hubInfo3);
 
     return ScopedAStatus::ok();
 };
 
-ScopedAStatus ContextHub::getEndpoints(std::vector<EndpointInfo>* /* _aidl_return */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ScopedAStatus ContextHub::getEndpoints(std::vector<EndpointInfo>* _aidl_return) {
+    if (_aidl_return == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    Service echoService;
+    echoService.format = Service::RpcFormat::CUSTOM;
+    echoService.serviceDescriptor = "android.hardware.contexthub.test.EchoService";
+    echoService.majorVersion = 1;
+    echoService.minorVersion = 0;
+
+    for (const EndpointInfo& endpoint : kMockEndpointInfos) {
+        EndpointInfo endpointWithService(endpoint);
+        endpointWithService.services.push_back(echoService);
+        _aidl_return->push_back(std::move(endpointWithService));
+    }
+
+    return ScopedAStatus::ok();
 };
 
-ScopedAStatus ContextHub::registerEndpoint(const EndpointInfo& /* in_endpoint */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ScopedAStatus ContextHub::registerEndpoint(const EndpointInfo& in_endpoint) {
+    std::unique_lock<std::mutex> lock(mEndpointMutex);
+
+    for (const EndpointInfo& endpoint : mEndpoints) {
+        if ((endpoint.id.id == in_endpoint.id.id && endpoint.id.hubId == in_endpoint.id.hubId) ||
+            endpoint.name == in_endpoint.name) {
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+    }
+    mEndpoints.push_back(in_endpoint);
+    return ScopedAStatus::ok();
 };
 
-ScopedAStatus ContextHub::unregisterEndpoint(const EndpointInfo& /* in_endpoint */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ScopedAStatus ContextHub::unregisterEndpoint(const EndpointInfo& in_endpoint) {
+    std::unique_lock<std::mutex> lock(mEndpointMutex);
+
+    for (auto it = mEndpoints.begin(); it != mEndpoints.end(); ++it) {
+        if (it->id.id == in_endpoint.id.id && it->id.hubId == in_endpoint.id.hubId) {
+            mEndpoints.erase(it);
+            return ScopedAStatus::ok();
+        }
+    }
+    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
 };
 
 ScopedAStatus ContextHub::registerEndpointCallback(
-        const std::shared_ptr<IEndpointCallback>& /* in_callback */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+        const std::shared_ptr<IEndpointCallback>& in_callback) {
+    std::unique_lock<std::mutex> lock(mEndpointMutex);
+
+    mEndpointCallback = in_callback;
+    return ScopedAStatus::ok();
 };
 
-ScopedAStatus ContextHub::requestSessionIdRange(int32_t /* in_size */,
-                                                std::vector<int32_t>* /* _aidl_return */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ScopedAStatus ContextHub::requestSessionIdRange(int32_t in_size,
+                                                std::array<int32_t, 2>* _aidl_return) {
+    constexpr int32_t kMaxSize = 1024;
+    if (in_size > kMaxSize || _aidl_return == nullptr) {
+        return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+
+    {
+        std::lock_guard<std::mutex> lock(mEndpointMutex);
+        mMaxValidSessionId = in_size;
+    }
+
+    (*_aidl_return)[0] = 0;
+    (*_aidl_return)[1] = in_size;
+    return ScopedAStatus::ok();
 };
 
 ScopedAStatus ContextHub::openEndpointSession(
-        int32_t /* in_sessionId */, const EndpointId& /* in_destination */,
-        const EndpointId& /* in_initiator */,
-        const std::optional<std::string>& /* in_serviceDescriptor */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+        int32_t in_sessionId, const EndpointId& in_destination, const EndpointId& in_initiator,
+        const std::optional<std::string>& in_serviceDescriptor) {
+    // We are not calling onCloseEndpointSession on failure because the remote endpoints (our
+    // mock endpoints) always accept the session.
+
+    std::weak_ptr<IEndpointCallback> callback;
+    {
+        std::unique_lock<std::mutex> lock(mEndpointMutex);
+        if (in_sessionId > mMaxValidSessionId) {
+            ALOGE("openEndpointSession: session ID %" PRId32 " is invalid", in_sessionId);
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+
+        for (const EndpointSession& session : mEndpointSessions) {
+            bool sessionAlreadyExists =
+                    (session.initiator == in_destination && session.peer == in_initiator) ||
+                    (session.peer == in_destination && session.initiator == in_initiator);
+            if (sessionAlreadyExists) {
+                ALOGD("openEndpointSession: session ID %" PRId32 " already exists", in_sessionId);
+                return (session.sessionId == in_sessionId &&
+                        session.serviceDescriptor == in_serviceDescriptor)
+                               ? ScopedAStatus::ok()
+                               : ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+            } else if (session.sessionId == in_sessionId) {
+                ALOGE("openEndpointSession: session ID %" PRId32 " is invalid: endpoint mismatch",
+                      in_sessionId);
+                return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+            }
+        }
+
+        // Verify the initiator and destination are valid endpoints
+        bool initiatorIsValid = findEndpoint(in_initiator, mEndpoints.begin(), mEndpoints.end());
+        if (!initiatorIsValid) {
+            ALOGE("openEndpointSession: initiator %" PRIu64 ":%" PRIu64 " is invalid",
+                  in_initiator.id, in_initiator.hubId);
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+        bool destinationIsValid = findEndpoint(in_destination, &kMockEndpointInfos[0],
+                                               &kMockEndpointInfos[kMockEndpointCount]);
+        if (!destinationIsValid) {
+            ALOGE("openEndpointSession: destination %" PRIu64 ":%" PRIu64 " is invalid",
+                  in_destination.id, in_destination.hubId);
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+
+        mEndpointSessions.push_back({
+                .sessionId = in_sessionId,
+                .initiator = in_initiator,
+                .peer = in_destination,
+                .serviceDescriptor = in_serviceDescriptor,
+        });
+
+        if (mEndpointCallback == nullptr) {
+            return ScopedAStatus::ok();
+        }
+        callback = mEndpointCallback;
+    }
+
+    std::unique_lock<std::mutex> lock(gCallbackMutex);
+    std::thread{[callback, in_sessionId]() {
+        std::unique_lock<std::mutex> lock(gCallbackMutex);
+        if (auto cb = callback.lock(); cb != nullptr) {
+            cb->onEndpointSessionOpenComplete(in_sessionId);
+        }
+    }}.detach();
+    return ScopedAStatus::ok();
 };
 
-ScopedAStatus ContextHub::sendMessageToEndpoint(int32_t /* in_sessionId */,
-                                                const Message& /* in_msg */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ScopedAStatus ContextHub::sendMessageToEndpoint(int32_t in_sessionId, const Message& in_msg) {
+    std::weak_ptr<IEndpointCallback> callback;
+    {
+        std::unique_lock<std::mutex> lock(mEndpointMutex);
+        bool foundSession = false;
+        for (const EndpointSession& session : mEndpointSessions) {
+            if (session.sessionId == in_sessionId) {
+                foundSession = true;
+                break;
+            }
+        }
+
+        if (!foundSession) {
+            ALOGE("sendMessageToEndpoint: session ID %" PRId32 " is invalid", in_sessionId);
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        }
+
+        if (mEndpointCallback == nullptr) {
+            return ScopedAStatus::ok();
+        }
+        callback = mEndpointCallback;
+    }
+
+    std::unique_lock<std::mutex> lock(gCallbackMutex);
+    if ((in_msg.flags & Message::FLAG_REQUIRES_DELIVERY_STATUS) != 0) {
+        MessageDeliveryStatus msgStatus = {};
+        msgStatus.messageSequenceNumber = in_msg.sequenceNumber;
+        msgStatus.errorCode = ErrorCode::OK;
+
+        std::thread{[callback, in_sessionId, msgStatus]() {
+            std::unique_lock<std::mutex> lock(gCallbackMutex);
+            if (auto cb = callback.lock(); cb != nullptr) {
+                cb->onMessageDeliveryStatusReceived(in_sessionId, msgStatus);
+            }
+        }}.detach();
+    }
+
+    // Echo the message back
+    std::thread{[callback, in_sessionId, in_msg]() {
+        std::unique_lock<std::mutex> lock(gCallbackMutex);
+        if (auto cb = callback.lock(); cb != nullptr) {
+            cb->onMessageReceived(in_sessionId, in_msg);
+        }
+    }}.detach();
+    return ScopedAStatus::ok();
 };
 
 ScopedAStatus ContextHub::sendMessageDeliveryStatusToEndpoint(
         int32_t /* in_sessionId */, const MessageDeliveryStatus& /* in_msgStatus */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    return ScopedAStatus::ok();
 };
 
-ScopedAStatus ContextHub::closeEndpointSession(int32_t /* in_sessionId */, Reason /* in_reason */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ScopedAStatus ContextHub::closeEndpointSession(int32_t in_sessionId, Reason /* in_reason */) {
+    std::unique_lock<std::mutex> lock(mEndpointMutex);
+
+    for (auto it = mEndpointSessions.begin(); it != mEndpointSessions.end(); ++it) {
+        if (it->sessionId == in_sessionId) {
+            mEndpointSessions.erase(it);
+            return ScopedAStatus::ok();
+        }
+    }
+    ALOGE("closeEndpointSession: session ID %" PRId32 " is invalid", in_sessionId);
+    return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
 };
 
 ScopedAStatus ContextHub::endpointSessionOpenComplete(int32_t /* in_sessionId */) {
-    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    return ScopedAStatus::ok();
 };
 
 }  // namespace aidl::android::hardware::contexthub
diff --git a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
index 5680a77..6da8bf2 100644
--- a/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
+++ b/contexthub/aidl/default/include/contexthub-impl/ContextHub.h
@@ -18,6 +18,7 @@
 
 #include <aidl/android/hardware/contexthub/BnContextHub.h>
 
+#include <mutex>
 #include <unordered_set>
 #include <vector>
 
@@ -60,7 +61,7 @@
     ::ndk::ScopedAStatus registerEndpointCallback(
             const std::shared_ptr<IEndpointCallback>& in_callback) override;
     ::ndk::ScopedAStatus requestSessionIdRange(int32_t in_size,
-                                               std::vector<int32_t>* _aidl_return) override;
+                                               std::array<int32_t, 2>* _aidl_return) override;
     ::ndk::ScopedAStatus openEndpointSession(
             int32_t in_sessionId, const EndpointId& in_destination, const EndpointId& in_initiator,
             const std::optional<std::string>& in_serviceDescriptor) override;
@@ -72,10 +73,37 @@
     ::ndk::ScopedAStatus endpointSessionOpenComplete(int32_t in_sessionId) override;
 
   private:
+    struct EndpointSession {
+        int32_t sessionId;
+        EndpointId initiator;
+        EndpointId peer;
+        std::optional<std::string> serviceDescriptor;
+    };
+
     static constexpr uint32_t kMockHubId = 0;
+
+    //! Finds an endpoint in the range defined by the endpoints
+    //! @return whether the endpoint was found
+    template <typename Iter>
+    bool findEndpoint(const EndpointId& target, const Iter& begin, const Iter& end) {
+        for (auto iter = begin; iter != end; ++iter) {
+            if (iter->id.id == target.id && iter->id.hubId == target.hubId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     std::shared_ptr<IContextHubCallback> mCallback;
 
     std::unordered_set<char16_t> mConnectedHostEndpoints;
+
+    //! Endpoint storage and information
+    std::mutex mEndpointMutex;
+    std::vector<EndpointInfo> mEndpoints;
+    std::vector<EndpointSession> mEndpointSessions;
+    std::shared_ptr<IEndpointCallback> mEndpointCallback;
+    int32_t mMaxValidSessionId = 0;
 };
 
 }  // namespace contexthub
diff --git a/contexthub/aidl/vts/Android.bp b/contexthub/aidl/vts/Android.bp
index 62a319e..a19b6fd 100644
--- a/contexthub/aidl/vts/Android.bp
+++ b/contexthub/aidl/vts/Android.bp
@@ -33,7 +33,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.contexthub-V3-cpp",
+        "android.hardware.contexthub-V4-cpp",
         "VtsHalContexthubUtils",
     ],
     test_suites: [
diff --git a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
index fa427a5..02f0653 100644
--- a/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
+++ b/contexthub/aidl/vts/VtsAidlHalContextHubTargetTest.cpp
@@ -20,8 +20,10 @@
 
 #include <android/hardware/contexthub/BnContextHub.h>
 #include <android/hardware/contexthub/BnContextHubCallback.h>
+#include <android/hardware/contexthub/BnEndpointCallback.h>
 #include <android/hardware/contexthub/IContextHub.h>
 #include <android/hardware/contexthub/IContextHubCallback.h>
+#include <android/hardware/contexthub/IEndpointCallback.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <log/log.h>
@@ -34,18 +36,25 @@
 using ::android::String16;
 using ::android::binder::Status;
 using ::android::hardware::contexthub::AsyncEventType;
+using ::android::hardware::contexthub::BnEndpointCallback;
 using ::android::hardware::contexthub::ContextHubInfo;
 using ::android::hardware::contexthub::ContextHubMessage;
+using ::android::hardware::contexthub::EndpointId;
+using ::android::hardware::contexthub::EndpointInfo;
 using ::android::hardware::contexthub::ErrorCode;
 using ::android::hardware::contexthub::HostEndpointInfo;
+using ::android::hardware::contexthub::HubInfo;
 using ::android::hardware::contexthub::IContextHub;
 using ::android::hardware::contexthub::IContextHubCallbackDefault;
+using ::android::hardware::contexthub::Message;
 using ::android::hardware::contexthub::MessageDeliveryStatus;
 using ::android::hardware::contexthub::NanoappBinary;
 using ::android::hardware::contexthub::NanoappInfo;
 using ::android::hardware::contexthub::NanoappRpcService;
 using ::android::hardware::contexthub::NanSessionRequest;
 using ::android::hardware::contexthub::NanSessionStateUpdate;
+using ::android::hardware::contexthub::Reason;
+using ::android::hardware::contexthub::Service;
 using ::android::hardware::contexthub::Setting;
 using ::android::hardware::contexthub::vts_utils::kNonExistentAppId;
 using ::android::hardware::contexthub::vts_utils::waitForCallback;
@@ -61,8 +70,14 @@
         contextHub = android::waitForDeclaredService<IContextHub>(
                 String16(std::get<0>(GetParam()).c_str()));
         ASSERT_NE(contextHub, nullptr);
+
+        // Best effort enable test mode - this may not be supported on older HALS, so we
+        // ignore the return value.
+        contextHub->setTestMode(/* enable= */ true);
     }
 
+    virtual void TearDown() override { contextHub->setTestMode(/* enable= */ false); }
+
     uint32_t getHubId() { return std::get<1>(GetParam()); }
 
     void testSettingChanged(Setting setting);
@@ -465,6 +480,305 @@
     }
 }
 
+class TestEndpointCallback : public BnEndpointCallback {
+  public:
+    Status onEndpointStarted(const std::vector<EndpointInfo>& /* endpointInfos */) override {
+        return Status::ok();
+    }
+
+    Status onEndpointStopped(const std::vector<EndpointId>& /* endpointIds */,
+                             Reason /* reason */) override {
+        return Status::ok();
+    }
+
+    Status onMessageReceived(int32_t /* sessionId */, const Message& message) override {
+        {
+            std::unique_lock<std::mutex> lock(mMutex);
+            mMessages.push_back(message);
+        }
+        mCondVar.notify_one();
+        return Status::ok();
+    }
+
+    Status onMessageDeliveryStatusReceived(int32_t /* sessionId */,
+                                           const MessageDeliveryStatus& /* msgStatus */) override {
+        return Status::ok();
+    }
+
+    Status onEndpointSessionOpenRequest(
+            int32_t /* sessionId */, const EndpointId& /* destination */,
+            const EndpointId& /* initiator */,
+            const std::optional<String16>& /* serviceDescriptor */) override {
+        return Status::ok();
+    }
+
+    Status onCloseEndpointSession(int32_t /* sessionId */, Reason /* reason */) override {
+        return Status::ok();
+    }
+
+    Status onEndpointSessionOpenComplete(int32_t /* sessionId */) override {
+        {
+            std::unique_lock<std::mutex> lock(mMutex);
+            mWasOnEndpointSessionOpenCompleteCalled = true;
+        }
+        mCondVar.notify_one();
+        return Status::ok();
+    }
+
+    bool wasOnEndpointSessionOpenCompleteCalled() {
+        return mWasOnEndpointSessionOpenCompleteCalled;
+    }
+
+    void resetWasOnEndpointSessionOpenCompleteCalled() {
+        mWasOnEndpointSessionOpenCompleteCalled = false;
+    }
+
+    std::mutex& getMutex() { return mMutex; }
+    std::condition_variable& getCondVar() { return mCondVar; }
+    std::vector<Message> getMessages() { return mMessages; }
+
+  private:
+    std::vector<Message> mMessages;
+    std::mutex mMutex;
+    std::condition_variable mCondVar;
+    bool mWasOnEndpointSessionOpenCompleteCalled = false;
+};
+
+TEST_P(ContextHubAidl, RegisterEndpoint) {
+    EndpointInfo endpointInfo;
+    endpointInfo.id.id = 1;
+    endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
+    endpointInfo.type = EndpointInfo::EndpointType::NATIVE;
+    endpointInfo.name = String16("Test host endpoint 1");
+    endpointInfo.version = 42;
+
+    Status status = contextHub->registerEndpoint(endpointInfo);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        EXPECT_TRUE(status.isOk());
+    }
+}
+
+TEST_P(ContextHubAidl, RegisterEndpointSameNameFailure) {
+    EndpointInfo endpointInfo;
+    endpointInfo.id.id = 2;
+    endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
+    endpointInfo.type = EndpointInfo::EndpointType::NATIVE;
+    endpointInfo.name = String16("Test host endpoint 2");
+    endpointInfo.version = 42;
+
+    EndpointInfo endpointInfo2;
+    endpointInfo2.id.id = 3;
+    endpointInfo2.id.hubId = 0xCAFECAFECAFECAFE;
+    endpointInfo2.type = EndpointInfo::EndpointType::NATIVE;
+    endpointInfo2.name = String16("Test host endpoint 2");
+    endpointInfo2.version = 42;
+
+    Status status = contextHub->registerEndpoint(endpointInfo);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        EXPECT_TRUE(status.isOk());
+    }
+
+    EXPECT_FALSE(contextHub->registerEndpoint(endpointInfo2).isOk());
+}
+
+TEST_P(ContextHubAidl, RegisterEndpointSameIdFailure) {
+    EndpointInfo endpointInfo;
+    endpointInfo.id.id = 4;
+    endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
+    endpointInfo.type = EndpointInfo::EndpointType::NATIVE;
+    endpointInfo.name = String16("Test host endpoint 4");
+    endpointInfo.version = 42;
+
+    EndpointInfo endpointInfo2;
+    endpointInfo2.id.id = 4;
+    endpointInfo2.id.hubId = 0xCAFECAFECAFECAFE;
+    endpointInfo2.type = EndpointInfo::EndpointType::NATIVE;
+    endpointInfo2.name = String16("Test host endpoint - same ID test");
+    endpointInfo2.version = 42;
+
+    Status status = contextHub->registerEndpoint(endpointInfo);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        EXPECT_TRUE(status.isOk());
+    }
+
+    EXPECT_FALSE(contextHub->registerEndpoint(endpointInfo2).isOk());
+}
+
+TEST_P(ContextHubAidl, UnregisterEndpoint) {
+    EndpointInfo endpointInfo;
+    endpointInfo.id.id = 6;
+    endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
+    endpointInfo.type = EndpointInfo::EndpointType::NATIVE;
+    endpointInfo.name = String16("Test host endpoint 6");
+    endpointInfo.version = 42;
+
+    Status status = contextHub->registerEndpoint(endpointInfo);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        EXPECT_TRUE(status.isOk());
+    }
+
+    EXPECT_TRUE(contextHub->unregisterEndpoint(endpointInfo).isOk());
+}
+
+TEST_P(ContextHubAidl, UnregisterEndpointNonexistent) {
+    EndpointInfo endpointInfo;
+    endpointInfo.id.id = 100;
+    endpointInfo.id.hubId = 0xCAFECAFECAFECAFE;
+    endpointInfo.type = EndpointInfo::EndpointType::NATIVE;
+    endpointInfo.name = String16("Test host endpoint 100");
+    endpointInfo.version = 42;
+
+    Status status = contextHub->unregisterEndpoint(endpointInfo);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        EXPECT_FALSE(status.isOk());
+    }
+}
+
+TEST_P(ContextHubAidl, RegisterCallback) {
+    auto cb = sp<TestEndpointCallback>::make();
+    Status status = contextHub->registerEndpointCallback(cb);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        EXPECT_TRUE(status.isOk());
+    }
+}
+
+TEST_P(ContextHubAidl, OpenEndpointSessionInvalidRange) {
+    auto cb = sp<TestEndpointCallback>::make();
+    Status status = contextHub->registerEndpointCallback(cb);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        EXPECT_TRUE(status.isOk());
+    }
+
+    // Register the endpoint
+    EndpointInfo initiatorEndpoint;
+    initiatorEndpoint.id.id = 7;
+    initiatorEndpoint.id.hubId = 0xCAFECAFECAFECAFE;
+    initiatorEndpoint.type = EndpointInfo::EndpointType::NATIVE;
+    initiatorEndpoint.name = String16("Test host endpoint 7");
+    initiatorEndpoint.version = 42;
+    EXPECT_TRUE(contextHub->registerEndpoint(initiatorEndpoint).isOk());
+
+    // Find the destination, if it exists
+    std::vector<EndpointInfo> endpoints;
+    EXPECT_TRUE(contextHub->getEndpoints(&endpoints).isOk());
+    const EndpointInfo* destinationEndpoint = nullptr;
+    for (const EndpointInfo& endpoint : endpoints) {
+        for (const Service& service : endpoint.services) {
+            if (service.serviceDescriptor == String16("ECHO")) {
+                destinationEndpoint = &endpoint;
+                break;
+            }
+        }
+    }
+    if (destinationEndpoint == nullptr) {
+        return;  // no echo service endpoint -> just return
+    }
+
+    // Request the range
+    constexpr int32_t requestedRange = 100;
+    std::array<int32_t, 2> range;
+    ASSERT_TRUE(contextHub->requestSessionIdRange(requestedRange, &range).isOk());
+    EXPECT_EQ(range.size(), 2);
+    EXPECT_GE(range[1] - range[0] + 1, requestedRange);
+
+    // Open the session
+    int32_t sessionId = range[1] + 10;  // invalid
+    EXPECT_FALSE(contextHub
+                         ->openEndpointSession(sessionId, destinationEndpoint->id,
+                                               initiatorEndpoint.id,
+                                               /* in_serviceDescriptor= */ String16("ECHO"))
+                         .isOk());
+}
+
+TEST_P(ContextHubAidl, OpenEndpointSessionAndSendMessageEchoesBack) {
+    auto cb = sp<TestEndpointCallback>::make();
+    Status status = contextHub->registerEndpointCallback(cb);
+    if (status.exceptionCode() == Status::EX_UNSUPPORTED_OPERATION ||
+        status.transactionError() == android::UNKNOWN_TRANSACTION) {
+        GTEST_SKIP() << "Not supported -> old API; or not implemented";
+    } else {
+        EXPECT_TRUE(status.isOk());
+    }
+
+    std::unique_lock<std::mutex> lock(cb->getMutex());
+
+    // Register the endpoint
+    EndpointInfo initiatorEndpoint;
+    initiatorEndpoint.id.id = 8;
+    initiatorEndpoint.id.hubId = 0xCAFECAFECAFECAFE;
+    initiatorEndpoint.type = EndpointInfo::EndpointType::NATIVE;
+    initiatorEndpoint.name = String16("Test host endpoint 7");
+    initiatorEndpoint.version = 42;
+    EXPECT_TRUE(contextHub->registerEndpoint(initiatorEndpoint).isOk());
+
+    // Find the destination, if it exists
+    std::vector<EndpointInfo> endpoints;
+    EXPECT_TRUE(contextHub->getEndpoints(&endpoints).isOk());
+    const EndpointInfo* destinationEndpoint = nullptr;
+    for (const EndpointInfo& endpoint : endpoints) {
+        for (const Service& service : endpoint.services) {
+            if (service.serviceDescriptor == String16("ECHO")) {
+                destinationEndpoint = &endpoint;
+                break;
+            }
+        }
+    }
+    if (destinationEndpoint == nullptr) {
+        return;  // no echo service endpoint -> just return
+    }
+
+    // Request the range
+    constexpr int32_t requestedRange = 100;
+    std::array<int32_t, 2> range;
+    ASSERT_TRUE(contextHub->requestSessionIdRange(requestedRange, &range).isOk());
+    EXPECT_EQ(range.size(), 2);
+    EXPECT_GE(range[1] - range[0] + 1, requestedRange);
+
+    // Open the session
+    cb->resetWasOnEndpointSessionOpenCompleteCalled();
+    int32_t sessionId = range[0];
+    ASSERT_TRUE(contextHub
+                        ->openEndpointSession(sessionId, destinationEndpoint->id,
+                                              initiatorEndpoint.id,
+                                              /* in_serviceDescriptor= */ String16("ECHO"))
+                        .isOk());
+    cb->getCondVar().wait(lock);
+    EXPECT_TRUE(cb->wasOnEndpointSessionOpenCompleteCalled());
+
+    // Send the message
+    Message message;
+    message.flags = 0;
+    message.sequenceNumber = 0;
+    message.content.push_back(42);
+    ASSERT_TRUE(contextHub->sendMessageToEndpoint(sessionId, message).isOk());
+
+    // Check for echo
+    cb->getCondVar().wait(lock);
+    EXPECT_FALSE(cb->getMessages().empty());
+    EXPECT_EQ(cb->getMessages().back().content.back(), 42);
+}
+
 std::string PrintGeneratedTest(const testing::TestParamInfo<ContextHubAidl::ParamType>& info) {
     return std::string("CONTEXT_HUB_ID_") + std::to_string(std::get<1>(info.param));
 }
diff --git a/drm/Android.bp b/drm/Android.bp
new file mode 100644
index 0000000..35c1b03
--- /dev/null
+++ b/drm/Android.bp
@@ -0,0 +1,5 @@
+dirgroup {
+    name: "trusty_dirgroup_hardware_interfaces_drm",
+    dirs: ["."],
+    visibility: ["//trusty/vendor/google/aosp/scripts"],
+}
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
index 827621c..7ee8c34 100644
--- a/drm/aidl/Android.bp
+++ b/drm/aidl/Android.bp
@@ -27,6 +27,9 @@
         ndk: {
             min_sdk_version: "34",
         },
+        rust: {
+            enabled: true,
+        },
     },
     double_loadable: true,
     versions_with_info: [
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 697cb91..6c338bd 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -27,7 +27,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@1.0",
-        "android.hardware.gnss-V4-ndk",
+        "android.hardware.gnss-V5-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp
index 65c752c..13984629 100644
--- a/gnss/1.1/vts/functional/Android.bp
+++ b/gnss/1.1/vts/functional/Android.bp
@@ -37,7 +37,7 @@
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@common-vts-lib",
-        "android.hardware.gnss-V4-cpp",
+        "android.hardware.gnss-V5-cpp",
     ],
     shared_libs: [
         "android.hardware.gnss.measurement_corrections@1.0",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 35c2e37..6a4965b 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -50,7 +50,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@1.0",
-        "android.hardware.gnss-V4-ndk",
+        "android.hardware.gnss-V5-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp
index 4ca3063..08d4cb3 100644
--- a/gnss/2.0/vts/functional/Android.bp
+++ b/gnss/2.0/vts/functional/Android.bp
@@ -40,7 +40,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@2.1",
         "android.hardware.gnss@common-vts-lib",
-        "android.hardware.gnss-V4-cpp",
+        "android.hardware.gnss-V5-cpp",
     ],
     test_suites: [
         "general-tests",
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
index 1bb7512..a2e652e 100644
--- a/gnss/2.1/default/Android.bp
+++ b/gnss/2.1/default/Android.bp
@@ -44,7 +44,7 @@
         "android.hardware.gnss@1.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
-        "android.hardware.gnss-V4-ndk",
+        "android.hardware.gnss-V5-ndk",
     ],
     static_libs: [
         "android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/vts/functional/Android.bp b/gnss/2.1/vts/functional/Android.bp
index af66037..8a8fa93 100644
--- a/gnss/2.1/vts/functional/Android.bp
+++ b/gnss/2.1/vts/functional/Android.bp
@@ -41,7 +41,7 @@
         "android.hardware.gnss@2.0",
         "android.hardware.gnss@2.1",
         "android.hardware.gnss@common-vts-lib",
-        "android.hardware.gnss-V4-cpp",
+        "android.hardware.gnss-V5-cpp",
     ],
     shared_libs: [
         "libvintf",
diff --git a/gnss/aidl/Android.bp b/gnss/aidl/Android.bp
index 47fc3af..6e159a1 100644
--- a/gnss/aidl/Android.bp
+++ b/gnss/aidl/Android.bp
@@ -30,6 +30,7 @@
         "android/hardware/gnss/*.aidl",
         "android/hardware/gnss/measurement_corrections/*.aidl",
         "android/hardware/gnss/visibility_control/*.aidl",
+        "android/hardware/gnss/gnss_assistance/*.aidl",
     ],
     stability: "vintf",
     backend: {
@@ -56,6 +57,6 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index d1aaf2c..fc74612 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -61,6 +61,7 @@
   void stopSvStatus();
   void startNmea();
   void stopNmea();
+  android.hardware.gnss.gnss_assistance.IGnssAssistanceInterface getExtensionGnssAssistanceInterface();
   const int ERROR_INVALID_ARGUMENT = 1;
   const int ERROR_ALREADY_INIT = 2;
   const int ERROR_GENERIC = 3;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/BeidouSatelliteEphemeris.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/BeidouSatelliteEphemeris.aidl
new file mode 100644
index 0000000..ec517e6
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/BeidouSatelliteEphemeris.aidl
@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
+@VintfStability
+parcelable BeidouSatelliteEphemeris {
+  int prn;
+  android.hardware.gnss.gnss_assistance.BeidouSatelliteEphemeris.BeidouSatelliteClockModel satelliteClockModel;
+  android.hardware.gnss.gnss_assistance.KeplerianOrbitModel satelliteOrbitModel;
+  android.hardware.gnss.gnss_assistance.BeidouSatelliteEphemeris.BeidouSatelliteHealth satelliteHealth;
+  android.hardware.gnss.gnss_assistance.BeidouSatelliteEphemeris.BeidouSatelliteEphemerisTime satelliteEphemerisTime;
+  @VintfStability
+  parcelable BeidouSatelliteClockModel {
+    long timeOfClockSeconds;
+    double af0;
+    double af1;
+    double af2;
+    double tgd1;
+    double tgd2;
+    int aodc;
+  }
+  parcelable BeidouSatelliteHealth {
+    int satH1;
+    double svAccur;
+  }
+  parcelable BeidouSatelliteEphemerisTime {
+    int aode;
+    int weekNumber;
+    int toeSeconds;
+  }
+}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
similarity index 91%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
index a5eda52..6d8040b 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable GalileoIonosphericModel {
+  double ai0;
+  double ai1;
+  double ai2;
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GalileoSatelliteEphemeris.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GalileoSatelliteEphemeris.aidl
new file mode 100644
index 0000000..1bac08e
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GalileoSatelliteEphemeris.aidl
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
+@VintfStability
+parcelable GalileoSatelliteEphemeris {
+  int satelliteCodeNumber;
+  android.hardware.gnss.gnss_assistance.GalileoSatelliteEphemeris.GalileoSatelliteClockModel[] satelliteClockModel;
+  android.hardware.gnss.gnss_assistance.KeplerianOrbitModel satelliteOrbitModel;
+  android.hardware.gnss.gnss_assistance.GalileoSatelliteEphemeris.GalileoSvHealth svHealth;
+  android.hardware.gnss.gnss_assistance.SatelliteEphemerisTime satelliteEphemerisTime;
+  @VintfStability
+  parcelable GalileoSatelliteClockModel {
+    long timeOfClockSeconds;
+    double af0;
+    double af1;
+    double af2;
+    double bgdSeconds;
+    double sisaMeters;
+    android.hardware.gnss.gnss_assistance.GalileoSatelliteEphemeris.GalileoSatelliteClockModel.SatelliteClockType satelliteClockType;
+    @Backing(type="int") @VintfStability
+    enum SatelliteClockType {
+      UNDEFINED = 0,
+      GALILEO_FNAV_CLOCK = 1,
+      GALILEO_INAV_CLOCK = 2,
+    }
+  }
+  @VintfStability
+  parcelable GalileoSvHealth {
+    int dataValidityStatusE1b;
+    int signalHealthStatusE1b;
+    int dataValidityStatusE5a;
+    int signalHealthStatusE5a;
+    int dataValidityStatusE5b;
+    int signalHealthStatusE5b;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
new file mode 100644
index 0000000..55621ab
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
+@VintfStability
+parcelable GlonassAlmanac {
+  long issueDateMs;
+  android.hardware.gnss.gnss_assistance.GlonassAlmanac.GlonassSatelliteAlmanac[] satelliteAlmanac;
+  @VintfStability
+  parcelable GlonassSatelliteAlmanac {
+    int slotNumber;
+    int svHealth;
+    int frequencyChannel;
+    double tau;
+    double tLambda;
+    double lambda;
+    double deltaI;
+    double deltaT;
+    double deltaTDot;
+    double eccentricity;
+    double omega;
+  }
+}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GlonassSatelliteEphemeris.aidl
similarity index 68%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GlonassSatelliteEphemeris.aidl
index a5eda52..bbcb3af 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GlonassSatelliteEphemeris.aidl
@@ -31,9 +31,33 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable GlonassSatelliteEphemeris {
+  int slotNumber;
+  int svHealth;
+  double frameTimeSeconds;
+  int ageInDays;
+  android.hardware.gnss.gnss_assistance.GlonassSatelliteEphemeris.GlonassSatelliteClockModel satelliteClockModel;
+  android.hardware.gnss.gnss_assistance.GlonassSatelliteEphemeris.GlonassSatelliteOrbitModel satelliteOrbitModel;
+  @VintfStability
+  parcelable GlonassSatelliteClockModel {
+    long timeOfClockSeconds;
+    double clockBias;
+    double freqBias;
+    int freqNumber;
+  }
+  @VintfStability
+  parcelable GlonassSatelliteOrbitModel {
+    double x;
+    double xDot;
+    double xAccel;
+    double y;
+    double yDot;
+    double yAccel;
+    double z;
+    double zDot;
+    double zAccel;
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
similarity index 76%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
index a5eda52..b986be4 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
@@ -31,9 +31,27 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable GnssAlmanac {
+  long issueDateMs;
+  int iod;
+  int weekNumber;
+  int toaSeconds;
+  android.hardware.gnss.gnss_assistance.GnssAlmanac.GnssSatelliteAlmanac[] satelliteAlmanac;
+  @VintfStability
+  parcelable GnssSatelliteAlmanac {
+    int svid;
+    int svHealth;
+    double eccentricity;
+    double inclination;
+    double omega;
+    double omega0;
+    double omegaDot;
+    double rootA;
+    double m0;
+    double af0;
+    double af1;
+  }
 }
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssAssistance.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssAssistance.aidl
new file mode 100644
index 0000000..1df2123
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssAssistance.aidl
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
+@VintfStability
+parcelable GnssAssistance {
+  android.hardware.gnss.gnss_assistance.GnssAssistance.GpsAssistance gpsAssistance;
+  android.hardware.gnss.gnss_assistance.GnssAssistance.GlonassAssistance glonassAssistance;
+  android.hardware.gnss.gnss_assistance.GnssAssistance.GalileoAssistance galileoAssistance;
+  android.hardware.gnss.gnss_assistance.GnssAssistance.BeidouAssistance beidouAssistance;
+  android.hardware.gnss.gnss_assistance.GnssAssistance.QzssAssistance qzssAssistance;
+  @VintfStability
+  parcelable GnssSatelliteCorrections {
+    int svid;
+    android.hardware.gnss.gnss_assistance.IonosphericCorrection[] ionosphericCorrections;
+  }
+  @VintfStability
+  parcelable GpsAssistance {
+    android.hardware.gnss.gnss_assistance.GnssAlmanac almanac;
+    android.hardware.gnss.gnss_assistance.KlobucharIonosphericModel ionosphericModel;
+    android.hardware.gnss.gnss_assistance.UtcModel utcModel;
+    android.hardware.gnss.gnss_assistance.LeapSecondsModel leapSecondsModel;
+    android.hardware.gnss.gnss_assistance.TimeModel[] timeModels;
+    android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris[] satelliteEphemeris;
+    android.hardware.gnss.gnss_assistance.RealTimeIntegrityModel[] realTimeIntegrityModels;
+    android.hardware.gnss.gnss_assistance.GnssAssistance.GnssSatelliteCorrections[] satelliteCorrections;
+  }
+  @VintfStability
+  parcelable GalileoAssistance {
+    android.hardware.gnss.gnss_assistance.GnssAlmanac almanac;
+    android.hardware.gnss.gnss_assistance.GalileoIonosphericModel ionosphericModel;
+    android.hardware.gnss.gnss_assistance.UtcModel utcModel;
+    android.hardware.gnss.gnss_assistance.LeapSecondsModel leapSecondsModel;
+    android.hardware.gnss.gnss_assistance.TimeModel[] timeModels;
+    android.hardware.gnss.gnss_assistance.GalileoSatelliteEphemeris[] satelliteEphemeris;
+    android.hardware.gnss.gnss_assistance.RealTimeIntegrityModel[] realTimeIntegrityModels;
+    android.hardware.gnss.gnss_assistance.GnssAssistance.GnssSatelliteCorrections[] satelliteCorrections;
+  }
+  @VintfStability
+  parcelable GlonassAssistance {
+    android.hardware.gnss.gnss_assistance.GlonassAlmanac almanac;
+    android.hardware.gnss.gnss_assistance.UtcModel utcModel;
+    android.hardware.gnss.gnss_assistance.TimeModel[] timeModels;
+    android.hardware.gnss.gnss_assistance.GlonassSatelliteEphemeris[] satelliteEphemeris;
+    android.hardware.gnss.gnss_assistance.GnssAssistance.GnssSatelliteCorrections[] satelliteCorrections;
+  }
+  @VintfStability
+  parcelable QzssAssistance {
+    android.hardware.gnss.gnss_assistance.GnssAlmanac almanac;
+    android.hardware.gnss.gnss_assistance.KlobucharIonosphericModel ionosphericModel;
+    android.hardware.gnss.gnss_assistance.UtcModel utcModel;
+    android.hardware.gnss.gnss_assistance.LeapSecondsModel leapSecondsModel;
+    android.hardware.gnss.gnss_assistance.TimeModel[] timeModels;
+    android.hardware.gnss.gnss_assistance.QzssSatelliteEphemeris[] satelliteEphemeris;
+    android.hardware.gnss.gnss_assistance.RealTimeIntegrityModel[] realTimeIntegrityModels;
+    android.hardware.gnss.gnss_assistance.GnssAssistance.GnssSatelliteCorrections[] satelliteCorrections;
+  }
+  @VintfStability
+  parcelable BeidouAssistance {
+    android.hardware.gnss.gnss_assistance.GnssAlmanac almanac;
+    android.hardware.gnss.gnss_assistance.KlobucharIonosphericModel ionosphericModel;
+    android.hardware.gnss.gnss_assistance.UtcModel utcModel;
+    android.hardware.gnss.gnss_assistance.LeapSecondsModel leapSecondsModel;
+    android.hardware.gnss.gnss_assistance.TimeModel[] timeModels;
+    android.hardware.gnss.gnss_assistance.BeidouSatelliteEphemeris[] satelliteEphemeris;
+    android.hardware.gnss.gnss_assistance.RealTimeIntegrityModel[] realTimeIntegrityModels;
+    android.hardware.gnss.gnss_assistance.GnssAssistance.GnssSatelliteCorrections[] satelliteCorrections;
+  }
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssCorrectionComponent.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssCorrectionComponent.aidl
new file mode 100644
index 0000000..2d43bb3
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GnssCorrectionComponent.aidl
@@ -0,0 +1,37 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
+@VintfStability
+parcelable GnssCorrectionComponent {
+  String sourceKey;
+  android.hardware.gnss.gnss_assistance.GnssCorrectionComponent.GnssInterval validityInterval;
+  android.hardware.gnss.gnss_assistance.GnssCorrectionComponent.PseudorangeCorrection pseudorangeCorrection;
+  @VintfStability
+  parcelable GnssInterval {
+    long startMillisSinceGpsEpoch;
+    long endMillisSinceGpsEpoch;
+  }
+  @VintfStability
+  parcelable PseudorangeCorrection {
+    double correctionMeters;
+    double correctionUncertaintyMeters;
+    double correctionRateMetersPerSecond;
+  }
+}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GpsSatelliteEphemeris.aidl
similarity index 64%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GpsSatelliteEphemeris.aidl
index a5eda52..721edb4 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/GpsSatelliteEphemeris.aidl
@@ -31,9 +31,34 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable GpsSatelliteEphemeris {
+  int prn;
+  android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsL2Params gpsL2Params;
+  android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsSatelliteClockModel satelliteClockModel;
+  android.hardware.gnss.gnss_assistance.KeplerianOrbitModel satelliteOrbitModel;
+  android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsSatelliteHealth satelliteHealth;
+  android.hardware.gnss.gnss_assistance.SatelliteEphemerisTime satelliteEphemerisTime;
+  @VintfStability
+  parcelable GpsL2Params {
+    int l2Code;
+    int l2Flag;
+  }
+  @VintfStability
+  parcelable GpsSatelliteClockModel {
+    long timeOfClockSeconds;
+    double af0;
+    double af1;
+    double af2;
+    double tgd;
+    int iodc;
+  }
+  @VintfStability
+  parcelable GpsSatelliteHealth {
+    int svHealth;
+    double svAccur;
+    double fitInt;
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IGnssAssistanceCallback.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IGnssAssistanceCallback.aidl
index a5eda52..602a249 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IGnssAssistanceCallback.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface IGnssAssistanceCallback {
+  void injectRequestCb();
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IGnssAssistanceInterface.aidl
similarity index 84%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IGnssAssistanceInterface.aidl
index a5eda52..4dd5cf6 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IGnssAssistanceInterface.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface IGnssAssistanceInterface {
+  void injectGnssAssistance(in android.hardware.gnss.gnss_assistance.GnssAssistance gnssAssistance);
+  void setCallback(in android.hardware.gnss.gnss_assistance.IGnssAssistanceCallback callback);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IonosphericCorrection.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IonosphericCorrection.aidl
index a5eda52..6e8434a 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/IonosphericCorrection.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable IonosphericCorrection {
+  long carrierFrequencyHz;
+  android.hardware.gnss.gnss_assistance.GnssCorrectionComponent ionosphericCorrectionComponent;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/KeplerianOrbitModel.aidl
similarity index 75%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/KeplerianOrbitModel.aidl
index a5eda52..835c6ec 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/KeplerianOrbitModel.aidl
@@ -31,9 +31,27 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable KeplerianOrbitModel {
+  double rootA;
+  double eccentricity;
+  double i0;
+  double iDot;
+  double omega;
+  double omega0;
+  double omegaDot;
+  double m0;
+  double deltaN;
+  android.hardware.gnss.gnss_assistance.KeplerianOrbitModel.SecondOrderHarmonicPerturbation secondOrderHarmonicPerturbation;
+  @VintfStability
+  parcelable SecondOrderHarmonicPerturbation {
+    double cic;
+    double cis;
+    double crc;
+    double crs;
+    double cuc;
+    double cus;
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
similarity index 87%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
index a5eda52..5a0caa5 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
@@ -31,9 +31,16 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable KlobucharIonosphericModel {
+  double alpha0;
+  double alpha1;
+  double alpha2;
+  double alpha3;
+  double beta0;
+  double beta1;
+  double beta2;
+  double beta3;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
index a5eda52..bc38b9b 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable LeapSecondsModel {
+  int leapSeconds;
+  int leapSecondsFuture;
+  int weekNumberLeapSecondsFuture;
+  int dayNumberLeapSecondsFuture;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/QzssSatelliteEphemeris.aidl
similarity index 74%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/QzssSatelliteEphemeris.aidl
index a5eda52..5bb1c97 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/QzssSatelliteEphemeris.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable QzssSatelliteEphemeris {
+  int prn;
+  android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsL2Params gpsL2Params;
+  android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsSatelliteClockModel satelliteClockModel;
+  android.hardware.gnss.gnss_assistance.KeplerianOrbitModel satelliteOrbitModel;
+  android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsSatelliteHealth satelliteHealth;
+  android.hardware.gnss.gnss_assistance.SatelliteEphemerisTime satelliteEphemerisTime;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/RealTimeIntegrityModel.aidl
similarity index 86%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/RealTimeIntegrityModel.aidl
index a5eda52..c7379e1 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/RealTimeIntegrityModel.aidl
@@ -31,9 +31,15 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable RealTimeIntegrityModel {
+  int svid;
+  boolean usable;
+  long publishDateSeconds;
+  long startDateSeconds;
+  long endDateSeconds;
+  String advisoryType;
+  String advisoryNumber;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/SatelliteEphemerisTime.aidl
similarity index 91%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/SatelliteEphemerisTime.aidl
index a5eda52..1e5cd02 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/SatelliteEphemerisTime.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable SatelliteEphemerisTime {
+  int iode;
+  int weekNumber;
+  int toeSeconds;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/TimeModel.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/TimeModel.aidl
index a5eda52..e1ce890 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/TimeModel.aidl
@@ -31,9 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable TimeModel {
+  android.hardware.gnss.GnssConstellationType toGnss;
+  double a0;
+  double a1;
+  int timeOfWeek;
+  int weekNumber;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/UtcModel.aidl
similarity index 91%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/UtcModel.aidl
index a5eda52..df754bc 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/gnss_assistance/UtcModel.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.gnss.gnss_assistance;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable UtcModel {
+  double a0;
+  double a1;
+  int timeOfWeek;
+  int weekNumber;
 }
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index aaafe7f..5fc8a48 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -29,6 +29,7 @@
 import android.hardware.gnss.IGnssNavigationMessageInterface;
 import android.hardware.gnss.IGnssPowerIndication;
 import android.hardware.gnss.IGnssPsds;
+import android.hardware.gnss.gnss_assistance.IGnssAssistanceInterface;
 import android.hardware.gnss.measurement_corrections.IMeasurementCorrectionsInterface;
 import android.hardware.gnss.visibility_control.IGnssVisibilityControl;
 
@@ -343,4 +344,11 @@
      * Stops the NMEA output stream.
      */
     void stopNmea();
+
+    /**
+     * This method returns the IGnssAssistanceInterface.
+     *
+     * @return Handle to the IGnssAssistanceInterface.
+     */
+    IGnssAssistanceInterface getExtensionGnssAssistanceInterface();
 }
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/BeidouSatelliteEphemeris.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/BeidouSatelliteEphemeris.aidl
new file mode 100644
index 0000000..bb1f7d9
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/BeidouSatelliteEphemeris.aidl
@@ -0,0 +1,98 @@
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.gnss_assistance.KeplerianOrbitModel;
+
+/**
+ * Contains ephemeris parameters specific to Beidou satellites.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable BeidouSatelliteEphemeris {
+    /*
+     * Contains the set of parameters needed for Beidou satellite clock
+     * correction.
+     * This is defined in BDS-SIS-ICD-B1I-3.0, section 5.2.4.9, 5.2.4.10.
+     */
+    @VintfStability
+    parcelable BeidouSatelliteClockModel {
+        /**
+         * Time of the clock in seconds since Beidou epoch.
+         *
+         * Represents the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of GNSS
+         * navigation message file in RINEX 3.05 Table A14.
+         */
+        long timeOfClockSeconds;
+
+        /** SV clock bias in seconds. */
+        double af0;
+
+        /** SV clock drift in seconds per second. */
+        double af1;
+
+        /** Clock drift rate in seconds per second squared. */
+        double af2;
+
+        /** Group delay differential 1 B1/B3 in seconds. */
+        double tgd1;
+
+        /** Group delay differential 2 B2/B3 in seconds. */
+        double tgd2;
+
+        /**
+         * Age of Data Clock and field range is: 0-31.
+         * This is defined in BDS-SIS-ICD-B1I-3.0 Section 5.2.4.8 Table 5-6.
+         */
+        int aodc;
+    }
+
+    /** Contains information about Beidou health. */
+    parcelable BeidouSatelliteHealth {
+        /**
+         * The autonomous satellite health flag (SatH1) occupies 1 bit. “0” means
+         * broadcasting satellite is good and “1” means not.
+         * This is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.6.
+         */
+        int satH1;
+
+        /**
+         * SV accuracy in meters.
+         * This is defined in the "BROADCAST ORBIT - 6" record of RINEX 3.05
+         * Table A14, pp.78.
+         */
+        double svAccur;
+    }
+
+    /** Contains information about time of ephemeris */
+    parcelable BeidouSatelliteEphemerisTime {
+        /**
+         * AODE Age of Data, Ephemeris.
+         * This is as defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.11 Table 5-8.
+         */
+        int aode;
+
+        /** Beidou week number without rollover. */
+        int weekNumber;
+
+        /**
+         * Time of ephemeris in seconds.
+         * This is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.12.
+         */
+        int toeSeconds;
+    }
+
+    /** The PRN number of the Beidou satellite. */
+    int prn;
+
+    /** Satellite clock model. */
+    BeidouSatelliteClockModel satelliteClockModel;
+
+    /** Satellite orbit model. */
+    KeplerianOrbitModel satelliteOrbitModel;
+
+    /** Satellite health. */
+    BeidouSatelliteHealth satelliteHealth;
+
+    /** Satellite ephemeris time. */
+    BeidouSatelliteEphemerisTime satelliteEphemerisTime;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
new file mode 100644
index 0000000..ced8917
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoIonosphericModel.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains Galileo ionospheric model.
+ * This is Defined in Galileo-OS-SIS-ICD-v2.1, 5.1.6.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable GalileoIonosphericModel {
+    /** Effective ionisation level 1st order parameter in sfu. */
+    double ai0;
+
+    /** Effective ionisation level 2nd order parameter in sfu per degree. */
+    double ai1;
+
+    /** Effective ionisation level 3nd order parameter in sfu per degree squared. */
+    double ai2;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoSatelliteEphemeris.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoSatelliteEphemeris.aidl
new file mode 100644
index 0000000..e3160ef
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GalileoSatelliteEphemeris.aidl
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.gnss_assistance.KeplerianOrbitModel;
+import android.hardware.gnss.gnss_assistance.SatelliteEphemerisTime;
+
+/**
+ * Contains ephemeris parameters specific to Galileo satellites.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable GalileoSatelliteEphemeris {
+    /**
+     * Contains the set of parameters needed for Galileo satellite clock correction.
+     * This is defined in Galileo-OS-SIS-ICD 5.1.3.
+     */
+    @VintfStability
+    parcelable GalileoSatelliteClockModel {
+        /*
+         * States the type of satellite clock.
+         */
+        @VintfStability
+        @Backing(type="int")
+        enum SatelliteClockType {
+            UNDEFINED = 0,
+            GALILEO_FNAV_CLOCK = 1,
+            GALILEO_INAV_CLOCK = 2
+        }
+
+        /**
+         * Time of the clock in seconds since Galileo epoch.
+         *
+         * Represents the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of GNSS
+         * navigation message file in RINEX 3.05 Table A8 (Galileo).
+         */
+        long timeOfClockSeconds;
+
+        /** SV clock bias correction coefficient in seconds. */
+        double af0;
+
+        /** SV clock drift correction coefficient in seconds per second. */
+        double af1;
+
+        /** SV clock drift rate correction coefficient in seconds per second squared. */
+        double af2;
+
+        /**
+         * Broadcast group delay in seconds.
+         * This is defined in Galileo-OS-SIS-ICD 5.1.5.
+         */
+        double bgdSeconds;
+
+        /**
+         * Signal in space accuracy in meters.
+         * This is defined in Galileo-OS-SIS-ICD 5.1.12.
+         */
+        double sisaMeters;
+
+        /** Type of satellite clock .*/
+        SatelliteClockType satelliteClockType;
+    }
+
+    /**
+     * Contains satellite health.
+     * This is defined in Galileo-OS-SIS-ICD 5.1.9.3.
+     */
+    @VintfStability
+    parcelable GalileoSvHealth {
+        /** E1-B data validity status. */
+        int dataValidityStatusE1b;
+
+        /** E1-B/C signal health status. */
+        int signalHealthStatusE1b;
+
+        /** E5a data validity status. */
+        int dataValidityStatusE5a;
+
+        /** E5a signal health status. */
+        int signalHealthStatusE5a;
+
+        /** E5b data validity status. */
+        int dataValidityStatusE5b;
+
+        /** E5b signal health status. */
+        int signalHealthStatusE5b;
+    }
+
+    /** Satellite code number. */
+    int satelliteCodeNumber;
+
+    /** Array of satellite clock model. */
+    GalileoSatelliteClockModel[] satelliteClockModel;
+
+    /** Satellite orbit model. */
+    KeplerianOrbitModel satelliteOrbitModel;
+
+    /** Satellite health. */
+    GalileoSvHealth svHealth;
+
+    /** Satellite ephemeris time. */
+    SatelliteEphemerisTime satelliteEphemerisTime;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
new file mode 100644
index 0000000..d4f149d
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassAlmanac.aidl
@@ -0,0 +1,56 @@
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains Glonass almanac data.
+ * This is defined in Glonass ICD v5.1, Section 4.5.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable GlonassAlmanac {
+    /**
+     * Contains Glonass satellite almanac data.
+     * This is defined in Glonass ICD v5.1, Section 4.5.
+     */
+    @VintfStability
+    parcelable GlonassSatelliteAlmanac {
+        /** Slot number. */
+        int slotNumber;
+
+        /** Satellite health (0=healthy, 1=unhealthy). */
+        int svHealth;
+
+        /** Frequency channel number. */
+        int frequencyChannel;
+
+        /** Coarse value of satellite time correction to GLONASS time in seconds. */
+        double tau;
+
+        /** Time of first ascending node passage of satellite in seconds. */
+        double tLambda;
+
+        /** Longitude of the first ascending node in semi-circles. */
+        double lambda;
+
+        /** Correction to the mean value of inclination in semi-circles. */
+        double deltaI;
+
+        /** Correction to the mean value of the draconian period in seconds per orbital period. */
+        double deltaT;
+
+        /** Rate of change of draconian period in seconds per orbital period squared. */
+        double deltaTDot;
+
+        /** Eccentricity. */
+        double eccentricity;
+
+        /** Argument of perigee in radians. */
+        double omega;
+    }
+
+    /** Almanac issue date in milliseconds (UTC). */
+    long issueDateMs;
+
+    /** Array of GlonassSatelliteAlmanac. */
+    GlonassSatelliteAlmanac[] satelliteAlmanac;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassSatelliteEphemeris.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassSatelliteEphemeris.aidl
new file mode 100644
index 0000000..bebde51
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GlonassSatelliteEphemeris.aidl
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.gnss_assistance.SatelliteEphemerisTime;
+
+/**
+ * Contains ephemeris parameters specific to Glonass satellites.
+ * This is defined in RINEX 3.05 APPENDIX 10 and Glonass ICD v5.1, section 4.4.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable GlonassSatelliteEphemeris {
+    /** Contains the set of parameters needed for Glonass satellite clock correction. */
+    @VintfStability
+    parcelable GlonassSatelliteClockModel {
+        /**
+         * Time of the clock in seconds (UTC).
+         *
+         * Represents the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of GNSS
+         * navigation message file in RINEX 3.05 Table A10.
+         */
+        long timeOfClockSeconds;
+
+        /** Clock bias in seconds (-TauN). */
+        double clockBias;
+
+        /** Frequency bias (+GammaN). */
+        double freqBias;
+
+        /** Frequency number. */
+        int freqNumber;
+    }
+
+    /** Contains Glonass orbit model parameters in PZ-90 coordinate system. */
+    @VintfStability
+    parcelable GlonassSatelliteOrbitModel {
+        /** X position in kilometers. */
+        double x;
+
+        /** X velocity in kilometers per second. */
+        double xDot;
+
+        /** X acceleration in kilometers per second squared. */
+        double xAccel;
+
+        /** Y position in kilometers. */
+        double y;
+
+        /** Y velocity in kilometers per second. */
+        double yDot;
+
+        /** Y acceleration in kilometers per second squared. */
+        double yAccel;
+
+        /** Z position in kilometers. */
+        double z;
+
+        /** Z velocity in kilometers per second. */
+        double zDot;
+
+        /** Z acceleration in kilometers per second squared. */
+        double zAccel;
+    }
+
+    /**
+     * L1/Satellite system (R), satellite number (slot number in sat.
+     * constellation).
+     */
+    int slotNumber;
+
+    /** Satellite health (0=healthy, 1=unhealthy). */
+    int svHealth;
+
+    /** Message frame time in seconds of the UTC week (tk+nd*86400). */
+    double frameTimeSeconds;
+
+    /** Age of current information in days (E). */
+    int ageInDays;
+
+    /** Satellite clock model. */
+    GlonassSatelliteClockModel satelliteClockModel;
+
+    /** Satellite orbit model. */
+    GlonassSatelliteOrbitModel satelliteOrbitModel;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
new file mode 100644
index 0000000..08f3373
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAlmanac.aidl
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains almanac parameters for GPS, QZSS, Galileo, Beidou.
+ *
+ * For Beidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.15.
+ * For GPS, this is defined in IS-GPS-200 section 20.3.3.5.1.2.
+ * For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.6.
+ * For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable GnssAlmanac {
+    /**
+     * Almanac issue date in milliseconds (UTC).
+     *
+     * This is unused for GPS/QZSS/Baidou.
+     */
+    long issueDateMs;
+
+    /**
+     * Almanac issue of data.
+     * This is defined Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
+     * This is unused for GPS/QZSS/Baidou.
+     */
+    int iod;
+
+    /**
+     * Almanac reference week number.
+     *
+     * For GPS and QZSS, this is GPS week number (modulo 1024).
+     * For Beidou, this is Baidou week number (modulo 8192).
+     * For Galileo, this is modulo 4 representation of the Galileo week number.
+     */
+    int weekNumber;
+
+    /** Almanac reference time in seconds. */
+    int toaSeconds;
+
+    /**
+     * Contains almanac parameters for GPS, QZSS, Galileo, Beidou.
+     *
+     * For Beidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.15.
+     * For GPS, this is defined in IS-GPS-200 section 20.3.3.5.1.2.
+     * For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.6.
+     * For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 section 5.1.10.
+     */
+    @VintfStability
+    parcelable GnssSatelliteAlmanac {
+        /** The PRN number of the GNSS satellite. */
+        int svid;
+
+        /**
+         * Satellite health information.
+         *
+         * For GPS, this is satellite subframe 4 and 5, page 25 6-bit health code as defined in
+         * IS-GPS-200 Table 20-VIII expressed in integer form.
+         *
+         * For QZSS, this is the 5-bit health code as defined in IS-QZSS-PNT, Table 4.1.2-5-2
+         * expressed in integer form.
+         *
+         * For Beidou, this is 1-bit health information. (0=healthy, 1=unhealthy).
+         *
+         * For Galileo, this is 6-bit health, bit 0 and 1 is for E5a, bit 2 and 3 is for E5b, bit
+         * 4 and 5 is for E1b.
+         */
+        int svHealth;
+
+        /** Eccentricity. */
+        double eccentricity;
+
+        /**
+         * Inclination in semi-circles.
+         *
+         * For GPS and Galileo, this is the difference between the inclination angle at reference
+         * time and the nominal inclination in semi-circles.
+         *
+         * For Beidou and QZSS, this is the inclination angle at reference time in semi-circles.
+         */
+        double inclination;
+
+        /** Argument of perigee in semi-circles. */
+        double omega;
+
+        /** Longitude of ascending node of orbital plane at weekly epoch in semi-circles. */
+        double omega0;
+
+        /** Rate of right ascension in semi-circles per second. */
+        double omegaDot;
+
+        /**
+         * Square root of semi-major axis in square root of meters.
+         *
+         * For Galileo, this is the difference with respect to the square root of the nominal
+         * semi-major axis in square root of meters.
+         */
+        double rootA;
+
+        /** Mean anomaly at reference time in semi-circles. */
+        double m0;
+
+        /** Satellite clock time bias correction coefficient in seconds. */
+        double af0;
+
+        /** Satellite clock time drift correction coefficient in seconds per second. */
+        double af1;
+    }
+
+    /** Array of GnssSatelliteAlmanac. */
+    GnssSatelliteAlmanac[] satelliteAlmanac;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAssistance.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAssistance.aidl
new file mode 100644
index 0000000..4bf6154
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssAssistance.aidl
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.gnss_assistance.BeidouSatelliteEphemeris;
+import android.hardware.gnss.gnss_assistance.GalileoIonosphericModel;
+import android.hardware.gnss.gnss_assistance.GalileoSatelliteEphemeris;
+import android.hardware.gnss.gnss_assistance.GlonassAlmanac;
+import android.hardware.gnss.gnss_assistance.GlonassSatelliteEphemeris;
+import android.hardware.gnss.gnss_assistance.GnssAlmanac;
+import android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris;
+import android.hardware.gnss.gnss_assistance.IonosphericCorrection;
+import android.hardware.gnss.gnss_assistance.KlobucharIonosphericModel;
+import android.hardware.gnss.gnss_assistance.LeapSecondsModel;
+import android.hardware.gnss.gnss_assistance.QzssSatelliteEphemeris;
+import android.hardware.gnss.gnss_assistance.RealTimeIntegrityModel;
+import android.hardware.gnss.gnss_assistance.TimeModel;
+import android.hardware.gnss.gnss_assistance.UtcModel;
+
+/**
+ * Contains GNSS assistance.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable GnssAssistance {
+    /** GNSS corrections for satellites. */
+    @VintfStability
+    parcelable GnssSatelliteCorrections {
+        /**
+         * Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle (SV), or
+         * OSN number for Glonass. The distinction is made by looking at the constellation field.
+         * Values must be in the range of:
+         *
+         * - GPS:    1-32
+         * - GLONASS: 1-25
+         * - QZSS:    183-206
+         * - Galileo: 1-36
+         * - Beidou:  1-63
+         */
+        int svid;
+
+        /** Ionospheric corrections */
+        IonosphericCorrection[] ionosphericCorrections;
+    }
+
+    /** Contains GPS assistance. */
+    @VintfStability
+    parcelable GpsAssistance {
+        /** The GPS almanac. */
+        GnssAlmanac almanac;
+
+        /** The Klobuchar ionospheric model. */
+        KlobucharIonosphericModel ionosphericModel;
+
+        /** The UTC model. */
+        UtcModel utcModel;
+
+        /** The leap seconds model. */
+        LeapSecondsModel leapSecondsModel;
+
+        /** The array of time models. */
+        TimeModel[] timeModels;
+
+        /** The array of GPS ephemeris. */
+        GpsSatelliteEphemeris[] satelliteEphemeris;
+
+        /** The array of real time integrity models. */
+        RealTimeIntegrityModel[] realTimeIntegrityModels;
+
+        /** The array of GPS satellite corrections. */
+        GnssSatelliteCorrections[] satelliteCorrections;
+    }
+
+    /** Contains Galileo assistance. */
+    @VintfStability
+    parcelable GalileoAssistance {
+        /** The Galileo almanac. */
+        GnssAlmanac almanac;
+
+        /** The Galileo ionospheric model. */
+        GalileoIonosphericModel ionosphericModel;
+
+        /** The UTC model. */
+        UtcModel utcModel;
+
+        /** The leap seconds model. */
+        LeapSecondsModel leapSecondsModel;
+
+        /** The array of time models. */
+        TimeModel[] timeModels;
+
+        /** The array of Galileo ephemeris. */
+        GalileoSatelliteEphemeris[] satelliteEphemeris;
+
+        /** The array of real time integrity models. */
+        RealTimeIntegrityModel[] realTimeIntegrityModels;
+
+        /** The array of Galileo satellite corrections. */
+        GnssSatelliteCorrections[] satelliteCorrections;
+    }
+
+    /** Contains Glonass assistance. */
+    @VintfStability
+    parcelable GlonassAssistance {
+        /** The Glonass almanac. */
+        GlonassAlmanac almanac;
+
+        /** The UTC model. */
+        UtcModel utcModel;
+
+        /** The array of time models. */
+        TimeModel[] timeModels;
+
+        /** The array of Glonass ephemeris. */
+        GlonassSatelliteEphemeris[] satelliteEphemeris;
+
+        /** The array of Glonass satellite corrections. */
+        GnssSatelliteCorrections[] satelliteCorrections;
+    }
+
+    /** Contains QZSS assistance. */
+    @VintfStability
+    parcelable QzssAssistance {
+        /** The QZSS almanac. */
+        GnssAlmanac almanac;
+
+        /** The Klobuchar ionospheric model. */
+        KlobucharIonosphericModel ionosphericModel;
+
+        /** The UTC model. */
+        UtcModel utcModel;
+
+        /** The leap seconds model. */
+        LeapSecondsModel leapSecondsModel;
+
+        /** The array of time models. */
+        TimeModel[] timeModels;
+
+        /** The array of QZSS ephemeris. */
+        QzssSatelliteEphemeris[] satelliteEphemeris;
+
+        /** The array of real time integrity models. */
+        RealTimeIntegrityModel[] realTimeIntegrityModels;
+
+        /** The array of QZSS satellite corrections. */
+        GnssSatelliteCorrections[] satelliteCorrections;
+    }
+
+    /** Contains Beidou assistance. */
+    @VintfStability
+    parcelable BeidouAssistance {
+        /** The Beidou almanac. */
+        GnssAlmanac almanac;
+
+        /** The Klobuchar ionospheric model. */
+        KlobucharIonosphericModel ionosphericModel;
+
+        /** The UTC model. */
+        UtcModel utcModel;
+
+        /** The leap seconds model. */
+        LeapSecondsModel leapSecondsModel;
+
+        /** The array of time models. */
+        TimeModel[] timeModels;
+
+        /** The array of Beidou ephemeris. */
+        BeidouSatelliteEphemeris[] satelliteEphemeris;
+
+        /** The array of real time integrity models. */
+        RealTimeIntegrityModel[] realTimeIntegrityModels;
+
+        /** The array of Beidou satellite corrections. */
+        GnssSatelliteCorrections[] satelliteCorrections;
+    }
+
+    /** GPS assistance. */
+    GpsAssistance gpsAssistance;
+
+    /** Glonass assistance. */
+    GlonassAssistance glonassAssistance;
+
+    /** Galileo assistance. */
+    GalileoAssistance galileoAssistance;
+
+    /** Beidou assistance. */
+    BeidouAssistance beidouAssistance;
+
+    /** QZSS assistance. */
+    QzssAssistance qzssAssistance;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssCorrectionComponent.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssCorrectionComponent.aidl
new file mode 100644
index 0000000..445727f
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GnssCorrectionComponent.aidl
@@ -0,0 +1,64 @@
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Gnss correction associated with a component (e.g. the Ionospheric error).
+ *
+ * @hide
+ */
+@VintfStability
+parcelable GnssCorrectionComponent {
+    /**
+     * Uniquely identifies the source of correction (e.g. "Klobuchar" for
+     * ionospheric corrections).
+     * Clients should not depend on the value of the source key but, rather,
+     * can compare before/after to detect changes.
+     */
+    String sourceKey;
+
+    /**
+     * Time interval referenced against the GPS epoch. The start must be less than
+     * or equal to the end. When the start equals the end, the interval is empty.
+     */
+    @VintfStability
+    parcelable GnssInterval {
+        /**
+         * Inclusive start of the interval in milliseconds since the GPS epoch.
+         * A timestamp matching this interval will have to be the same or after the
+         * start. Required as a reference time for the initial correction value and
+         * its rate of change over time.
+         */
+        long startMillisSinceGpsEpoch;
+
+        /**
+         * Exclusive end of the interval in milliseconds since the GPS epoch. If
+         * specified, a timestamp matching this interval will have to be before the
+         * end.
+         */
+        long endMillisSinceGpsEpoch;
+    }
+
+    /** The correction is only applicable during this time interval. */
+    GnssInterval validityInterval;
+
+    /** Pseudorange correction. */
+    @VintfStability
+    parcelable PseudorangeCorrection {
+        /* Correction to be added to the measured pseudorange, in meters. */
+        double correctionMeters;
+
+        /* Uncertainty of the correction, in meters. */
+        double correctionUncertaintyMeters;
+
+        /**
+         * Linear approximation of the change in correction over time. Intended
+         * usage is to adjust the correction using the formula:
+         *   correctionMeters + correctionRateMetersPerSecond * delta_seconds
+         * Where `delta_seconds` is the number of elapsed seconds since the beginning
+         * of the correction validity interval.
+         */
+        double correctionRateMetersPerSecond;
+    }
+
+    /* Pseudorange correction. */
+    PseudorangeCorrection pseudorangeCorrection;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/GpsSatelliteEphemeris.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/GpsSatelliteEphemeris.aidl
new file mode 100644
index 0000000..ab38030
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/GpsSatelliteEphemeris.aidl
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.gnss_assistance.KeplerianOrbitModel;
+import android.hardware.gnss.gnss_assistance.SatelliteEphemerisTime;
+
+/**
+ * Contains ephemeris parameters specific to GPS satellites.
+ * This is defined in IS-GPS-200, section 20.3.3.3.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable GpsSatelliteEphemeris {
+    /** Satellite PRN */
+    int prn;
+
+    /* Contains information about L2 params. */
+    @VintfStability
+    parcelable GpsL2Params {
+        /** Code(s) on L2 Channel. */
+        int l2Code;
+
+        /** Data Flag for L2 P-Code. */
+        int l2Flag;
+    }
+
+    /** L2 parameters. */
+    GpsL2Params gpsL2Params;
+
+    /** Contains the set of parameters needed for GPS satellite clock correction. */
+    @VintfStability
+    parcelable GpsSatelliteClockModel {
+        /**
+         * Time of the clock in seconds since GPS epoch.
+         *
+         * Represents the 'Epoch' field within the 'SV/EPOCH/SV CLK' record of GNSS
+         * navigation message file in RINEX 3.05 Table A6.
+         */
+        long timeOfClockSeconds;
+
+        /** SV clock bias in seconds. */
+        double af0;
+
+        /** SV clock drift in seconds per second. */
+        double af1;
+
+        /** Clock drift rate in seconds per second squared. */
+        double af2;
+
+        /** Group delay differential in seconds. */
+        double tgd;
+
+        /** Issue of data, clock. */
+        int iodc;
+    }
+
+    /** Clock model. */
+    GpsSatelliteClockModel satelliteClockModel;
+
+    /** Orbit model. */
+    KeplerianOrbitModel satelliteOrbitModel;
+
+    /**
+     * Contains information about GPS health. The information is tied to
+     * Legacy Navigation (LNAV) data, not Civil Navigation (CNAV) data.
+     */
+    @VintfStability
+    parcelable GpsSatelliteHealth {
+        /**
+         * Represents "SV health" in the "BROADCAST ORBIT - 6"
+         * record of RINEX 3.05. Table A6, pp.68.
+         */
+        int svHealth;
+
+        /**
+         * Represents "SV accuracy" in meters in the "BROADCAST ORBIT - 6"
+         * record of RINEX 3.05. Table A6, pp.68.
+         */
+        double svAccur;
+
+        /**
+         * Represents the "Fit Interval" in hours in the "BROADCAST ORBIT - 7"
+         * record of RINEX 3.05. Table A6, pp.69.
+         */
+        double fitInt;
+    }
+
+    /** Satellite health. */
+    GpsSatelliteHealth satelliteHealth;
+
+    /** Ephemeris time. */
+    SatelliteEphemerisTime satelliteEphemerisTime;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/IGnssAssistanceCallback.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/IGnssAssistanceCallback.aidl
new file mode 100644
index 0000000..883189c
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/IGnssAssistanceCallback.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * The callback interface for GNSS HAL to request GNSS assistance data
+ * (ephemeris and ionospheric corrections) from the framework.
+ *
+ * @hide
+ */
+@VintfStability
+interface IGnssAssistanceCallback {
+    /**
+     * Callback to request the framework to inject GNSS assistance data via
+     * IGnssAssistanceInterface.
+     */
+    void injectRequestCb();
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/IGnssAssistanceInterface.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/IGnssAssistanceInterface.aidl
new file mode 100644
index 0000000..2097e1e
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/IGnssAssistanceInterface.aidl
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.gnss_assistance.GnssAssistance;
+import android.hardware.gnss.gnss_assistance.IGnssAssistanceCallback;
+
+/**
+ * Interface used by the GNSS HAL to request the GNSS assistance data
+ * (ephemeris and ionospheric corrections) from the framework.
+ *
+ * The GNSS chipset uses the injected assistance data in the process of computing
+ * the user position for satellite position computation and error corrections.
+ *
+ * The framework ensures the assistance data is valid. GNSS HAL should request the
+ * data when it's engine lacks valid assistance data.
+ *
+ * @hide
+ */
+@VintfStability
+interface IGnssAssistanceInterface {
+    /**
+     * Inject the GNSS assistance into the GNSS receiver.
+     *
+     * @param gnssAssistance GNSS assistance.
+     */
+    void injectGnssAssistance(in GnssAssistance gnssAssistance);
+
+    /**
+     * Provides the callback routines to request the GNSS assistance.
+     *
+     * @param callback Handle to the IGnssAssistanceCallback interface.
+     */
+    void setCallback(in IGnssAssistanceCallback callback);
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/IonosphericCorrection.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/IonosphericCorrection.aidl
new file mode 100644
index 0000000..fe6b63d
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/IonosphericCorrection.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.gnss_assistance.GnssCorrectionComponent;
+
+/**
+ * Contains Ionospheric correction.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable IonosphericCorrection {
+    /**
+     * Carrier frequency in Hz to differentiate signals from the same satellite.
+     * e.g. GPS L1/L5
+     */
+    long carrierFrequencyHz;
+
+    /** Ionospheric correction component. */
+    GnssCorrectionComponent ionosphericCorrectionComponent;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/KeplerianOrbitModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/KeplerianOrbitModel.aidl
new file mode 100644
index 0000000..441b61d
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/KeplerianOrbitModel.aidl
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains Keplerian orbit model parameters for GPS/Galileo/QZSS/Beidou.
+ * For GPS, this is defined in IS-GPS-200 Table 20-II.
+ * For Galileo, this is defined in Galileo-OS-SIS-ICD-v2.1 5.1.1.
+ * For QZSS, this is defined in IS-QZSS-PNT section 4.1.2.
+ * For Baidou, this is defined in BDS-SIS-ICD-B1I-3.0 section 5.2.4.12.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable KeplerianOrbitModel {
+    /** Square root of the semi-major axis in square root of meters. */
+    double rootA;
+
+    /** Eccentricity. */
+    double eccentricity;
+
+    /** Inclination angle at reference time in radians. */
+    double i0;
+
+    /** Rate of change of inclination angle in radians per second. */
+    double iDot;
+
+    /** Argument of perigee in radians. */
+    double omega;
+
+    /** Longitude of ascending node of orbit plane at beginning of week in radians. */
+    double omega0;
+
+    /** Rate of right ascension in radians per second. */
+    double omegaDot;
+
+    /** Mean anomaly at reference time in radians. */
+    double m0;
+
+    /** Mean motion difference from computed value in radians per second. */
+    double deltaN;
+
+    /**
+     * Contains second-order harmonic perturbations.
+     */
+    @VintfStability
+    parcelable SecondOrderHarmonicPerturbation {
+        /** Amplitude of cosine harmonic correction term to angle of inclination in radians. */
+        double cic;
+
+        /** Amplitude of sine harmonic correction term to angle of inclination in radians. */
+        double cis;
+
+        /** Amplitude of cosine harmonic correction term to the orbit in meters. */
+        double crc;
+
+        /** Amplitude of sine harmonic correction term to the orbit in meters. */
+        double crs;
+
+        /** Amplitude of cosine harmonic correction term to the argument of latitude in radians. */
+        double cuc;
+
+        /** Amplitude of sine harmonic correction term to the argument of latitude in radians. */
+        double cus;
+    }
+
+    /** Second-order harmonic perturbations. */
+    SecondOrderHarmonicPerturbation secondOrderHarmonicPerturbation;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
new file mode 100644
index 0000000..e261e97
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/KlobucharIonosphericModel.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains Klobuchar ionospheric model coefficients used by GPS, BDS, QZSS.
+ * This is defined in IS-GPS-200 20.3.3.5.1.7.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable KlobucharIonosphericModel {
+    /** Alpha0 coefficient in seconds. */
+    double alpha0;
+
+    /** Alpha1 coefficient in seconds per semi-circle. */
+    double alpha1;
+
+    /** Alpha2 coefficient in seconds per semi-circle squared. */
+    double alpha2;
+
+    /** Alpha3 coefficient in seconds per semi-circle cubed. */
+    double alpha3;
+
+    /** Beta0 coefficient in seconds. */
+    double beta0;
+
+    /** Beta1 coefficient in seconds per semi-circle. */
+    double beta1;
+
+    /** Beta2 coefficient in seconds per semi-circle squared. */
+    double beta2;
+
+    /** Beta3 coefficient in seconds per semi-circle cubed. */
+    double beta3;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
new file mode 100644
index 0000000..0ebd46d
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/LeapSecondsModel.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains the leap seconds set of parameters needed for GNSS time.
+ * This is defined in RINEX 3.05 "LEAP SECONDS" in table A2.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable LeapSecondsModel {
+    /** Time difference due to leap seconds before the event in seconds. */
+    int leapSeconds;
+
+    /** Time difference due to leap seconds after the event in seconds. */
+    int leapSecondsFuture;
+
+    /** GNSS week number in which the leap second event will occur. */
+    int weekNumberLeapSecondsFuture;
+
+    /** Day number when the next leap second will occur. */
+    int dayNumberLeapSecondsFuture;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/QzssSatelliteEphemeris.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/QzssSatelliteEphemeris.aidl
new file mode 100644
index 0000000..a5a22d0
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/QzssSatelliteEphemeris.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsL2Params;
+import android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsSatelliteClockModel;
+import android.hardware.gnss.gnss_assistance.GpsSatelliteEphemeris.GpsSatelliteHealth;
+import android.hardware.gnss.gnss_assistance.KeplerianOrbitModel;
+import android.hardware.gnss.gnss_assistance.SatelliteEphemerisTime;
+
+/**
+ * Contains ephemeris parameters specific to QZSS satellites.
+ * This is defined in IS-QZSS-PNT, section 4.1.2.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable QzssSatelliteEphemeris {
+    /** Satellite PRN. */
+    int prn;
+
+    /** L2 parameters. */
+    GpsL2Params gpsL2Params;
+
+    /** Clock model. */
+    GpsSatelliteClockModel satelliteClockModel;
+
+    /** Orbit model. */
+    KeplerianOrbitModel satelliteOrbitModel;
+
+    /** Satellite health. */
+    GpsSatelliteHealth satelliteHealth;
+
+    /** Ephemeris time. */
+    SatelliteEphemerisTime satelliteEphemerisTime;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/RealTimeIntegrityModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/RealTimeIntegrityModel.aidl
new file mode 100644
index 0000000..10a511f
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/RealTimeIntegrityModel.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains the real time integrity status of a GNSS satellite based on
+ * notice advisory.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable RealTimeIntegrityModel {
+    /**
+     * Pseudo-random or satellite ID number for the satellite, a.k.a. Space Vehicle (SV), or
+     * OSN number for Glonass. The distinction is made by looking at the constellation field.
+     * Values must be in the range of:
+     *
+     * - GPS:    1-32
+     * - GLONASS: 1-25
+     * - QZSS:    183-206
+     * - Galileo: 1-36
+     * - Beidou:  1-63
+     */
+    int svid;
+
+    /** Indicates whether the satellite is currently usable for navigation. */
+    boolean usable;
+
+    /** UTC timestamp (in seconds) when the advisory was published. */
+    long publishDateSeconds;
+
+    /** UTC timestamp (in seconds) for the start of the event. */
+    long startDateSeconds;
+
+    /** UTC timestamp (in seconds) for the end of the event. */
+    long endDateSeconds;
+
+    /**
+     * Abbreviated type of the advisory, providing a concise summary of the event.
+     * This field follows different definitions depending on the GNSS constellation:
+     *  - GPS: See NANU type definitions
+     *    (https://www.navcen.uscg.gov/nanu-abbreviations-and-descriptions)
+     *  - Galileo: See NAGU type definitions
+     *    (https://www.gsc-europa.eu/system-service-status/nagu-information)
+     *  - QZSS: See NAQU type definitions (https://sys.qzss.go.jp/dod/en/naqu/type.html)
+     *  - BeiDou: Not used; set to an empty string.
+     */
+    String advisoryType;
+
+    /**
+     *  Unique identifier for the advisory within its constellation's system.
+     *  For BeiDou, this is not used and should be an empty string.
+     */
+    String advisoryNumber;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/SatelliteEphemerisTime.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/SatelliteEphemerisTime.aidl
new file mode 100644
index 0000000..8849401
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/SatelliteEphemerisTime.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains time of ephemeris.
+ *
+ * For GPS, this is defined in IS-GPS-200, section 20.3.3.4.1.
+ * For QZSS, this is defined in IS-QZSS-200, section 4.1.2.4.
+ * @hide
+ */
+@VintfStability
+parcelable SatelliteEphemerisTime {
+    /** The issue of ephemeris data. */
+    int iode;
+
+    /** The satellite week number without rollover. */
+    int weekNumber;
+
+    /** The broadcast time of ephemeris in GNSS time of week in seconds. */
+    int toeSeconds;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/TimeModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/TimeModel.aidl
new file mode 100644
index 0000000..8804f02
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/TimeModel.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+import android.hardware.gnss.GnssConstellationType;
+
+/*
+ * Contains the GNSS-GNSS system time offset between the GNSS system time.
+ * This is defined in RINEX 3.05 "TIME SYSTEM CORR" in table A5.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable TimeModel {
+    /*
+     * Model represents parameters to convert from current GNSS to GNSS system
+     * time indicated by toGnss.
+     */
+    GnssConstellationType toGnss;
+
+    /** Bias coefficient of GNSS time scale relative to GNSS time scale in seconds. */
+    double a0;
+
+    /** Drift coefficient of GNSS time scale relative to GNSS time scale in seconds per second. */
+    double a1;
+
+    /** Reference GNSS time of week in seconds. */
+    int timeOfWeek;
+
+    /** Reference GNSS week number. */
+    int weekNumber;
+}
diff --git a/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl b/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl
new file mode 100644
index 0000000..c16a711
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/gnss_assistance/UtcModel.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.gnss.gnss_assistance;
+
+/**
+ * Contains parameters to convert from current GNSS time to UTC time.
+ * This is defined in RINEX 3.05 "TIME SYSTEM CORR" in table A5.
+ *
+ * @hide
+ */
+@VintfStability
+parcelable UtcModel {
+    /** Bias coefficient of GNSS time scale relative to UTC time scale in seconds. */
+    double a0;
+
+    /** Drift coefficient of GNSS time scale relative to UTC time scale in seconds per second. */
+    double a1;
+
+    /** Reference GNSS time of week in seconds. */
+    int timeOfWeek;
+
+    /** Reference GNSS week number. */
+    int weekNumber;
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 822e8fc..efe2953 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -45,13 +45,14 @@
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.visibility_control@1.0",
-        "android.hardware.gnss-V4-ndk",
+        "android.hardware.gnss-V5-ndk",
     ],
     srcs: [
         "AGnssRil.cpp",
         "AGnss.cpp",
         "Gnss.cpp",
         "GnssAntennaInfo.cpp",
+        "GnssAssistanceInterface.cpp",
         "GnssBatching.cpp",
         "GnssDebug.cpp",
         "GnssGeofence.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 94d4d00..41720c0 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -25,6 +25,7 @@
 #include "DeviceFileReader.h"
 #include "FixLocationParser.h"
 #include "GnssAntennaInfo.h"
+#include "GnssAssistanceInterface.h"
 #include "GnssBatching.h"
 #include "GnssConfiguration.h"
 #include "GnssDebug.h"
@@ -122,10 +123,13 @@
             std::this_thread::sleep_for(std::chrono::milliseconds(TTFF_MILLIS));
             mFirstFixReceived = true;
         }
+        int reportGnssCount = 0;
         do {
             if (!mIsActive) {
+                ALOGD("Do not report location. mIsActive is false");
                 break;
             }
+            reportGnssCount += 1;
             if (!mGnssMeasurementEnabled || mMinIntervalMs <= mGnssMeasurementIntervalMs) {
                 this->reportSvStatus();
             }
@@ -140,6 +144,7 @@
                 this->reportLocation(location);
             }
         } while (mIsActive && mThreadBlocker.wait_for(std::chrono::milliseconds(mMinIntervalMs)));
+        ALOGD("reportGnssCount: %d", reportGnssCount);
     });
     return ScopedAStatus::ok();
 }
@@ -390,6 +395,14 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Gnss::getExtensionGnssAssistanceInterface(
+        std::shared_ptr<gnss_assistance::IGnssAssistanceInterface>* iGnssAssistanceInterface) {
+    ALOGD("Gnss::getExtensionGnssAssistanceInterface");
+
+    *iGnssAssistanceInterface = SharedRefBase::make<gnss_assistance::GnssAssistanceInterface>();
+    return ndk::ScopedAStatus::ok();
+}
+
 void Gnss::setGnssMeasurementEnabled(const bool enabled) {
     mGnssMeasurementEnabled = enabled;
 }
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 73085ef..56fe399 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -26,6 +26,7 @@
 #include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
 #include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
 #include <aidl/android/hardware/gnss/BnGnssPsds.h>
+#include <aidl/android/hardware/gnss/gnss_assistance/BnGnssAssistanceInterface.h>
 #include <aidl/android/hardware/gnss/measurement_corrections/BnMeasurementCorrectionsInterface.h>
 #include <aidl/android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h>
 #include <atomic>
@@ -83,6 +84,9 @@
             std::shared_ptr<android::hardware::gnss::measurement_corrections::
                                     IMeasurementCorrectionsInterface>* iMeasurementCorrections)
             override;
+    ndk::ScopedAStatus getExtensionGnssAssistanceInterface(
+            std::shared_ptr<android::hardware::gnss::gnss_assistance::IGnssAssistanceInterface>*
+                    iGnssAssistanceInterface) override;
 
     void reportSvStatus() const;
     void setGnssMeasurementEnabled(const bool enabled);
diff --git a/gnss/aidl/default/GnssAssistanceInterface.cpp b/gnss/aidl/default/GnssAssistanceInterface.cpp
new file mode 100644
index 0000000..2ef334c
--- /dev/null
+++ b/gnss/aidl/default/GnssAssistanceInterface.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GnssAssistanceInterfaceAidl"
+
+#include "GnssAssistanceInterface.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss::gnss_assistance {
+
+std::shared_ptr<IGnssAssistanceCallback> GnssAssistanceInterface::sCallback = nullptr;
+
+ndk::ScopedAStatus GnssAssistanceInterface::setCallback(
+        const std::shared_ptr<IGnssAssistanceCallback>& callback) {
+    ALOGD("setCallback");
+    std::unique_lock<std::mutex> lock(mMutex);
+    sCallback = callback;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssAssistanceInterface::injectGnssAssistance(
+        const GnssAssistance& gnssAssistance) {
+    ALOGD("injectGnssAssistance. %s", gnssAssistance.toString().c_str());
+    if (gnssAssistance.gpsAssistance.satelliteEphemeris.size() == 0 &&
+        gnssAssistance.gpsAssistance.satelliteCorrections.size() == 0) {
+        ALOGE("Empty GnssAssistance");
+        return ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_INVALID_ARGUMENT);
+    }
+    return ndk::ScopedAStatus::ok();
+}
+}  // namespace aidl::android::hardware::gnss::gnss_assistance
diff --git a/gnss/aidl/default/GnssAssistanceInterface.h b/gnss/aidl/default/GnssAssistanceInterface.h
new file mode 100644
index 0000000..9d92975
--- /dev/null
+++ b/gnss/aidl/default/GnssAssistanceInterface.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/gnss_assistance/BnGnssAssistanceInterface.h>
+
+namespace aidl::android::hardware::gnss::gnss_assistance {
+
+struct GnssAssistanceInterface : public BnGnssAssistanceInterface {
+  public:
+    ndk::ScopedAStatus setCallback(
+            const std::shared_ptr<IGnssAssistanceCallback>& callback) override;
+    ndk::ScopedAStatus injectGnssAssistance(const GnssAssistance& gnssAssistance) override;
+
+  private:
+    // Guarded by mMutex
+    static std::shared_ptr<IGnssAssistanceCallback> sCallback;
+
+    // Synchronization lock for sCallback
+    mutable std::mutex mMutex;
+};
+
+}  // namespace aidl::android::hardware::gnss::gnss_assistance
diff --git a/gnss/aidl/default/GnssDebug.cpp b/gnss/aidl/default/GnssDebug.cpp
index 5ae6edd..185bfe4 100644
--- a/gnss/aidl/default/GnssDebug.cpp
+++ b/gnss/aidl/default/GnssDebug.cpp
@@ -126,9 +126,46 @@
             .ephemerisAgeSeconds = 12,
             .serverPredictionIsAvailable = true,
             .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData10 = {
+            .svid = 2,
+            .constellation = GnssConstellationType::GALILEO,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData11 = {
+            .svid = 4,
+            .constellation = GnssConstellationType::GALILEO,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData12 = {
+            .svid = 10,
+            .constellation = GnssConstellationType::GALILEO,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData13 = {
+            .svid = 29,
+            .constellation = GnssConstellationType::GALILEO,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
     std::vector<SatelliteData> satelliteDataArrayDebug = {
-            satelliteData1, satelliteData2, satelliteData3, satelliteData4, satelliteData5,
-            satelliteData6, satelliteData7, satelliteData8, satelliteData9};
+            satelliteData1,  satelliteData2,  satelliteData3, satelliteData4, satelliteData5,
+            satelliteData6,  satelliteData7,  satelliteData8, satelliteData9, satelliteData10,
+            satelliteData11, satelliteData12, satelliteData13};
     debugData->position = positionDebug;
     debugData->time = timeDebug;
     debugData->satelliteDataArray = satelliteDataArrayDebug;
diff --git a/gnss/aidl/default/gnss-default.xml b/gnss/aidl/default/gnss-default.xml
index c01069e..700e240 100644
--- a/gnss/aidl/default/gnss-default.xml
+++ b/gnss/aidl/default/gnss-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.gnss</name>
-        <version>4</version>
+        <version>5</version>
         <interface>
             <name>IGnss</name>
             <instance>default</instance>
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 2bd6f07..20cf44f 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -52,7 +52,7 @@
         "libbinder",
     ],
     static_libs: [
-        "android.hardware.gnss-V4-cpp",
+        "android.hardware.gnss-V5-cpp",
         "android.hardware.gnss@common-vts-lib",
     ],
     test_suites: [
diff --git a/gnss/aidl/vts/gnss_hal_test.cpp b/gnss/aidl/vts/gnss_hal_test.cpp
index 0dd8b32..f7deb29 100644
--- a/gnss/aidl/vts/gnss_hal_test.cpp
+++ b/gnss/aidl/vts/gnss_hal_test.cpp
@@ -276,35 +276,43 @@
 }
 
 /*
- * FindStrongFrequentBlockableSource:
+ * FindStrongFrequentSource:
  *
- * Search through a GnssSvStatus list for the strongest blockable satellite observed enough times
+ * Search through a GnssSvStatus list for the strongest satellite observed enough times per
+ * constellation
  *
- * returns the strongest source,
- *         or a source with constellation == UNKNOWN if none are found sufficient times
+ * returns the strongest sources for each constellation,
+ *         or an empty vector if none are found sufficient times
  */
-BlocklistedSource GnssHalTest::FindStrongFrequentBlockableSource(
+std::vector<BlocklistedSource> GnssHalTest::FindStrongFrequentSources(
         const std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_list,
         const int min_observations) {
-    return FindStrongFrequentBlockableSource(convertToAidl(sv_info_list), min_observations);
+    return FindStrongFrequentSources(convertToAidl(sv_info_list), min_observations);
 }
 
-BlocklistedSource GnssHalTest::FindStrongFrequentBlockableSource(
+bool GnssHalTest::isBlockableConstellation(const GnssConstellationType constellation,
+                                           const bool isCnBuild) {
+    if (constellation == GnssConstellationType::GPS) {
+        return false;
+    }
+    if (isCnBuild && (constellation == GnssConstellationType::BEIDOU)) {
+        // Do not blocklist BDS on CN builds
+        return false;
+    }
+    return true;
+}
+
+std::vector<BlocklistedSource> GnssHalTest::FindStrongFrequentSources(
         const std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_list,
         const int min_observations) {
-    std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
+    ALOGD("Find strongest sv from %d sv_info_list with %d min_observations.",
+          (int)sv_info_list.size(), min_observations);
 
-    bool isCnBuild = Utils::isCnBuild();
-    ALOGD("isCnBuild: %s", isCnBuild ? "true" : "false");
+    std::map<ComparableBlocklistedSource, SignalCounts> mapSignals;
     for (const auto& sv_info_vec : sv_info_list) {
         for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
             const auto& gnss_sv = sv_info_vec[iSv];
-            if ((gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX) &&
-                (gnss_sv.constellation != GnssConstellationType::GPS)) {
-                if (isCnBuild && (gnss_sv.constellation == GnssConstellationType::BEIDOU)) {
-                    // Do not blocklist BDS on CN builds
-                    continue;
-                }
+            if (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX) {
                 ComparableBlocklistedSource source;
                 source.id.svid = gnss_sv.svid;
                 source.id.constellation = gnss_sv.constellation;
@@ -326,27 +334,76 @@
         }
     }
 
-    float max_cn0_dbhz_with_sufficient_count = 0.;
-    int total_observation_count = 0;
-    int blocklisted_source_count_observation = 0;
+    // the Cn0 of the strongest SV per constellation
+    std::unordered_map<GnssConstellationType, float> max_cn0_map;
+    // # of total observations of all signals per constellation
+    std::unordered_map<GnssConstellationType, int> total_observation_count_map;
+    // # of observations of the strongest sv per constellation
+    std::unordered_map<GnssConstellationType, int> source_observation_count_map;
+    // the source to blocklist per constellation
+    std::unordered_map<GnssConstellationType, ComparableBlocklistedSource> source_map;
+    // # of signals per constellation
+    std::unordered_map<GnssConstellationType, int> signal_count_map;
 
-    ComparableBlocklistedSource source_to_blocklist;  // initializes to zero = UNKNOWN constellation
     for (auto const& pairSignal : mapSignals) {
-        total_observation_count += pairSignal.second.observations;
-        if ((pairSignal.second.observations >= min_observations) &&
-            (pairSignal.second.max_cn0_dbhz > max_cn0_dbhz_with_sufficient_count)) {
-            source_to_blocklist = pairSignal.first;
-            blocklisted_source_count_observation = pairSignal.second.observations;
-            max_cn0_dbhz_with_sufficient_count = pairSignal.second.max_cn0_dbhz;
+        ComparableBlocklistedSource source = pairSignal.first;
+        total_observation_count_map[source.id.constellation] += pairSignal.second.observations;
+        signal_count_map[source.id.constellation]++;
+        if (pairSignal.second.observations < min_observations) {
+            continue;
+        }
+        if (pairSignal.second.max_cn0_dbhz > max_cn0_map[source.id.constellation]) {
+            source_map[source.id.constellation] = pairSignal.first;
+            source_observation_count_map[source.id.constellation] = pairSignal.second.observations;
+            max_cn0_map[source.id.constellation] = pairSignal.second.max_cn0_dbhz;
         }
     }
-    ALOGD("Among %d observations, chose svid %d, constellation %d, "
-          "with %d observations at %.1f max CNo",
-          total_observation_count, source_to_blocklist.id.svid,
-          (int)source_to_blocklist.id.constellation, blocklisted_source_count_observation,
-          max_cn0_dbhz_with_sufficient_count);
 
-    return source_to_blocklist.id;
+    std::vector<BlocklistedSource> sources;
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 4) {
+        /* For AIDL version <= 4 (launched-in-15 or earlier), only blocklist 1 sv */
+        float max_cn0 = 0;
+        ComparableBlocklistedSource source_to_blocklist;
+        for (auto const& pair : source_map) {
+            GnssConstellationType constellation = pair.first;
+            ComparableBlocklistedSource source = pair.second;
+            if (max_cn0_map[constellation] > max_cn0) {
+                max_cn0 = max_cn0_map[constellation];
+                source_to_blocklist = source;
+            }
+        }
+        if (source_to_blocklist.id.constellation != GnssConstellationType::UNKNOWN) {
+            ALOGD("In constellation %d, among %d observed SVs, svid %d is chosen to blocklist. "
+                  "It has %d observations with max Cn0: %.1f among %d total observations of this "
+                  "constellation.",
+                  (int)source_to_blocklist.id.constellation,
+                  signal_count_map[source_to_blocklist.id.constellation],
+                  source_to_blocklist.id.svid,
+                  source_observation_count_map[source_to_blocklist.id.constellation], max_cn0,
+                  total_observation_count_map[source_to_blocklist.id.constellation]);
+            sources.push_back(source_to_blocklist.id);
+        }
+    } else {
+        /* For AIDL version >= 5 (launched-in-16 or later), blocklist 1 sv per constellation */
+        for (auto const& pair : source_map) {
+            ComparableBlocklistedSource source = pair.second;
+            if (signal_count_map[source.id.constellation] < 4) {
+                // Skip the constellation with a small number of signals
+                // 4 is arbitrarily chosen to avoid affecting constellations with a limited coverage
+                continue;
+            }
+            ALOGD("In constellation %d, among %d observed SVs, svid %d is chosen to blocklist. "
+                  "It has %d observations with max Cn0: %.1f among %d total observations of this "
+                  "constellation.",
+                  (int)source.id.constellation, signal_count_map[source.id.constellation],
+                  source.id.svid, source_observation_count_map[source.id.constellation],
+                  max_cn0_map[source.id.constellation],
+                  total_observation_count_map[source.id.constellation]);
+            sources.push_back(source.id);
+        }
+    }
+
+    return sources;
 }
 
 GnssConstellationType GnssHalTest::startLocationAndGetBlockableConstellation(
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index dec5856..c41620a 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -81,14 +81,17 @@
     std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>> convertToAidl(
             const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>&
                     sv_info_list);
-    android::hardware::gnss::BlocklistedSource FindStrongFrequentBlockableSource(
+    std::vector<android::hardware::gnss::BlocklistedSource> FindStrongFrequentSources(
             const std::list<hidl_vec<android::hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>>
                     sv_info_list,
             const int min_observations);
-    android::hardware::gnss::BlocklistedSource FindStrongFrequentBlockableSource(
+    std::vector<android::hardware::gnss::BlocklistedSource> FindStrongFrequentSources(
             const std::list<std::vector<android::hardware::gnss::IGnssCallback::GnssSvInfo>>
                     sv_info_list,
             const int min_observations);
+    bool isBlockableConstellation(
+            const android::hardware::gnss::GnssConstellationType constellation,
+            const bool isCnBuild);
 
     void checkGnssMeasurementClockFields(const android::hardware::gnss::GnssData& measurement);
     void checkGnssMeasurementFlags(const android::hardware::gnss::GnssMeasurement& measurement);
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index e4890a7..781476fd 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -25,6 +25,7 @@
 #include <android/hardware/gnss/IGnssMeasurementInterface.h>
 #include <android/hardware/gnss/IGnssPowerIndication.h>
 #include <android/hardware/gnss/IGnssPsds.h>
+#include <android/hardware/gnss/gnss_assistance/IGnssAssistanceInterface.h>
 #include <android/hardware/gnss/measurement_corrections/IMeasurementCorrectionsInterface.h>
 #include <android/hardware/gnss/visibility_control/IGnssVisibilityControl.h>
 #include <cutils/properties.h>
@@ -73,6 +74,8 @@
 using android::hardware::gnss::PsdsType;
 using android::hardware::gnss::SatellitePvt;
 using android::hardware::gnss::common::Utils;
+using android::hardware::gnss::gnss_assistance::GnssAssistance;
+using android::hardware::gnss::gnss_assistance::IGnssAssistanceInterface;
 using android::hardware::gnss::measurement_corrections::IMeasurementCorrectionsInterface;
 using android::hardware::gnss::visibility_control::IGnssVisibilityControl;
 
@@ -612,7 +615,7 @@
  * BlocklistIndividualSatellites:
  *
  * 1) Turns on location, waits for 3 locations, ensuring they are valid, and checks corresponding
- * GnssStatus for common satellites (strongest and one other.)
+ * GnssStatus for common satellites (strongest one in each constellation.)
  * 2a & b) Turns off location, and blocklists common satellites.
  * 3) Restart location, wait for 3 locations, ensuring they are valid, and checks corresponding
  * GnssStatus does not use those satellites.
@@ -630,6 +633,7 @@
         return;
     }
 
+    const int kWarmUpLocations = 3;
     const int kLocationsToAwait = 3;
     const int kRetriesToUnBlocklist = 10;
 
@@ -638,7 +642,7 @@
     } else {
         aidl_gnss_cb_->location_cbq_.reset();
     }
-    StartAndCheckLocations(kLocationsToAwait);
+    StartAndCheckLocations(kLocationsToAwait + kWarmUpLocations);
     int location_called_count = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
                                         ? gnss_cb_->location_cbq_.calledCount()
                                         : aidl_gnss_cb_->location_cbq_.calledCount();
@@ -647,37 +651,50 @@
     int sv_info_list_cbq_size = (aidl_gnss_hal_->getInterfaceVersion() <= 1)
                                         ? gnss_cb_->sv_info_list_cbq_.size()
                                         : aidl_gnss_cb_->sv_info_list_cbq_.size();
-    EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
+    EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait + kWarmUpLocations);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
-          sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+          sv_info_list_cbq_size, kLocationsToAwait + kWarmUpLocations, location_called_count);
 
     /*
-     * Identify strongest SV seen at least kLocationsToAwait -1 times
-     * Why -1?  To avoid test flakiness in case of (plausible) slight flakiness in strongest signal
-     * observability (one epoch RF null)
+     * Identify strongest SV per constellation seen seen at least kLocationsToAwait -1 times.
+     *
+     * Why not (kLocationsToAwait + kWarmUpLocations)?  To avoid test flakiness in case of
+     * (plausible) slight flakiness in strongest signal observability (one epoch RF null)
      */
 
     const int kGnssSvInfoListTimeout = 2;
-    BlocklistedSource source_to_blocklist;
+    std::vector<BlocklistedSource> sources_to_blocklist;
     if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
+        // Discard kWarmUpLocations sv_info_vec
+        std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> tmp;
+        int count =
+                gnss_cb_->sv_info_list_cbq_.retrieve(tmp, kWarmUpLocations, kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, kWarmUpLocations);
+
+        // Retrieve (sv_info_list_cbq_size - kWarmUpLocations) sv_info_vec
         std::list<hidl_vec<IGnssCallback_2_1::GnssSvInfo>> sv_info_vec_list;
-        int count = gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec_list, sv_info_list_cbq_size,
-                                                         kGnssSvInfoListTimeout);
-        ASSERT_EQ(count, sv_info_list_cbq_size);
-        source_to_blocklist =
-                FindStrongFrequentBlockableSource(sv_info_vec_list, kLocationsToAwait - 1);
+        count = gnss_cb_->sv_info_list_cbq_.retrieve(
+                sv_info_vec_list, sv_info_list_cbq_size - kWarmUpLocations, kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, sv_info_list_cbq_size - kWarmUpLocations);
+        sources_to_blocklist = FindStrongFrequentSources(sv_info_vec_list, kLocationsToAwait - 1);
     } else {
+        // Discard kWarmUpLocations sv_info_vec
+        std::list<std::vector<IGnssCallback::GnssSvInfo>> tmp;
+        int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(tmp, kWarmUpLocations,
+                                                              kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, kWarmUpLocations);
+
+        // Retrieve (sv_info_list_cbq_size - kWarmUpLocations) sv_info_vec
         std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_vec_list;
-        int count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
-                sv_info_vec_list, sv_info_list_cbq_size, kGnssSvInfoListTimeout);
-        ASSERT_EQ(count, sv_info_list_cbq_size);
-        source_to_blocklist =
-                FindStrongFrequentBlockableSource(sv_info_vec_list, kLocationsToAwait - 1);
+        count = aidl_gnss_cb_->sv_info_list_cbq_.retrieve(
+                sv_info_vec_list, sv_info_list_cbq_size - kWarmUpLocations, kGnssSvInfoListTimeout);
+        ASSERT_EQ(count, sv_info_list_cbq_size - kWarmUpLocations);
+        sources_to_blocklist = FindStrongFrequentSources(sv_info_vec_list, kLocationsToAwait - 1);
     }
 
-    if (source_to_blocklist.constellation == GnssConstellationType::UNKNOWN) {
-        // Cannot find a blockable satellite. Let the test pass.
-        ALOGD("Cannot find a blockable satellite. Letting the test pass.");
+    if (sources_to_blocklist.empty()) {
+        // Cannot find a satellite to blocklist. Let the test pass.
+        ALOGD("Cannot find a satellite to blocklist. Letting the test pass.");
         return;
     }
 
@@ -690,9 +707,7 @@
     ASSERT_NE(gnss_configuration_hal, nullptr);
 
     std::vector<BlocklistedSource> sources;
-    sources.resize(1);
-    sources[0] = source_to_blocklist;
-
+    sources = sources_to_blocklist;
     status = gnss_configuration_hal->setBlocklist(sources);
     ASSERT_TRUE(status.isOk());
 
@@ -723,26 +738,47 @@
     EXPECT_GE(sv_info_list_cbq_size + 1, kLocationsToAwait);
     ALOGD("Observed %d GnssSvInfo, while awaiting %d Locations (%d received)",
           sv_info_list_cbq_size, kLocationsToAwait, location_called_count);
+    bool isCnBuild = Utils::isCnBuild();
     for (int i = 0; i < sv_info_list_cbq_size; ++i) {
         if (aidl_gnss_hal_->getInterfaceVersion() <= 1) {
             hidl_vec<IGnssCallback_2_1::GnssSvInfo> sv_info_vec;
             gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
                 auto& gnss_sv = sv_info_vec[iSv];
-                EXPECT_FALSE(
-                        (gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
-                        (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
-                         source_to_blocklist.constellation) &&
-                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX));
+                if (!(gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+                    continue;
+                }
+                for (auto const& source : sources_to_blocklist) {
+                    if (isBlockableConstellation(source.constellation, isCnBuild)) {
+                        EXPECT_FALSE((gnss_sv.v2_0.v1_0.svid == source.svid) &&
+                                     (static_cast<GnssConstellationType>(
+                                              gnss_sv.v2_0.constellation) == source.constellation));
+                    } else if ((gnss_sv.v2_0.v1_0.svid == source.svid) &&
+                               (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
+                                source.constellation)) {
+                        ALOGW("Found constellation %d, svid %d blocklisted but still used-in-fix.",
+                              source.constellation, source.svid);
+                    }
+                }
             }
         } else {
             std::vector<IGnssCallback::GnssSvInfo> sv_info_vec;
             aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
             for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
                 auto& gnss_sv = sv_info_vec[iSv];
-                EXPECT_FALSE((gnss_sv.svid == source_to_blocklist.svid) &&
-                             (gnss_sv.constellation == source_to_blocklist.constellation) &&
-                             (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX));
+                if (!(gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+                    continue;
+                }
+                for (auto const& source : sources_to_blocklist) {
+                    if (isBlockableConstellation(source.constellation, isCnBuild)) {
+                        EXPECT_FALSE((gnss_sv.svid == source.svid) &&
+                                     (gnss_sv.constellation == source.constellation));
+                    } else if ((gnss_sv.svid == source.svid) &&
+                               (gnss_sv.constellation == source.constellation)) {
+                        ALOGW("Found constellation %d, svid %d blocklisted but still used-in-fix.",
+                              gnss_sv.constellation, gnss_sv.svid);
+                    }
+                }
             }
         }
     }
@@ -792,12 +828,15 @@
                 gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
                 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
                     auto& gnss_sv = sv_info_vec[iSv];
-                    if ((gnss_sv.v2_0.v1_0.svid == source_to_blocklist.svid) &&
-                        (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
-                         source_to_blocklist.constellation) &&
-                        (gnss_sv.v2_0.v1_0.svFlag & IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
-                        strongest_sv_is_reobserved = true;
-                        break;
+                    for (auto const& source : sources_to_blocklist) {
+                        if ((gnss_sv.v2_0.v1_0.svid == source.svid) &&
+                            (static_cast<GnssConstellationType>(gnss_sv.v2_0.constellation) ==
+                             source.constellation) &&
+                            (gnss_sv.v2_0.v1_0.svFlag &
+                             IGnssCallback_1_0::GnssSvFlags::USED_IN_FIX)) {
+                            strongest_sv_is_reobserved = true;
+                            break;
+                        }
                     }
                 }
             } else {
@@ -805,11 +844,13 @@
                 aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_vec, kGnssSvInfoListTimeout);
                 for (uint32_t iSv = 0; iSv < sv_info_vec.size(); iSv++) {
                     auto& gnss_sv = sv_info_vec[iSv];
-                    if ((gnss_sv.svid == source_to_blocklist.svid) &&
-                        (gnss_sv.constellation == source_to_blocklist.constellation) &&
-                        (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
-                        strongest_sv_is_reobserved = true;
-                        break;
+                    for (auto const& source : sources_to_blocklist) {
+                        if ((gnss_sv.svid == source.svid) &&
+                            (gnss_sv.constellation == source.constellation) &&
+                            (gnss_sv.svFlag & (int)IGnssCallback::GnssSvFlags::USED_IN_FIX)) {
+                            strongest_sv_is_reobserved = true;
+                            break;
+                        }
                     }
                 }
             }
@@ -1877,3 +1918,22 @@
         }
     }
 }
+
+/*
+ * Test GnssAssistanceExtension:
+ * 1. Gets the GnssAssistanceExtension
+ * 2. Injects empty GnssAssistance data and verifies that it returns an error.
+ */
+TEST_P(GnssHalTest, TestGnssAssistanceExtension) {
+    // Only runs on devices launched in Android 16+
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 4) {
+        return;
+    }
+    sp<IGnssAssistanceInterface> iGnssAssistance;
+    auto status = aidl_gnss_hal_->getExtensionGnssAssistanceInterface(&iGnssAssistance);
+    if (status.isOk() && iGnssAssistance != nullptr) {
+        GnssAssistance gnssAssistance = {};
+        status = iGnssAssistance->injectGnssAssistance(gnssAssistance);
+        ASSERT_FALSE(status.isOk());
+    }
+}
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 208bc59..e8c370a 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -57,6 +57,6 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.1",
         "android.hardware.gnss.measurement_corrections@1.0",
-        "android.hardware.gnss-V4-ndk",
+        "android.hardware.gnss-V5-ndk",
     ],
 }
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index 8303d93..740bc59 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -338,16 +338,25 @@
 
 std::vector<GnssSvInfo> Utils::getMockSvInfoList() {
     std::vector<GnssSvInfo> gnssSvInfoList = {
+            // svid in [1, 32] for GPS
             getMockSvInfo(3, GnssConstellationType::GPS, 32.5, 27.5, 59.1, 166.5, kGpsL1FreqHz),
             getMockSvInfo(5, GnssConstellationType::GPS, 27.0, 22.0, 29.0, 56.5, kGpsL1FreqHz),
             getMockSvInfo(17, GnssConstellationType::GPS, 30.5, 25.5, 71.0, 77.0, kGpsL5FreqHz),
             getMockSvInfo(26, GnssConstellationType::GPS, 24.1, 19.1, 28.0, 253.0, kGpsL5FreqHz),
+            // svid in [1, 36] for GAL
+            getMockSvInfo(2, GnssConstellationType::GALILEO, 33.5, 27.5, 59.1, 166.5, kGalE1FreqHz),
+            getMockSvInfo(4, GnssConstellationType::GALILEO, 28.0, 22.0, 29.0, 56.5, kGalE1FreqHz),
+            getMockSvInfo(10, GnssConstellationType::GALILEO, 35.5, 25.5, 71.0, 77.0, kGalE1FreqHz),
+            getMockSvInfo(29, GnssConstellationType::GALILEO, 34.1, 19.1, 28.0, 253.0,
+                          kGalE1FreqHz),
+            // "1 <= svid <= 25 || 93 <= svid <= 106" for GLO
             getMockSvInfo(5, GnssConstellationType::GLONASS, 20.5, 15.5, 11.5, 116.0, kGloG1FreqHz),
             getMockSvInfo(17, GnssConstellationType::GLONASS, 21.5, 16.5, 28.5, 186.0,
                           kGloG1FreqHz),
             getMockSvInfo(18, GnssConstellationType::GLONASS, 28.3, 25.3, 38.8, 69.0, kGloG1FreqHz),
             getMockSvInfo(10, GnssConstellationType::GLONASS, 25.0, 20.0, 66.0, 247.0,
                           kGloG1FreqHz),
+            // "1 <= X <= 14" for IRNSS
             getMockSvInfo(3, GnssConstellationType::IRNSS, 22.0, 19.7, 35.0, 112.0, kIrnssL5FreqHz),
     };
     return gnssSvInfoList;
diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h
index 489413e..e6605c4 100644
--- a/gnss/common/utils/default/include/Constants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -31,6 +31,7 @@
 const int64_t kMockTimestamp = 1519930775453L;
 const float kGpsL1FreqHz = 1575.42 * 1e6;
 const float kGpsL5FreqHz = 1176.45 * 1e6;
+const float kGalE1FreqHz = 1575.42 * 1e6;
 const float kGloG1FreqHz = 1602.0 * 1e6;
 const float kIrnssL5FreqHz = 1176.45 * 1e6;
 
diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp
index ed5674c..b8b048a 100644
--- a/gnss/common/utils/vts/Android.bp
+++ b/gnss/common/utils/vts/Android.bp
@@ -44,7 +44,7 @@
         "android.hardware.gnss@2.1",
         "android.hardware.gnss.measurement_corrections@1.0",
         "android.hardware.gnss.measurement_corrections@1.1",
-        "android.hardware.gnss-V4-cpp",
+        "android.hardware.gnss-V5-cpp",
     ],
     static_libs: [
         "libgtest",
diff --git a/graphics/Android.bp b/graphics/Android.bp
index cdeb2e6..2213f15 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -35,9 +35,13 @@
 
 cc_defaults {
     name: "android.hardware.graphics.allocator-ndk_static",
-    static_libs: [
-        "android.hardware.graphics.allocator-V2-ndk",
-    ],
+    target: {
+        linux: {
+            static_libs: [
+                "android.hardware.graphics.allocator-V2-ndk",
+            ],
+        },
+    },
     defaults: [
         "android.hardware.graphics.common-ndk_static",
     ],
@@ -45,9 +49,13 @@
 
 cc_defaults {
     name: "android.hardware.graphics.allocator-ndk_shared",
-    shared_libs: [
-        "android.hardware.graphics.allocator-V2-ndk",
-    ],
+    target: {
+        linux: {
+            shared_libs: [
+                "android.hardware.graphics.allocator-V2-ndk",
+            ],
+        },
+    },
     defaults: [
         "android.hardware.graphics.common-ndk_shared",
     ],
@@ -69,16 +77,24 @@
 
 cc_defaults {
     name: "android.hardware.graphics.common-ndk_static",
-    static_libs: [
-        "android.hardware.graphics.common-V6-ndk",
-    ],
+    target: {
+        linux: {
+            static_libs: [
+                "android.hardware.graphics.common-V6-ndk",
+            ],
+        },
+    },
 }
 
 cc_defaults {
     name: "android.hardware.graphics.common-ndk_shared",
-    shared_libs: [
-        "android.hardware.graphics.common-V6-ndk",
-    ],
+    target: {
+        linux: {
+            shared_libs: [
+                "android.hardware.graphics.common-V6-ndk",
+            ],
+        },
+    },
 }
 
 aidl_interface_defaults {
@@ -90,16 +106,24 @@
 
 cc_defaults {
     name: "android.hardware.graphics.composer3-ndk_static",
-    static_libs: [
-        "android.hardware.drm.common-V1-ndk",
-        "android.hardware.graphics.composer3-V4-ndk",
-    ],
+    target: {
+        linux: {
+            static_libs: [
+                "android.hardware.drm.common-V1-ndk",
+                "android.hardware.graphics.composer3-V4-ndk",
+            ],
+        },
+    },
 }
 
 cc_defaults {
     name: "android.hardware.graphics.composer3-ndk_shared",
-    shared_libs: [
-        "android.hardware.drm.common-V1-ndk",
-        "android.hardware.graphics.composer3-V4-ndk",
-    ],
+    target: {
+        linux: {
+            shared_libs: [
+                "android.hardware.drm.common-V1-ndk",
+                "android.hardware.graphics.composer3-V4-ndk",
+            ],
+        },
+    },
 }
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
index 6ed5bb2..7264a21 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/Dataspace.aidl
@@ -97,5 +97,6 @@
   JPEG_APP_SEGMENTS = 0x1003,
   HEIF = 0x1004,
   JPEG_R = 0x1005,
+  HEIF_ULTRAHDR = 0x1006,
   BT709_FULL_RANGE = (((1 << 16) | (3 << 22)) | (1 << 27)) /* 146866176 */,
 }
diff --git a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/DisplayHotplugEvent.aidl b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/DisplayHotplugEvent.aidl
index 63dca0a..b18d2be 100644
--- a/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/DisplayHotplugEvent.aidl
+++ b/graphics/common/aidl/aidl_api/android.hardware.graphics.common/current/android/hardware/graphics/common/DisplayHotplugEvent.aidl
@@ -39,4 +39,5 @@
   ERROR_UNKNOWN = (-1) /* -1 */,
   ERROR_INCOMPATIBLE_CABLE = (-2) /* -2 */,
   ERROR_TOO_MANY_DISPLAYS = (-3) /* -3 */,
+  ERROR_LINK_UNSTABLE = (-4) /* -4 */,
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
index 79737eb..8705aef 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/Dataspace.aidl
@@ -702,19 +702,32 @@
     /**
      * Ultra HDR
      *
-     * JPEG image with embedded 10-bit recovery map following the Ultra HDR specification.
+     * JPEG image with embedded HDR gain map following the Ultra HDR specification and
+     * ISO/CD 21496‐1
      *
      * This value must always remain aligned with the public ImageFormat Jpeg/R definition and is
      * valid with formats:
      *    HAL_PIXEL_FORMAT_BLOB: JPEG image encoded by Ultra HDR encoder according to
      *    the <a href="https://developer.android.com/guide/topics/media/hdr-image-format">
      *    Ultra HDR Image format specification</a>.
-     * The image contains a standard SDR JPEG and a recovery map. Ultra HDR decoders can use the
-     * map to recover the 10-bit input image.
+     * The image contains a standard SDR JPEG and a gain map. Ultra HDR decoders can use the
+     * map to boost the brightness of the rendered image.
      */
     JPEG_R = 0x1005,
 
     /**
+     * ISO/IEC 23008-12:2024
+     *
+     * High Efficiency Image File Format (HEIF) with embedded HDR gain map
+     *
+     * This value is valid with formats:
+     *    HAL_PIXEL_FORMAT_BLOB: A HEIC image encoded by HEIC or HEVC encoder
+     * according to ISO/IEC 23008-12:2024 that includes an HDR gain map and
+     * metadata according to ISO/CD 21496‐1.
+     */
+    HEIF_ULTRAHDR = 0x1006,
+
+    /**
      * ITU-R Recommendation 709 (BT.709)
      *
      * High-definition television
diff --git a/graphics/common/aidl/android/hardware/graphics/common/DisplayHotplugEvent.aidl b/graphics/common/aidl/android/hardware/graphics/common/DisplayHotplugEvent.aidl
index b35ada5..f779105 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/DisplayHotplugEvent.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/DisplayHotplugEvent.aidl
@@ -23,24 +23,31 @@
 @Backing(type="int")
 enum DisplayHotplugEvent {
     /**
-     * Display is successfully connected.
-     * Connected may be called more than once and the behavior of subsequent
-     * calls is that SurfaceFlinger queries the display properties again.
+     * Display was successfully connected.
+     * CONNECTED may be emitted more than once and the behavior of subsequent
+     * events is that SurfaceFlinger queries the display properties again.
      */
     CONNECTED = 0,
 
-    /** Display is successfully disconnected */
+    /** Display was successfully disconnected */
     DISCONNECTED = 1,
 
-    /** Display is plugged in, but an unknown error occurred */
+    /** Unknown error occurred */
     ERROR_UNKNOWN = -1,
 
-    /** Display is plugged in, but incompatible cable error detected */
+    /** Display was plugged in, but incompatible cable error detected */
     ERROR_INCOMPATIBLE_CABLE = -2,
 
     /**
-     * Display is plugged in, but exceeds the max number of
+     * Display was plugged in, but exceeds the max number of
      * displays that can be simultaneously connected
      */
     ERROR_TOO_MANY_DISPLAYS = -3,
+
+    /**
+     * Display link is unstable, e.g. link training failure (negotiation
+     * of connection speed failed), and the display needs to be
+     * reconfigured
+     */
+    ERROR_LINK_UNSTABLE = -4,
 }
diff --git a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
index 8cfdae6..e4da890 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/StandardMetadataType.aidl
@@ -282,7 +282,7 @@
      * When it is encoded into a byte stream, the total number of Rects is written using
      * 8 bytes in little endian. It is followed by each Rect.
      *
-     * To encode a Rect, write the following fields in this order each as 8 bytes in little endian:
+     * To encode a Rect, write the following fields in this order each as 4 bytes in little endian:
      * left, top, right and bottom.
      */
     CROP = 16,
diff --git a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
index cd47374..5b3a433 100644
--- a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
+++ b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
@@ -17,19 +17,13 @@
 #pragma once
 
 #ifndef LOG_TAG
-#warn "ComposerCommandBuffer.h included without LOG_TAG"
+#warning "ComposerCommandBuffer.h included without LOG_TAG"
 #endif
 
 //#define LOG_NDEBUG 0
 
-#include <algorithm>
-#include <limits>
-#include <memory>
 #include <vector>
 
-#include <inttypes.h>
-#include <string.h>
-
 #include <android/hardware/graphics/composer/2.2/IComposer.h>
 #include <android/hardware/graphics/composer/2.2/IComposerClient.h>
 #include <fmq/MessageQueue.h>
@@ -82,7 +76,7 @@
 
     void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
         beginCommand(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
-                     metadataVec.size() * 2);
+                     static_cast<uint16_t>(metadataVec.size() * 2));
         for (const auto& metadata : metadataVec) {
             writeSigned(static_cast<int32_t>(metadata.key));
             writeFloat(metadata.value);
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index 1a9276c..46d8d4a 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #ifndef LOG_TAG
-#warn "ComposerCommandBuffer.h included without LOG_TAG"
+#warning "ComposerCommandBuffer.h included without LOG_TAG"
 #endif
 
 //#define LOG_NDEBUG 0
@@ -46,7 +46,7 @@
    public:
     void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
         beginCommand(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
-                     metadataVec.size() * 2);
+                     static_cast<uint16_t>(metadataVec.size() * 2));
         for (const auto& metadata : metadataVec) {
             writeSigned(static_cast<int32_t>(metadata.key));
             writeFloat(metadata.value);
diff --git a/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h b/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
index e981da6..064fc57 100644
--- a/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
+++ b/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #ifndef LOG_TAG
-#warn "ComposerCommandBuffer.h included without LOG_TAG"
+#warning "ComposerCommandBuffer.h included without LOG_TAG"
 #endif
 
 //#define LOG_NDEBUG 0
@@ -63,16 +63,17 @@
 
         beginCommand(IComposerClient::Command::SET_LAYER_GENERIC_METADATA,
                      static_cast<uint16_t>(commandSize));
-        write(key.size());
-        writeBlob(key.size(), reinterpret_cast<const unsigned char*>(key.c_str()));
+        write(static_cast<uint32_t>(key.size()));
+        writeBlob(static_cast<uint32_t>(key.size()),
+                  reinterpret_cast<const unsigned char*>(key.c_str()));
         write(mandatory);
-        write(value.size());
-        writeBlob(value.size(), value.data());
+        write(static_cast<uint32_t>(value.size()));
+        writeBlob(static_cast<uint32_t>(value.size()), value.data());
         endCommand();
     }
 
   protected:
-    uint32_t sizeToElements(uint32_t size) { return (size + 3) / 4; }
+    uint32_t sizeToElements(size_t size) { return static_cast<uint32_t>((size + 3) / 4); }
 };
 
 // This class helps parse a command queue.  Note that all sizes/lengths are in
diff --git a/graphics/composer/aidl/Android.bp b/graphics/composer/aidl/Android.bp
index 719318a..655188d 100644
--- a/graphics/composer/aidl/Android.bp
+++ b/graphics/composer/aidl/Android.bp
@@ -77,7 +77,6 @@
                 "android.hardware.common-V2",
             ],
         },
-
     ],
 
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
index 0e2d72b..955ff89 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -43,4 +43,5 @@
   SUSPEND = 6,
   DISPLAY_IDLE_TIMER = 7,
   MULTI_THREADED_PRESENT = 8,
+  PICTURE_PROCESSING = 9,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
index cce35e7..9e24a26 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -46,4 +46,5 @@
   boolean presentDisplay;
   boolean presentOrValidateDisplay;
   int frameIntervalNs;
+  long pictureProfileId;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayConfiguration.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayConfiguration.aidl
index 040afd7..c522188 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayConfiguration.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayConfiguration.aidl
@@ -41,6 +41,7 @@
   int configGroup;
   int vsyncPeriod;
   @nullable android.hardware.graphics.composer3.VrrConfig vrrConfig;
+  android.hardware.graphics.composer3.OutputType hdrOutputType;
   parcelable Dpi {
     float x;
     float y;
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayIdentification.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayIdentification.aidl
index a0cc9b0..06f2dde 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayIdentification.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayIdentification.aidl
@@ -36,4 +36,5 @@
 parcelable DisplayIdentification {
   byte port;
   byte[] data;
+  android.hardware.graphics.composer3.ScreenPartStatus screenPartStatus = android.hardware.graphics.composer3.ScreenPartStatus.UNSUPPORTED;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
index 327e84c..4263140 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/DisplayLuts.aidl
@@ -38,6 +38,6 @@
   android.hardware.graphics.composer3.DisplayLuts.LayerLut[] layerLuts;
   parcelable LayerLut {
     long layer;
-    android.hardware.graphics.composer3.Lut lut;
+    android.hardware.graphics.composer3.Luts luts;
   }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index bc27cc7..1e568b9 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -87,6 +87,9 @@
   void setRefreshRateChangedCallbackDebugEnabled(long display, boolean enabled);
   android.hardware.graphics.composer3.DisplayConfiguration[] getDisplayConfigurations(long display, int maxFrameIntervalNs);
   oneway void notifyExpectedPresent(long display, in android.hardware.graphics.composer3.ClockMonotonicTimestamp expectedPresentTime, int frameIntervalNs);
+  int getMaxLayerPictureProfiles(long display);
+  oneway void startHdcpNegotiation(long display, in android.hardware.drm.HdcpLevels levels);
+  android.hardware.graphics.composer3.Luts[] getLuts(long display, in android.hardware.graphics.composer3.Buffer[] buffers);
   const int EX_BAD_CONFIG = 1;
   const int EX_BAD_DISPLAY = 2;
   const int EX_BAD_LAYER = 3;
@@ -97,5 +100,7 @@
   const int EX_UNSUPPORTED = 8;
   const int EX_SEAMLESS_NOT_ALLOWED = 9;
   const int EX_SEAMLESS_NOT_POSSIBLE = 10;
+  const int EX_CONFIG_FAILED = 11;
+  const int EX_PICTURE_PROFILE_MAX_EXCEEDED = 12;
   const int INVALID_CONFIGURATION = 0x7fffffff;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
index 8b2b13c..c26cb15 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -57,5 +57,6 @@
   @nullable int[] bufferSlotsToClear;
   android.hardware.graphics.composer3.LayerLifecycleBatchCommandType layerLifecycleBatchCommandType;
   int newBufferSlotCount;
-  @nullable android.hardware.graphics.composer3.Lut[] luts;
+  @nullable android.hardware.graphics.composer3.Luts luts;
+  long pictureProfileId;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LutProperties.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LutProperties.aidl
index 5edceb5..9516351 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LutProperties.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/LutProperties.aidl
@@ -35,7 +35,7 @@
 @VintfStability
 parcelable LutProperties {
   android.hardware.graphics.composer3.LutProperties.Dimension dimension;
-  long size;
+  int size;
   android.hardware.graphics.composer3.LutProperties.SamplingKey[] samplingKeys;
   @VintfStability
   enum Dimension {
@@ -46,5 +46,6 @@
   enum SamplingKey {
     RGB,
     MAX_RGB,
+    CIE_Y,
   }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luts.aidl
similarity index 93%
rename from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
rename to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luts.aidl
index 5fae35b..2890365 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Luts.aidl
@@ -33,7 +33,8 @@
 
 package android.hardware.graphics.composer3;
 @VintfStability
-parcelable Lut {
+parcelable Luts {
   @nullable ParcelFileDescriptor pfd;
-  android.hardware.graphics.composer3.LutProperties lutProperties;
+  @nullable int[] offsets;
+  android.hardware.graphics.composer3.LutProperties[] lutProperties;
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OutputType.aidl
similarity index 92%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OutputType.aidl
index 5fae35b..e1149cb 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/OutputType.aidl
@@ -32,8 +32,10 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@VintfStability
-parcelable Lut {
-  @nullable ParcelFileDescriptor pfd;
-  android.hardware.graphics.composer3.LutProperties lutProperties;
+@Backing(type="int") @VintfStability
+enum OutputType {
+  INVALID = 0,
+  SYSTEM = 1,
+  SDR = 2,
+  HDR10 = 3,
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
index 3bb09cd..5a77e22 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/PresentFence.aidl
@@ -36,4 +36,10 @@
 parcelable PresentFence {
   long display;
   ParcelFileDescriptor fence;
+  @nullable android.hardware.graphics.composer3.PresentFence.LayerPresentFence[] layerPresentFences;
+  parcelable LayerPresentFence {
+    long layer;
+    ParcelFileDescriptor bufferFence;
+    long bufferLatencyNanos;
+  }
 }
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ScreenPartStatus.aidl
similarity index 89%
copy from graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
copy to graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ScreenPartStatus.aidl
index 5fae35b..ff55370 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/Lut.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/ScreenPartStatus.aidl
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
+/**
+ * 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.
@@ -32,8 +32,9 @@
 // later when a module using the interface is updated, e.g., Mainline modules.
 
 package android.hardware.graphics.composer3;
-@VintfStability
-parcelable Lut {
-  @nullable ParcelFileDescriptor pfd;
-  android.hardware.graphics.composer3.LutProperties lutProperties;
+@Backing(type="int") @VintfStability
+enum ScreenPartStatus {
+  UNSUPPORTED = 0,
+  ORIGINAL = 1,
+  REPLACED = 2,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
index 7154d74..fa58fb7 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCapability.aidl
@@ -96,4 +96,10 @@
      * @see DisplayCommand.validateDisplay
      */
     MULTI_THREADED_PRESENT = 8,
+    /**
+     * Specifies that the display supports a global picture-processing pipeline.
+     *
+     * @see DisplayCommand.pictureProfileId
+     */
+    PICTURE_PROCESSING = 9,
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
index 02c1389..c3fd68e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayCommand.aidl
@@ -185,4 +185,21 @@
      * close as possible to the cadence.
      */
     int frameIntervalNs;
+
+    /**
+     * If the display supports DisplayCapability.PICTURE_PROCESSING, then this value is used to look
+     * up a picture profile which defines the parameters used when configuring a picture-processing
+     * pipeline applied to the composition result, enhancing the quality of the entire composed
+     * image. If the server does not recognize the picture profile, it must continue composition
+     * and ignore this value. If the value is zero, then the server's default picture processing,
+     * if possible, must be applied.
+     *
+     * Note that the client will never send a DisplayCommand.pictureProfileId if
+     * IComposerClient.getMaxLayerPictureProfiles is non-zero. Picture profiles will only be
+     * specified on a per-layer basis via LayerCommand.pictureProfileId.
+     *
+     * @see IComposerClient.getMaxLayerPictureProfiles
+     * @see DisplayCommand.pictureProfileId
+     */
+    long pictureProfileId;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConfiguration.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConfiguration.aidl
index 09c42dc..80d1337 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConfiguration.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayConfiguration.aidl
@@ -15,6 +15,8 @@
  */
 
 package android.hardware.graphics.composer3;
+
+import android.hardware.graphics.composer3.OutputType;
 import android.hardware.graphics.composer3.VrrConfig;
 
 @VintfStability
@@ -67,4 +69,9 @@
      * Non-VRR modes should set this to null.
      */
     @nullable VrrConfig vrrConfig;
+
+    /**
+     * The HDR output format available.
+     */
+    OutputType hdrOutputType;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayIdentification.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayIdentification.aidl
index 03ef8e6..a477eb6 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayIdentification.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayIdentification.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.graphics.composer3;
 
+import android.hardware.graphics.composer3.ScreenPartStatus;
 /**
  * Output parameters for IComposerClient.getDisplayIdentificationData
  */
@@ -29,4 +30,8 @@
      * The EDID 1.3 blob identifying the display.
      */
     byte[] data;
+    /**
+     * Indicator for part originality of the screen
+     */
+    ScreenPartStatus screenPartStatus = ScreenPartStatus.UNSUPPORTED;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl
index ac0a606..6b59a6f 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/DisplayLuts.aidl
@@ -16,7 +16,7 @@
 
 package android.hardware.graphics.composer3;
 
-import android.hardware.graphics.composer3.Lut;
+import android.hardware.graphics.composer3.Luts;
 
 /**
  * LUT (Look-Up Table) Interface for Color Transformation.
@@ -37,9 +37,9 @@
          */
         long layer;
         /**
-         * A Lut specified by the HWC for given HDR layers that don't have Luts provided.
+         * Lut(s) specified by the HWC for given HDR layers that don't have Luts provided.
          */
-        Lut lut;
+        Luts luts;
     }
 
     LayerLut[] layerLuts;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 213e8e9..7556962 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -16,11 +16,13 @@
 
 package android.hardware.graphics.composer3;
 
+import android.hardware.drm.HdcpLevels;
 import android.hardware.graphics.common.DisplayDecorationSupport;
 import android.hardware.graphics.common.Hdr;
 import android.hardware.graphics.common.HdrConversionCapability;
 import android.hardware.graphics.common.HdrConversionStrategy;
 import android.hardware.graphics.common.Transform;
+import android.hardware.graphics.composer3.Buffer;
 import android.hardware.graphics.composer3.ClientTargetProperty;
 import android.hardware.graphics.composer3.ClockMonotonicTimestamp;
 import android.hardware.graphics.composer3.ColorMode;
@@ -37,6 +39,7 @@
 import android.hardware.graphics.composer3.FormatColorComponent;
 import android.hardware.graphics.composer3.HdrCapabilities;
 import android.hardware.graphics.composer3.IComposerCallback;
+import android.hardware.graphics.composer3.Luts;
 import android.hardware.graphics.composer3.OverlayProperties;
 import android.hardware.graphics.composer3.PerFrameMetadataKey;
 import android.hardware.graphics.composer3.PowerMode;
@@ -93,6 +96,18 @@
      * Seamless requirements cannot be met Exception
      */
     const int EX_SEAMLESS_NOT_POSSIBLE = 10;
+    /**
+     * Proposed configuration failed for undisclosed reasons
+     */
+    const int EX_CONFIG_FAILED = 11;
+
+    /**
+     * The number of per-layer picture profiles in use is larger than the number of layer-specific
+     * picture-processing pipelines, as-defined by getMaxLayerPictureProfiles.
+     *
+     * @see LayerCommand.pictureProfileId
+     */
+    const int EX_PICTURE_PROFILE_MAX_EXCEEDED = 12;
 
     /**
      * Integer.MAX_VALUE is reserved for the invalid configuration.
@@ -558,6 +573,7 @@
      * @exception EX_BAD_DISPLAY when an invalid display handle was passed in.
      * @exception EX_BAD_CONFIG when the configuration handle passed in is not valid
      *                    for this display.
+     * @exception EX_CONFIG_FAILED when the config failed for undisclosed reasons.
      */
     void setActiveConfig(long display, int config);
 
@@ -583,6 +599,7 @@
      * achieve the vsync period change without a noticeable visual artifact. When the conditions
      * change and it may be possible to change the vsync period seamlessly, onSeamlessPossible
      * callback must be called to indicate that caller should retry.
+     * @exception EX_CONFIG_FAILED when the config failed for undisclosed reasons.
      *
      * @return is the timeline for the vsync period change.
      */
@@ -913,4 +930,40 @@
      */
     oneway void notifyExpectedPresent(
             long display, in ClockMonotonicTimestamp expectedPresentTime, int frameIntervalNs);
+
+    /*
+     * Returns the number of layer-specific picture-processing profiles that can be referenced from
+     * multiple LayerCommand.pictureProfileId. If the client passes in more pictureProfileIds whose
+     * values are larger than zero (indicating none) then the implementation can support, it should
+     * return EX_PICTURE_PROFILE_MAX_EXCEEDED.
+     *
+     * If the implementation only supports one display-wide picture-processing
+     * pipeline, a value of zero should be returned here.
+     */
+    int getMaxLayerPictureProfiles(long display);
+
+    /**
+     * Supports HDCP lazy activation.
+     *
+     * When SurfaceFlinger detects secure layers, this method is called to instruct HWC side that
+     * HDCP negotiation process can be started.
+     *
+     * When HDCP is successfully started or failed to start, HWC reports the HDCP levels via
+     * IComposerCallback.onHdcpLevelsChanged().
+     *
+     * @param display is the display whose HDCP negotiation can be started.
+     * @param levels is the desired HDCP levels.
+     *
+     * @see IComposerCallback.onHdcpLevelsChanged
+     *
+     */
+    oneway void startHdcpNegotiation(long display, in HdcpLevels levels);
+
+    /*
+     * Returns the Luts based on the buffers.
+     *
+     * @param display is the display for which the luts are requested.
+     * @param buffers is the buffer where the luts can be computed from
+     */
+    Luts[] getLuts(long display, in Buffer[] buffers);
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
index bf4f504..d7ef4c1 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LayerCommand.aidl
@@ -24,7 +24,7 @@
 import android.hardware.graphics.composer3.Color;
 import android.hardware.graphics.composer3.LayerBrightness;
 import android.hardware.graphics.composer3.LayerLifecycleBatchCommandType;
-import android.hardware.graphics.composer3.Lut;
+import android.hardware.graphics.composer3.Luts;
 import android.hardware.graphics.composer3.ParcelableBlendMode;
 import android.hardware.graphics.composer3.ParcelableComposition;
 import android.hardware.graphics.composer3.ParcelableDataspace;
@@ -284,5 +284,21 @@
     /**
      * Sets the lut(s) for the layer.
      */
-    @nullable Lut[] luts;
+    @nullable Luts luts;
+
+    /**
+     * If the display has multiple per-layer picture processing pipelines, then this value is used
+     * to look up a picture profile which defines the parameters used when configuring a
+     * picture-processing pipeline for this layer, enhancing the quality of the buffer contents. If
+     * the server doesn't recognize this profile, it must continue with composition and ignore
+     * this value. If the value is zero, then the no picture processing must be applied.
+     *
+     * Note that the client will never send a DisplayCommand.pictureProfileId if
+     * IComposerClient.getMaxLayerPictureProfiles is non-zero. Picture profiles will only be
+     * specified on a per-layer basis.
+     *
+     * @see IComposerClient.getMaxLayerPictureProfiles
+     * @see DisplayCommand.pictureProfileId
+     */
+    long pictureProfileId;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl
index 47ec390..5f436d9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/LutProperties.aidl
@@ -32,17 +32,16 @@
      * The size of the Lut.
      * This refers to the length of a 1D Lut, or the grid size of a 3D one.
      */
-    long size;
+    int size;
 
     /**
      * SamplingKey is about how a Lut can be sampled.
-     * A Lut can be sampled in more than one way,
-     * but only one sampling method is used at one time.
+     * A Lut can be sampled in more than one key,
+     * but only one sampling key is used at one time.
      *
      * The implementations should use a sampling strategy
      * at least as good as linear sampling.
      */
-    // TODO(b/358422255): add sampling ways
-    @VintfStability enum SamplingKey { RGB, MAX_RGB }
+    @VintfStability enum SamplingKey { RGB, MAX_RGB, CIE_Y }
     SamplingKey[] samplingKeys;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/Luts.aidl
similarity index 64%
rename from graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl
rename to graphics/composer/aidl/android/hardware/graphics/composer3/Luts.aidl
index abfeb14..393354e 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/Lut.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/Luts.aidl
@@ -26,13 +26,13 @@
  */
 
 @VintfStability
-parcelable Lut {
+parcelable Luts {
     /**
      * A handle to a memory region.
      * If the file descriptor is not set, this means that the HWC doesn't specify a Lut.
      *
      * When specifying a Lut, the HWC is required to follow the instructions as below:
-     * 1. use `memfd_create` to create a shared memory segment
+     * 1. use `ashmem_create_region` to create a shared memory segment
      *    with the size specified in lutProperties.
      * 2. use `mmap` to map the shared memory segment into its own virtual address space.
      *    PROT_READ/PROT_WRITE recommended for prot argument.
@@ -40,17 +40,31 @@
      * For data precision, 32-bit float is used to specify a Lut by both the HWC and
      * the platform.
      *
-     * For unflattening/flattening 3D Lut(s), the algorithm below should be observed
-     * by both the HWC and the platform.
      * Assuming that we have a 3D array `ORIGINAL[WIDTH, HEIGHT, DEPTH]`, we would turn it into
      * `FLAT[WIDTH * HEIGHT * DEPTH]` by
      *
      * `FLAT[z + DEPTH * (y + HEIGHT * x)] = ORIGINAL[x, y, z]`
+     *
+     * Note that 1D Lut(s) should be gain curve ones and 3D Lut(s) should be pure color lookup
+     * ones. For 3D Luts buffer,the values of the lut buffer should be normalized, ranging from 0.0
+     * to 1.0, inclusively and the data is organized in the order of R, G, B channels.
+     * For 1D Luts, the lut's values should be also normalized for fixed point pixel formats,
+     * and we now ignore floating point pixel formats + extended range buffers.
      */
     @nullable ParcelFileDescriptor pfd;
 
     /**
-     * The properties of the Lut.
+     * The offsets store the starting point of each Lut memory of the Lut buffer.
+     *
+     * Multiple Luts can be packed into one same `pfd`, and `offsets` is used to pinpoint
+     * the starting point of each Lut.
      */
-    LutProperties lutProperties;
+    @nullable int[] offsets;
+
+    /**
+     * The properties list of the Luts.
+     *
+     * The number of sampling key inside should only be one.
+     */
+    LutProperties[] lutProperties;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/OutputType.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/OutputType.aidl
new file mode 100644
index 0000000..bf4a786
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/OutputType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3;
+
+/**
+ * Display output formats for HDR content.
+ */
+@VintfStability
+@Backing(type="int")
+enum OutputType {
+    /**
+     * Invalid HDR output type
+     */
+    INVALID = 0,
+    /**
+     * Display output format will be chosen by the HAL implementation
+     * and will not adjust to match the content format
+     */
+    SYSTEM = 1,
+    /**
+     * Display supports SDR output type
+     */
+    SDR = 2,
+    /**
+     * Display supports HDR10 output type
+     */
+    HDR10 = 3,
+}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
index b757656..0d8ea76 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/PresentFence.aidl
@@ -27,4 +27,40 @@
      * The present fence for this display.
      */
     ParcelFileDescriptor fence;
+
+    /**
+     * A LayerPresentFence is provided by the server when a LayerCommand.pictureProfileId, specified
+     * by the client, results in the buffer being rendered on the display with some latency after
+     * the rest of the DisplayCommand has been rendered. This can happen due to the picture
+     * processing pipeline adding additional latency for the buffer, itself. LayerPresentFences are
+     * intended to arrive in the same order for each buffer submission on that layer.
+     *
+     * Note that this violates the SurfaceControl.Transaction API contract and therefore is only
+     * allowed on TV devices that require this feature to support high quality video playback on
+     * large displays.
+     */
+    parcelable LayerPresentFence {
+        /**
+         * The layer which this fence refers to.
+         */
+        long layer;
+
+        /**
+         * The present fence for the buffer contents.
+         *
+         * If the buffer ends up being dropped by the server and not rendered, this fence should be
+         * fired at the same time as the next buffer's present fence (or the display fence if
+         * picture processing for this layer was removed).
+         */
+        ParcelFileDescriptor bufferFence;
+
+        /**
+         * The latency that is required for applying picture processing to the layer's buffer.
+         */
+        long bufferLatencyNanos;
+    }
+    /**
+     * The LayerPresentFences for the display.
+     */
+    @nullable LayerPresentFence[] layerPresentFences;
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/ScreenPartStatus.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/ScreenPartStatus.aidl
new file mode 100644
index 0000000..48c1270
--- /dev/null
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/ScreenPartStatus.aidl
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2024, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.graphics.composer3;
+
+/**
+ * Information relating to internal screen panel part originality
+ */
+@VintfStability
+@Backing(type="int")
+enum ScreenPartStatus {
+    /**
+     * Device cannot differentiate an original screen from a replaced screen.
+     */
+    UNSUPPORTED = 0,
+    /**
+     * Device has the original screen it was manufactured with.
+     */
+    ORIGINAL = 1,
+    /**
+     * Device has a replaced screen.
+     */
+    REPLACED = 2,
+}
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
index 331d717..2196530 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h
@@ -145,6 +145,18 @@
         return std::move(data.releasedLayers);
     }
 
+    // Get and clear saved layer present fences.
+    std::vector<PresentFence::LayerPresentFence> takeLayerPresentFences(int64_t display) {
+        LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
+        auto found = mReturnData.find(display);
+        if (found == mReturnData.end()) {
+            return {};
+        }
+
+        ReturnData& data = found->second;
+        return std::move(data.layerPresentFences);
+    }
+
     // Get and clear saved present fence.
     ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
@@ -223,6 +235,14 @@
         LOG_ALWAYS_FATAL_IF(mDisplay && presentFence.display != *mDisplay);
         auto& data = mReturnData[presentFence.display];
         data.presentFence = std::move(presentFence.fence);
+
+        if (presentFence.layerPresentFences.has_value()) {
+            for (auto& optionalFence : presentFence.layerPresentFences.value()) {
+                if (optionalFence.has_value()) {
+                    data.layerPresentFences.push_back(std::move(optionalFence.value()));
+                }
+            }
+        }
     }
 
     void parseSetReleaseFences(ReleaseFences&& releaseFences) {
@@ -247,11 +267,11 @@
     void parseSetDisplayLuts(DisplayLuts&& displayLuts) {
         LOG_ALWAYS_FATAL_IF(mDisplay && displayLuts.display != *mDisplay);
         auto& data = mReturnData[displayLuts.display];
-        for (auto& layerLut : displayLuts.layerLuts) {
-            if (layerLut.lut.pfd.get() >= 0) {
+        for (auto& [layerId, luts] : displayLuts.layerLuts) {
+            if (luts.pfd.get() >= 0) {
                 data.layerLuts.push_back(
-                        {layerLut.layer, Lut{ndk::ScopedFileDescriptor(layerLut.lut.pfd.release()),
-                                             layerLut.lut.lutProperties}});
+                        {layerId, Luts{ndk::ScopedFileDescriptor(luts.pfd.release()), luts.offsets,
+                                       luts.lutProperties}});
             }
         }
     }
@@ -260,6 +280,7 @@
         DisplayRequest displayRequests;
         std::vector<ChangedCompositionLayer> changedLayers;
         ndk::ScopedFileDescriptor presentFence;
+        std::vector<PresentFence::LayerPresentFence> layerPresentFences;
         std::vector<ReleaseFences::Layer> releasedLayers;
         PresentOrValidate::Result presentOrValidateState;
 
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
index 02fb3aa..71a04f3 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h
@@ -25,21 +25,19 @@
 #include <string.h>
 
 #include <aidl/android/hardware/graphics/common/BlendMode.h>
-#include <aidl/android/hardware/graphics/composer3/Color.h>
-#include <aidl/android/hardware/graphics/composer3/Composition.h>
-#include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
-#include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
-#include <aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.h>
-#include <aidl/android/hardware/graphics/composer3/Lut.h>
-#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
-#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
-
-#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
-
 #include <aidl/android/hardware/graphics/common/ColorTransform.h>
 #include <aidl/android/hardware/graphics/common/FRect.h>
 #include <aidl/android/hardware/graphics/common/Rect.h>
 #include <aidl/android/hardware/graphics/common/Transform.h>
+#include <aidl/android/hardware/graphics/composer3/Color.h>
+#include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h>
+#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
+#include <aidl/android/hardware/graphics/composer3/LayerBrightness.h>
+#include <aidl/android/hardware/graphics/composer3/LayerLifecycleBatchCommandType.h>
+#include <aidl/android/hardware/graphics/composer3/Luts.h>
+#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
+#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
 
 #include <log/log.h>
 #include <sync/sync.h>
@@ -59,6 +57,8 @@
 
 namespace aidl::android::hardware::graphics::composer3 {
 
+using PictureProfileId = decltype(LayerCommand().pictureProfileId);
+
 class ComposerClientWriter final {
   public:
     static constexpr std::optional<ClockMonotonicTimestamp> kNoTimestamp = std::nullopt;
@@ -84,6 +84,10 @@
                 DisplayBrightness{.brightness = brightness, .brightnessNits = brightnessNits});
     }
 
+    void setDisplayPictureProfileId(int64_t display, PictureProfileId pictureProfileId) {
+        getDisplayCommand(display).pictureProfileId = pictureProfileId;
+    }
+
     void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target,
                          int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage,
                          float hdrSdrRatio) {
@@ -246,13 +250,13 @@
         getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end());
     }
 
-    void setLayerLuts(int64_t display, int64_t layer, std::vector<Lut>& luts) {
-        std::vector<std::optional<Lut>> currentLuts;
-        for (auto& lut : luts) {
-            currentLuts.push_back(std::make_optional<Lut>(
-                    {ndk::ScopedFileDescriptor(lut.pfd.release()), lut.lutProperties}));
-        }
-        getLayerCommand(display, layer).luts.emplace(std::move(currentLuts));
+    void setLayerLuts(int64_t display, int64_t layer, Luts& luts) {
+        getLayerCommand(display, layer).luts.emplace(std::move(luts));
+    }
+
+    void setLayerPictureProfileId(int64_t display, int64_t layer,
+                                  PictureProfileId pictureProfileId) {
+        getLayerCommand(display, layer).pictureProfileId = pictureProfileId;
     }
 
     std::vector<DisplayCommand> takePendingCommands() {
diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerServiceWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerServiceWriter.h
index b50b84b..9dce140 100644
--- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerServiceWriter.h
+++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerServiceWriter.h
@@ -116,6 +116,13 @@
         mCommandsResults.emplace_back(std::move(clientTargetPropertyWithBrightness));
     }
 
+    void setDisplayLuts(int64_t display, std::vector<DisplayLuts::LayerLut> layerLuts) {
+        DisplayLuts displayLuts;
+        displayLuts.display = display;
+        displayLuts.layerLuts = std::move(layerLuts);
+        mCommandsResults.emplace_back(std::move(displayLuts));
+    }
+
     std::vector<CommandResultPayload> getPendingCommandResults() {
         return std::move(mCommandsResults);
     }
diff --git a/graphics/composer/aidl/vts/Android.bp b/graphics/composer/aidl/vts/Android.bp
index 894ca52..61c2593 100644
--- a/graphics/composer/aidl/vts/Android.bp
+++ b/graphics/composer/aidl/vts/Android.bp
@@ -71,6 +71,7 @@
         "libarect",
         "libbase",
         "libfmq",
+        "libgmock",
         "libgtest",
         "libmath",
         "librenderengine",
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp
index 89ba2e6..9b6a005 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.cpp
+++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp
@@ -690,4 +690,10 @@
     mDisplayResources.clear();
     return true;
 }
+
+std::pair<ScopedAStatus, int32_t> VtsComposerClient::getMaxLayerPictureProfiles(int64_t display) {
+    int32_t outMaxProfiles = 0;
+    return {mComposerClient->getMaxLayerPictureProfiles(display, &outMaxProfiles), outMaxProfiles};
+}
+
 }  // namespace aidl::android::hardware::graphics::composer3::vts
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index da6116f..53f5fae 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -198,6 +198,8 @@
 
     std::vector<RefreshRateChangedDebugData> takeListOfRefreshRateChangedDebugData();
 
+    std::pair<ScopedAStatus, int32_t> getMaxLayerPictureProfiles(int64_t display);
+
     static constexpr int32_t kMaxFrameIntervalNs = 50000000;  // 20fps
     static constexpr int32_t kNoFrameIntervalNs = 0;
 
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index eaf23b5..c1900d7 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -22,15 +22,19 @@
 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
 #include <aidl/android/hardware/graphics/common/Rect.h>
 #include <aidl/android/hardware/graphics/composer3/Composition.h>
+#include <aidl/android/hardware/graphics/composer3/OutputType.h>
 #include <aidl/android/hardware/graphics/composer3/IComposer.h>
 #include <android-base/properties.h>
 #include <android/binder_process.h>
 #include <android/hardware/graphics/composer3/ComposerClientReader.h>
 #include <android/hardware/graphics/composer3/ComposerClientWriter.h>
 #include <binder/ProcessState.h>
+#include <cutils/ashmem.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <ui/Fence.h>
 #include <ui/GraphicBuffer.h>
+#include <ui/PictureProfileHandle.h>
 #include <ui/PixelFormat.h>
 #include <algorithm>
 #include <iterator>
@@ -45,6 +49,8 @@
 #undef LOG_TAG
 #define LOG_TAG "VtsHalGraphicsComposer3_TargetTest"
 
+using testing::Ge;
+
 namespace aidl::android::hardware::graphics::composer3::vts {
 
 using namespace std::chrono_literals;
@@ -118,6 +124,15 @@
                 [&](const Capability& activeCapability) { return activeCapability == capability; });
     }
 
+    bool hasDisplayCapability(int64_t displayId, DisplayCapability capability) {
+        const auto& [status, capabilities] = mComposerClient->getDisplayCapabilities(displayId);
+        EXPECT_TRUE(status.isOk());
+        return std::any_of(capabilities.begin(), capabilities.end(),
+                           [&](const DisplayCapability& activeCapability) {
+                               return activeCapability == capability;
+                           });
+    }
+
     int getInterfaceVersion() {
         const auto& [versionStatus, version] = mComposerClient->getInterfaceVersion();
         EXPECT_TRUE(versionStatus.isOk());
@@ -1254,6 +1269,16 @@
         EXPECT_TRUE(status.isOk());
         EXPECT_FALSE(displayConfigurations.empty());
 
+        const bool areAllModesARR =
+                std::all_of(displayConfigurations.cbegin(), displayConfigurations.cend(),
+                            [](const auto& config) { return config.vrrConfig.has_value(); });
+
+        const bool areAllModesMRR =
+                std::all_of(displayConfigurations.cbegin(), displayConfigurations.cend(),
+                            [](const auto& config) { return !config.vrrConfig.has_value(); });
+
+        EXPECT_TRUE(areAllModesARR || areAllModesMRR) << "Mixing MRR and ARR modes is not allowed";
+
         for (const auto& displayConfig : displayConfigurations) {
             EXPECT_NE(-1, displayConfig.width);
             EXPECT_NE(-1, displayConfig.height);
@@ -2048,6 +2073,7 @@
     EXPECT_TRUE(layerStatus.isOk());
     writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
     execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
@@ -3219,6 +3245,173 @@
     });
 }
 
+class GraphicsComposerAidlCommandV4Test : public GraphicsComposerAidlCommandTest {
+  protected:
+    void SetUp() override {
+        GraphicsComposerAidlTest::SetUp();
+        if (getInterfaceVersion() <= 3) {
+            GTEST_SKIP() << "Device interface version is expected to be >= 4";
+        }
+    }
+};
+
+TEST_P(GraphicsComposerAidlCommandV4Test, getMaxLayerPictureProfiles_success) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+        const auto& [status, maxProfiles] =
+                mComposerClient->getMaxLayerPictureProfiles(displayId);
+        EXPECT_TRUE(status.isOk());
+        EXPECT_THAT(maxProfiles, Ge(0));
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV4Test, getMaxLayerPictureProfiles_unsupported) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+        const auto& [status, maxProfiles] =
+                mComposerClient->getMaxLayerPictureProfiles(displayId);
+        EXPECT_FALSE(status.isOk());
+        EXPECT_NO_FATAL_FAILURE(
+                assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV4Test, setDisplayPictureProfileId_success) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+
+        auto& writer = getWriter(displayId);
+        const auto layer = createOnScreenLayer(display);
+        const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+        ASSERT_NE(nullptr, buffer->handle);
+        // TODO(b/337330263): Lookup profile IDs from MediaQualityManager
+        writer.setDisplayPictureProfileId(displayId, PictureProfileId(1));
+        writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+                              /*acquireFence*/ -1);
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV4Test, setLayerPictureProfileId_success) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+        const auto& [status, maxProfiles] = mComposerClient->getMaxLayerPictureProfiles(displayId);
+        EXPECT_TRUE(status.isOk());
+        if (maxProfiles == 0) {
+            continue;
+        }
+
+        auto& writer = getWriter(displayId);
+        const auto layer = createOnScreenLayer(display);
+        const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+        ASSERT_NE(nullptr, buffer->handle);
+        writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+                              /*acquireFence*/ -1);
+        // TODO(b/337330263): Lookup profile IDs from MediaQualityManager
+        writer.setLayerPictureProfileId(displayId, layer, PictureProfileId(1));
+        execute();
+        ASSERT_TRUE(mReader.takeErrors().empty());
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV4Test, setLayerPictureProfileId_failsWithTooManyProfiles) {
+    for (auto& display : mDisplays) {
+        int64_t displayId = display.getDisplayId();
+        if (!hasDisplayCapability(displayId, DisplayCapability::PICTURE_PROCESSING)) {
+            continue;
+        }
+        const auto& [status, maxProfiles] = mComposerClient->getMaxLayerPictureProfiles(displayId);
+        EXPECT_TRUE(status.isOk());
+        if (maxProfiles == 0) {
+            continue;
+        }
+
+        auto& writer = getWriter(displayId);
+        for (int profileId = 1; profileId <= maxProfiles + 1; ++profileId) {
+            const auto layer = createOnScreenLayer(display);
+            const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+            ASSERT_NE(nullptr, buffer->handle);
+            writer.setLayerBuffer(displayId, layer, /*slot*/ 0, buffer->handle,
+                                  /*acquireFence*/ -1);
+            // TODO(b/337330263): Lookup profile IDs from MediaQualityManager
+            writer.setLayerPictureProfileId(displayId, layer, PictureProfileId(profileId));
+        }
+        execute();
+        const auto errors = mReader.takeErrors();
+        ASSERT_TRUE(errors.size() == 1 &&
+                    errors[0].errorCode == IComposerClient::EX_PICTURE_PROFILE_MAX_EXCEEDED);
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV4Test, SetUnsupportedLayerLuts) {
+    auto& writer = getWriter(getPrimaryDisplayId());
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(layerStatus.isOk());
+    const auto& [status, properties] = mComposerClient->getOverlaySupport();
+
+    // TODO (b/362319189): add Lut VTS enforcement
+    if ((!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+         status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) ||
+        (status.isOk() && !properties.lutProperties)) {
+        int32_t size = 7;
+        size_t bufferSize = static_cast<size_t>(size) * sizeof(float);
+        int32_t fd = ashmem_create_region("lut_shared_mem", bufferSize);
+        void* ptr = mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+        std::vector<float> buffers = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f};
+        memcpy(ptr, buffers.data(), bufferSize);
+        munmap(ptr, bufferSize);
+        Luts luts;
+        luts.offsets = {0};
+        luts.lutProperties = {
+                {LutProperties::Dimension::ONE_D, size, {LutProperties::SamplingKey::RGB}}};
+        luts.pfd = ndk::ScopedFileDescriptor(fd);
+
+        const auto layer = createOnScreenLayer(getPrimaryDisplayId());
+        const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
+        ASSERT_NE(nullptr, buffer->handle);
+        writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, buffer->handle,
+                              /*acquireFence*/ -1);
+        writer.setLayerLuts(getPrimaryDisplayId(), layer, luts);
+        writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+                               VtsComposerClient::kNoFrameIntervalNs);
+        execute();
+        const auto errors = mReader.takeErrors();
+        if (errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_UNSUPPORTED) {
+            GTEST_SUCCEED() << "setLayerLuts is not supported";
+            return;
+        }
+        // change to client composition
+        ASSERT_FALSE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
+    }
+}
+
+TEST_P(GraphicsComposerAidlCommandV4Test, GetDisplayConfigurations_hasHdrType) {
+    for (const auto& display : mDisplays) {
+        const auto& [status, displayConfigurations] =
+                mComposerClient->getDisplayConfigurations(display.getDisplayId());
+        EXPECT_TRUE(status.isOk());
+        EXPECT_FALSE(displayConfigurations.empty());
+
+        for (const auto& displayConfig : displayConfigurations) {
+            EXPECT_NE(displayConfig.hdrOutputType, OutputType::INVALID);
+        }
+    }
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, GraphicsComposerAidlCommandTest,
@@ -3249,6 +3442,11 @@
         PerInstance, GraphicsComposerAidlCommandV3Test,
         testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
         ::android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV4Test);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, GraphicsComposerAidlCommandV4Test,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+        ::android::PrintInstanceNameToString);
 }  // namespace aidl::android::hardware::graphics::composer3::vts
 
 int main(int argc, char** argv) {
diff --git a/graphics/mapper/stable-c/Android.bp b/graphics/mapper/stable-c/Android.bp
index 82306be..f4196b9 100644
--- a/graphics/mapper/stable-c/Android.bp
+++ b/graphics/mapper/stable-c/Android.bp
@@ -111,7 +111,7 @@
         "VtsHalTargetTestDefaults",
         "use_libaidlvintf_gtest_helper_static",
         "android.hardware.graphics.allocator-ndk_shared",
-        "android.hardware.graphics.common-ndk_shared",
+        "android.hardware.graphics.common-ndk_static",
     ],
     srcs: [
         "vts/VtsHalGraphicsMapperStableC_TargetTest.cpp",
diff --git a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
index 5de5f1c..cfd3173 100644
--- a/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
+++ b/graphics/mapper/stable-c/vts/VtsHalGraphicsMapperStableC_TargetTest.cpp
@@ -753,7 +753,7 @@
  * Test IMapper::lock and IMapper::unlock with no CPU usage requested.
  */
 TEST_P(GraphicsMapperStableCTests, LockUnlockNoCPUUsage) {
-    constexpr auto usage = BufferUsage::CPU_READ_NEVER | BufferUsage::CPU_WRITE_NEVER;
+    constexpr auto usage = BufferUsage::CPU_READ_RARELY | BufferUsage::CPU_WRITE_NEVER;
     auto buffer = allocate({
             .name = {"VTS_TEMP"},
             .width = 64,
@@ -771,15 +771,12 @@
     auto handle = buffer->import();
     uint8_t* data = nullptr;
 
-    EXPECT_EQ(AIMAPPER_ERROR_BAD_VALUE,
-              mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
-                                region, -1,(void**)&data))
-              << "Locking with 0 access succeeded";
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_VALUE, mapper()->v5.lock(*handle, 0, region, -1, (void**)&data))
+            << "Locking with 0 access succeeded";
 
     int releaseFence = -1;
-    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER,
-              mapper()->v5.unlock(*handle, &releaseFence))
-              << "Unlocking not locked buffer succeeded";
+    EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(*handle, &releaseFence))
+            << "Unlocking not locked buffer succeeded";
     if (releaseFence != -1) {
         close(releaseFence);
     }
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index 97de0e2..d2ad3b1 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -50,9 +50,8 @@
             version: "3",
             imports: [],
         },
-
     ],
-    frozen: true,
+    frozen: false,
 
 }
 
@@ -84,7 +83,7 @@
     name: "android.hardware.health-translate-ndk",
     defaults: ["android.hardware.health-translate-ndk_defaults"],
     shared_libs: [
-        "android.hardware.health-V3-ndk",
+        "android.hardware.health-V4-ndk",
     ],
 }
 
@@ -101,7 +100,7 @@
     name: "android.hardware.health-translate-java",
     srcs: ["android/hardware/health/Translate.java"],
     libs: [
-        "android.hardware.health-V3-java",
+        "android.hardware.health-V4-java",
         "android.hardware.health-V2.0-java",
         "android.hardware.health-V2.1-java",
     ],
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
index e013e31..9303767 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/BatteryPartStatus.aidl
@@ -34,7 +34,7 @@
 package android.hardware.health;
 @Backing(type="int") @VintfStability
 enum BatteryPartStatus {
-  UNSUPPORTED,
-  ORIGINAL,
-  REPLACED,
+  UNSUPPORTED = 0,
+  ORIGINAL = 1,
+  REPLACED = 2,
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
index bfa1475..d993040 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HealthInfo.aidl
@@ -60,5 +60,6 @@
   android.hardware.health.BatteryChargingState chargingState;
   android.hardware.health.BatteryChargingPolicy chargingPolicy;
   @nullable android.hardware.health.BatteryHealthData batteryHealthData;
+  @nullable android.hardware.health.HingeInfo[] hingeInfos;
   const int BATTERY_CHARGE_TIME_TO_FULL_NOW_SECONDS_UNSUPPORTED = (-1) /* -1 */;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HingeInfo.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HingeInfo.aidl
index a5eda52..b3c38ad 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/HingeInfo.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.health;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable HingeInfo {
+  int numTimesFolded;
+  int expectedHingeLifespan;
 }
diff --git a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/IHealth.aidl b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/IHealth.aidl
index b49dfff..e919f14 100644
--- a/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/IHealth.aidl
+++ b/health/aidl/aidl_api/android.hardware.health/current/android/hardware/health/IHealth.aidl
@@ -49,6 +49,7 @@
   void setChargingPolicy(android.hardware.health.BatteryChargingPolicy in_value);
   android.hardware.health.BatteryChargingPolicy getChargingPolicy();
   android.hardware.health.BatteryHealthData getBatteryHealthData();
+  android.hardware.health.HingeInfo[] getHingeInfo();
   const int STATUS_UNKNOWN = 2;
   const int STATUS_CALLBACK_DIED = 4;
 }
diff --git a/health/aidl/android/hardware/health/HealthInfo.aidl b/health/aidl/android/hardware/health/HealthInfo.aidl
index af84089..1c953ee 100644
--- a/health/aidl/android/hardware/health/HealthInfo.aidl
+++ b/health/aidl/android/hardware/health/HealthInfo.aidl
@@ -24,6 +24,7 @@
 import android.hardware.health.BatteryStatus;
 import android.hardware.health.DiskStats;
 import android.hardware.health.StorageInfo;
+import android.hardware.health.HingeInfo;
 
 /**
  * Health Information.
@@ -115,7 +116,6 @@
      * Battery capacity level. See {@link BatteryCapacityLevel} for more details.
      */
     BatteryCapacityLevel batteryCapacityLevel;
-
     /**
      * Value of {@link #batteryChargeTimeToFullNowSeconds} if it is not
      * supported.
@@ -148,4 +148,8 @@
      * Battery health data
      */
     @nullable BatteryHealthData batteryHealthData;
+    /**
+     * Information about foldable hinge health. Will be an empty vector if no hinges present
+     */
+    @nullable HingeInfo[] hingeInfos;
 }
diff --git a/health/aidl/android/hardware/health/HingeInfo.aidl b/health/aidl/android/hardware/health/HingeInfo.aidl
new file mode 100644
index 0000000..ad38821
--- /dev/null
+++ b/health/aidl/android/hardware/health/HingeInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.health;
+
+/*
+ * Information on foldable hinge health life time estimates, end of life
+ * information and other attributes.
+ *
+ * All integers in this struct must be interpreted as non-negative.
+ */
+@VintfStability
+parcelable HingeInfo {
+    /**
+     * returns count of times a given hinge has been folded.
+     *
+     * opening fully counts as 1 fold and closing fully counts as another.
+     * The hinge has to engage in its full range of motion to be considered
+     * a fold. Partial folds must not be counted.
+     */
+    int numTimesFolded;
+    /**
+     * returns the expected lifespan of hinge in units of number of folds
+     */
+    int expectedHingeLifespan;
+}
diff --git a/health/aidl/android/hardware/health/IHealth.aidl b/health/aidl/android/hardware/health/IHealth.aidl
index bdfe07a..c88141c 100644
--- a/health/aidl/android/hardware/health/IHealth.aidl
+++ b/health/aidl/android/hardware/health/IHealth.aidl
@@ -23,6 +23,7 @@
 import android.hardware.health.HealthInfo;
 import android.hardware.health.IHealthInfoCallback;
 import android.hardware.health.StorageInfo;
+import android.hardware.health.HingeInfo;
 
 /**
  * IHealth manages health info and posts events on registered callbacks.
@@ -242,4 +243,17 @@
      *           for other errors.
      */
     BatteryHealthData getBatteryHealthData();
+
+    /**
+     * Get Hinge info.
+     *
+     * @return vector of HingeInfo structs if successful.
+     *         If error:
+     *         - Return exception with code EX_UNSUPPORTED_OPERATION
+     *           if this property is not supported,
+     *         - Return service specific error with code STATUS_UNKNOWN
+     *           for other errors.
+     */
+    HingeInfo[] getHingeInfo();
+
 }
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 2071f08..cc5d0a0 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -29,7 +29,7 @@
         "libcutils",
         "liblog",
         "libutils",
-        "android.hardware.health-V3-ndk",
+        "android.hardware.health-V4-ndk",
 
         // TODO(b/177269435): remove when BatteryMonitor works with AIDL HealthInfo.
         "libhidlbase",
@@ -48,7 +48,7 @@
     name: "libhealth_aidl_charger_defaults",
     shared_libs: [
         // common
-        "android.hardware.health-V3-ndk",
+        "android.hardware.health-V4-ndk",
         "libbase",
         "libcutils",
         "liblog",
@@ -195,7 +195,7 @@
         "service_fuzzer_defaults",
     ],
     static_libs: [
-        "android.hardware.health-V3-ndk",
+        "android.hardware.health-V4-ndk",
         "libbase",
         "liblog",
         "fuzz_libhealth_aidl_impl",
diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp
index 37662ea..d0e2dac 100644
--- a/health/aidl/default/Health.cpp
+++ b/health/aidl/default/Health.cpp
@@ -192,6 +192,12 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
+ndk::ScopedAStatus Health::getHingeInfo(std::vector<HingeInfo>*) {
+    // This implementation does not support HingeInfo. An implementation may extend this
+    // class and override this function to support storage info.
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
 ndk::ScopedAStatus Health::getHealthInfo(HealthInfo* out) {
     battery_monitor_.updateValues();
 
diff --git a/health/aidl/default/android.hardware.health-service.example.xml b/health/aidl/default/android.hardware.health-service.example.xml
index 2acaaba..8ddfbda 100644
--- a/health/aidl/default/android.hardware.health-service.example.xml
+++ b/health/aidl/default/android.hardware.health-service.example.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.health</name>
-        <version>3</version>
+        <version>4</version>
         <fqname>IHealth/default</fqname>
     </hal>
 </manifest>
diff --git a/health/aidl/default/include/health-impl/Health.h b/health/aidl/default/include/health-impl/Health.h
index 429ae2a..96df517 100644
--- a/health/aidl/default/include/health-impl/Health.h
+++ b/health/aidl/default/include/health-impl/Health.h
@@ -72,6 +72,7 @@
     // The default implementations return nothing in |out|.
     ndk::ScopedAStatus getDiskStats(std::vector<DiskStats>* out) override;
     ndk::ScopedAStatus getStorageInfo(std::vector<StorageInfo>* out) override;
+    ndk::ScopedAStatus getHingeInfo(std::vector<HingeInfo>* out) override;
 
     ndk::ScopedAStatus setChargingPolicy(BatteryChargingPolicy in_value) override;
     ndk::ScopedAStatus getChargingPolicy(BatteryChargingPolicy* out) override;
diff --git a/health/aidl/vts/functional/Android.bp b/health/aidl/vts/functional/Android.bp
index 25ba5f8..75bec97 100644
--- a/health/aidl/vts/functional/Android.bp
+++ b/health/aidl/vts/functional/Android.bp
@@ -40,7 +40,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.health-V3-ndk",
+        "android.hardware.health-V4-ndk",
         "libgmock",
     ],
     header_libs: [
diff --git a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
index 45a1e40..a44cd5e 100644
--- a/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
+++ b/health/aidl/vts/functional/VtsHalHealthTargetTest.cpp
@@ -360,6 +360,20 @@
 }
 
 /*
+ * Tests the values returned by getHingeInfo() from interface IHealth.
+ */
+TEST_P(HealthAidl, getHingeInfo) {
+    std::vector<HingeInfo> value;
+    auto status = health->getHingeInfo(&value);
+    ASSERT_THAT(status, AnyOf(IsOk(), ExceptionIs(EX_UNSUPPORTED_OPERATION)));
+    if (!status.isOk()) return;
+    for (auto& hinge : value) {
+        ASSERT_TRUE(hinge.expectedHingeLifespan >= 0);
+        ASSERT_TRUE(hinge.numTimesFolded >= 0);
+    }
+}
+
+/*
  * Tests the values returned by getDiskStats() from interface IHealth.
  */
 TEST_P(HealthAidl, getDiskStats) {
diff --git a/health/utils/libhealthshim/Android.bp b/health/utils/libhealthshim/Android.bp
index b0ea743..9f9970f 100644
--- a/health/utils/libhealthshim/Android.bp
+++ b/health/utils/libhealthshim/Android.bp
@@ -34,7 +34,7 @@
         "-Werror",
     ],
     static_libs: [
-        "android.hardware.health-V3-ndk",
+        "android.hardware.health-V4-ndk",
         "android.hardware.health-translate-ndk",
         "android.hardware.health@1.0",
         "android.hardware.health@2.0",
diff --git a/health/utils/libhealthshim/include/health-shim/shim.h b/health/utils/libhealthshim/include/health-shim/shim.h
index ff6849b..9a62601 100644
--- a/health/utils/libhealthshim/include/health-shim/shim.h
+++ b/health/utils/libhealthshim/include/health-shim/shim.h
@@ -43,6 +43,7 @@
     ndk::ScopedAStatus getEnergyCounterNwh(int64_t* _aidl_return) override;
     ndk::ScopedAStatus getChargeStatus(BatteryStatus* _aidl_return) override;
     ndk::ScopedAStatus getStorageInfo(std::vector<StorageInfo>* _aidl_return) override;
+    ndk::ScopedAStatus getHingeInfo(std::vector<HingeInfo>* _aidl_return) override;
     ndk::ScopedAStatus getDiskStats(std::vector<DiskStats>* _aidl_return) override;
     ndk::ScopedAStatus getHealthInfo(HealthInfo* _aidl_return) override;
     ndk::ScopedAStatus setChargingPolicy(BatteryChargingPolicy in_value) override;
diff --git a/health/utils/libhealthshim/shim.cpp b/health/utils/libhealthshim/shim.cpp
index a5ba919..2ddf97e 100644
--- a/health/utils/libhealthshim/shim.cpp
+++ b/health/utils/libhealthshim/shim.cpp
@@ -190,6 +190,10 @@
     return ReturnAndResultToStatus(ret, out_result);
 }
 
+ScopedAStatus HealthShim::getHingeInfo(std::vector<HingeInfo>* /*out*/) {
+    return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
 ScopedAStatus HealthShim::getDiskStats(std::vector<DiskStats>* out) {
     Result out_result = Result::UNKNOWN;
     auto ret = service_->getDiskStats([out, &out_result](auto result, const auto& value) {
diff --git a/power/aidl/Android.bp b/power/aidl/Android.bp
index dc57613..2c80aab 100644
--- a/power/aidl/Android.bp
+++ b/power/aidl/Android.bp
@@ -69,46 +69,53 @@
                 "android.hardware.common-V2",
             ],
         },
-
     ],
-    frozen: true,
-
+    frozen: false,
 }
 
+power_version = "android.hardware.power-V6"
+
 cc_defaults {
     name: "android.hardware.power-ndk_shared",
     shared_libs: [
-        "android.hardware.power-V5-ndk",
+        power_version + "-ndk",
     ],
 }
 
 cc_defaults {
     name: "android.hardware.power-ndk_export_shared",
     shared_libs: [
-        "android.hardware.power-V5-ndk",
+        power_version + "-ndk",
     ],
     export_shared_lib_headers: [
-        "android.hardware.power-V5-ndk",
+        power_version + "-ndk",
     ],
 }
 
 cc_defaults {
     name: "android.hardware.power-ndk_static",
     static_libs: [
-        "android.hardware.power-V5-ndk",
+        power_version + "-ndk",
     ],
 }
 
 java_defaults {
     name: "android.hardware.power-java_shared",
     libs: [
-        "android.hardware.power-V5-java",
+        power_version + "-java",
     ],
 }
 
 java_defaults {
     name: "android.hardware.power-java_static",
     static_libs: [
-        "android.hardware.power-V5-java",
+        power_version + "-java",
+    ],
+}
+
+aidl_interface_defaults {
+    name: "android.hardware.power-aidl",
+    imports: [
+        power_version,
     ],
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CompositionData.aidl
similarity index 84%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CompositionData.aidl
index a5eda52..9ab4818 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CompositionData.aidl
@@ -31,9 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.power;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable CompositionData {
+  long timestampNanos;
+  long[] scheduledPresentTimestampsNanos;
+  long latchTimestampNanos;
+  android.hardware.power.FrameProducer[] producers;
+  @nullable android.hardware.power.CompositionUpdate updateData;
+  long[] outputIds;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CompositionUpdate.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CompositionUpdate.aidl
index a5eda52..a0c4b21 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CompositionUpdate.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.power;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable CompositionUpdate {
+  long timestampNanos;
+  android.hardware.power.FrameProducerUpdate[] producerUpdates;
+  long[] deadOutputIds;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl
similarity index 81%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl
index a5eda52..a38156a 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.power;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable CpuHeadroomParams {
+  android.hardware.power.CpuHeadroomParams.CalculationType calculationType = android.hardware.power.CpuHeadroomParams.CalculationType.MIN;
+  int calculationWindowMillis = 1000;
+  int[] tids;
+  enum CalculationType {
+    MIN,
+    AVERAGE,
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomResult.aidl
similarity index 91%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomResult.aidl
index a5eda52..21b1e69 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomResult.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.power;
+@JavaDerive(equals=true, toString=true) @VintfStability
+union CpuHeadroomResult {
+  float globalHeadroom;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/FrameProducer.aidl
similarity index 87%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/FrameProducer.aidl
index a5eda52..0d9084b 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/FrameProducer.aidl
@@ -31,9 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.power;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable FrameProducer {
+  long producerId;
+  int uid;
+  double fps;
+  @nullable android.hardware.power.LatchedFrameData currentlyLatchedFrame;
+  boolean cpuDeadlineMissed;
+  boolean gpuDeadlineMissed;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/FrameProducerUpdate.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/FrameProducerUpdate.aidl
index a5eda52..08ea3dc 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/FrameProducerUpdate.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.power;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable FrameProducerUpdate {
+  long producerId;
+  boolean isDead;
+  int[] sessions;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomParams.aidl
similarity index 82%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomParams.aidl
index a5eda52..6faa938 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomParams.aidl
@@ -31,9 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.power;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable GpuHeadroomParams {
+  android.hardware.power.GpuHeadroomParams.CalculationType calculationType = android.hardware.power.GpuHeadroomParams.CalculationType.MIN;
+  int calculationWindowMillis = 1000;
+  enum CalculationType {
+    MIN,
+    AVERAGE,
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomResult.aidl
similarity index 91%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomResult.aidl
index a5eda52..bbd3d8b 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/GpuHeadroomResult.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.power;
+@JavaDerive(equals=true, toString=true) @VintfStability
+union GpuHeadroomResult {
+  float globalHeadroom;
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
index 8acdaf2..080c0bd 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
@@ -43,4 +43,9 @@
   android.hardware.power.IPowerHintSession createHintSessionWithConfig(in int tgid, in int uid, in int[] threadIds, in long durationNanos, in android.hardware.power.SessionTag tag, out android.hardware.power.SessionConfig config);
   android.hardware.power.ChannelConfig getSessionChannel(in int tgid, in int uid);
   oneway void closeSessionChannel(in int tgid, in int uid);
+  android.hardware.power.SupportInfo getSupportInfo();
+  android.hardware.power.CpuHeadroomResult getCpuHeadroom(in android.hardware.power.CpuHeadroomParams params);
+  android.hardware.power.GpuHeadroomResult getGpuHeadroom(in android.hardware.power.GpuHeadroomParams params);
+  oneway void sendCompositionData(in android.hardware.power.CompositionData[] data);
+  oneway void sendCompositionUpdate(in android.hardware.power.CompositionUpdate update);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/LatchedFrameData.aidl
similarity index 85%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/LatchedFrameData.aidl
index a5eda52..01ce157 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/LatchedFrameData.aidl
@@ -31,9 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.power;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable LatchedFrameData {
+  long frameStartTimestampNanos;
+  long intendedPresentTimestampNanos;
+  long bufferSubmissionTimestampNanos;
+  long gpuSignalTimestampNanos;
+  boolean usedGpu;
+  @nullable ParcelFileDescriptor gpuAcquireFence;
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
index df31618..f6b32d0 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionHint.aidl
@@ -42,4 +42,6 @@
   GPU_LOAD_UP = 5,
   GPU_LOAD_DOWN = 6,
   GPU_LOAD_RESET = 7,
+  CPU_LOAD_SPIKE = 8,
+  GPU_LOAD_SPIKE = 9,
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionMode.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionMode.aidl
index d0ae0ba..448dbb3 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionMode.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionMode.aidl
@@ -35,4 +35,7 @@
 @Backing(type="int") @VintfStability
 enum SessionMode {
   POWER_EFFICIENCY,
+  GRAPHICS_PIPELINE,
+  AUTO_CPU,
+  AUTO_GPU,
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
index 862fbc5..71da2d4 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SessionTag.aidl
@@ -39,4 +39,5 @@
   HWUI,
   GAME,
   APP,
+  SYSUI,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl
similarity index 71%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl
index a5eda52..c90125c 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl
@@ -31,9 +31,29 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.power;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable SupportInfo {
+  boolean usesSessions;
+  long boosts;
+  long modes;
+  long sessionHints;
+  long sessionModes;
+  long sessionTags;
+  android.hardware.power.SupportInfo.CompositionDataSupportInfo compositionData;
+  android.hardware.power.SupportInfo.HeadroomSupportInfo headroom;
+  @VintfStability
+  parcelable CompositionDataSupportInfo {
+    boolean isSupported;
+    boolean disableGpuFences;
+    int maxBatchSize;
+    boolean alwaysBatch;
+  }
+  @VintfStability
+  parcelable HeadroomSupportInfo {
+    boolean isCpuSupported;
+    boolean isGpuSupported;
+    int cpuMinIntervalMillis;
+    int gpuMinIntervalMillis;
+  }
 }
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl
index 45013dd..25a5350 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/WorkDuration.aidl
@@ -39,4 +39,5 @@
   long workPeriodStartTimestampNanos;
   long cpuDurationNanos;
   long gpuDurationNanos;
+  long intendedPresentTimestampNanos;
 }
diff --git a/power/aidl/android/hardware/power/CompositionData.aidl b/power/aidl/android/hardware/power/CompositionData.aidl
new file mode 100644
index 0000000..43c636f
--- /dev/null
+++ b/power/aidl/android/hardware/power/CompositionData.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+import android.hardware.power.CompositionUpdate;
+import android.hardware.power.FrameProducer;
+
+/**
+ * Object sent to PowerHAL once per frame during commit that contains relevant
+ * timing data for a given set of frame producers, drawing to a given set of outputs.
+ *
+ * This will generally be layer objects drawing to displays, but could also represent
+ * things like arbitrary graphics buffers drawing into network sockets. All frame
+ * producers that participated in this composition and have associated
+ * sessions will be listed under "producers".
+ *
+ * All timestamps use SYSTEM_TIME_MONOTONIC clock, at nanosecond resolution.
+ */
+@VintfStability
+parcelable CompositionData {
+    /**
+     * Timestamp for when the message was sent, useful to combine and correlate
+     * composition data with any reported info from sessions.
+     *
+     * The latchTime can be used alongside this for chronologically
+     * ordering events that happened during latching, such as frame drop.
+     */
+    long timestampNanos;
+
+    /**
+     * Scheduled presentation times for each outputId, corresponding to the outputId
+     * with the same index.
+     */
+    long[] scheduledPresentTimestampsNanos;
+
+    /**
+     * The current frame's latch time for buffers targeting its vsync, this serves
+     * as the effective frame deadline unless the frame latches with GPU unsignaled.
+     */
+    long latchTimestampNanos;
+
+    /**
+     * The set of frame producers that tried to present this vsync on these outputs,
+     * ignoring the ones without associated sessions.
+     */
+    FrameProducer[] producers;
+
+    /**
+     * Optional parcel containing information not bound to a specific frame,
+     * such as lifecycle updates. These updates can be sent along with CompositionData
+     * to minimize additional calls, when appropriate.
+     */
+    @nullable CompositionUpdate updateData;
+
+    /**
+     * A list of IDs corresponding to one or more outputs, such as displays,
+     * that are the intended recipients of this frame composition. Each output
+     * ID is guaranteed to be unique for its lifetime.
+     */
+    long[] outputIds;
+}
diff --git a/power/aidl/android/hardware/power/CompositionUpdate.aidl b/power/aidl/android/hardware/power/CompositionUpdate.aidl
new file mode 100644
index 0000000..7cd451c
--- /dev/null
+++ b/power/aidl/android/hardware/power/CompositionUpdate.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+import android.hardware.power.FrameProducerUpdate;
+
+/**
+ * An update regarding composition objects that might be sent outside of a normal
+ * sendCompositionData call, such as for lifecycle updates. This object is either
+ * attached to CompositionData or sent separately, depending on current activity
+ * and urgency.
+ */
+@VintfStability
+parcelable CompositionUpdate {
+    /**
+     * Timestamp for when the message was sent.
+     */
+    long timestampNanos;
+
+    /**
+     * Update objects for all frame producers that have changed.
+     */
+    FrameProducerUpdate[] producerUpdates;
+
+    /**
+     * The IDs of any outputs that have disconnected in the framework.
+     */
+    long[] deadOutputIds;
+}
diff --git a/power/aidl/android/hardware/power/CpuHeadroomParams.aidl b/power/aidl/android/hardware/power/CpuHeadroomParams.aidl
new file mode 100644
index 0000000..fab8f43
--- /dev/null
+++ b/power/aidl/android/hardware/power/CpuHeadroomParams.aidl
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable CpuHeadroomParams {
+    /**
+     * Defines how to calculate the headroom.
+     */
+    enum CalculationType {
+        // Default to return the minimum headroom in a window.
+        MIN,
+        // Returns the average headroom in a window.
+        AVERAGE,
+    }
+
+    /**
+     * The calculation type.
+     */
+    CalculationType calculationType = CalculationType.MIN;
+
+    /**
+     * The calculation rolling window size in milliseconds.
+     * The device should support a superset of [50, 10000] and try to use the closest feasible
+     * window size to the provided value param.
+     */
+    int calculationWindowMillis = 1000;
+
+    /**
+     * The thread TIDs to track.
+     *
+     * If tids are not-empty, return the headrooms only for cores that are available
+     * to the given tids, otherwise return the headroom(s) for all cores.
+     *
+     * This should handle all the cases including but not limited to core affinity and app cpuset
+     * that change the available CPU cores for the caller. And the HAL should check that the TIDs
+     * have the same core affinity.
+     */
+    int[] tids;
+}
diff --git a/power/aidl/android/hardware/power/CpuHeadroomResult.aidl b/power/aidl/android/hardware/power/CpuHeadroomResult.aidl
new file mode 100644
index 0000000..e7ed8b6
--- /dev/null
+++ b/power/aidl/android/hardware/power/CpuHeadroomResult.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+/**
+ * Headroom value result depending on the request params.
+ *
+ * Each value is ranged from [0, 100], where 0 indicates no CPU resources were left
+ * during the calculation interval and the app may expect low resources to be granted.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+union CpuHeadroomResult {
+    /**
+     * If ALL selection type is requested.
+     */
+    float globalHeadroom;
+}
diff --git a/power/aidl/android/hardware/power/FrameProducer.aidl b/power/aidl/android/hardware/power/FrameProducer.aidl
new file mode 100644
index 0000000..9ff77d3
--- /dev/null
+++ b/power/aidl/android/hardware/power/FrameProducer.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+import android.hardware.power.LatchedFrameData;
+
+/**
+ * Abstract unit of frame production. Frame production could be for outputs
+ * such as layers, sets of layers, serial devices, or a network connection.
+ * Frame producers are associated with one or more sessions that provide timing context
+ * and thread associations for the producer.
+ */
+@VintfStability
+parcelable FrameProducer {
+    /**
+     * ID of the producer, unique per-producer at a given time.
+     */
+    long producerId;
+
+    /**
+     * UID of the process that owns the producer.
+     */
+    int uid;
+
+    /**
+     * The framerate of the producer. This parameter will be set when SF is reasonably
+     * confident it knows what framerate of the frame producer is, and will
+     * be set to -1 in cases where SF is not sure, or it's rapidly changing.
+     */
+    double fps;
+
+    /**
+     * Info for the currently latching frame on this producer,
+     * this value will be null if the producer tried but failed to latch.
+     */
+    @nullable LatchedFrameData currentlyLatchedFrame;
+
+    /**
+     * True if SF thinks a frame tried to latch for this producer but failed because the
+     * CPU did not submit a buffer on time; currentlyLatchedFrame is null if this is true.
+     */
+    boolean cpuDeadlineMissed;
+
+    /**
+     * True if SF thinks a frame tried to latch for this producer, but failed because the
+     * GPU did not finish on time; currentlyLatchedFrame is null if this is true.
+     */
+    boolean gpuDeadlineMissed;
+}
diff --git a/power/aidl/android/hardware/power/FrameProducerUpdate.aidl b/power/aidl/android/hardware/power/FrameProducerUpdate.aidl
new file mode 100644
index 0000000..3075a8e
--- /dev/null
+++ b/power/aidl/android/hardware/power/FrameProducerUpdate.aidl
@@ -0,0 +1,45 @@
+
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+/**
+ * A single update for an individual producer object.
+ */
+@VintfStability
+parcelable FrameProducerUpdate {
+    /**
+     * The ID of the producer, guaranteed to be unique at a given time.
+     */
+    long producerId;
+
+    /**
+     * If true, this producer is no longer active and its data can be released.
+     * "sessions" will be blank in this case, as there are no more associations
+     * with this producer.
+     */
+    boolean isDead;
+
+    /**
+     * The IDs of all sessions associated with the producer, corresponding to the
+     * ID in SessionConfig returned to the framework during session creation.
+     *
+     * If an object was created without a Session ID by using an older creation
+     * method, it is not eligible to be associated to a FrameProducer.
+     */
+    int[] sessions;
+}
diff --git a/power/aidl/android/hardware/power/GpuHeadroomParams.aidl b/power/aidl/android/hardware/power/GpuHeadroomParams.aidl
new file mode 100644
index 0000000..68848d8
--- /dev/null
+++ b/power/aidl/android/hardware/power/GpuHeadroomParams.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+parcelable GpuHeadroomParams {
+    /**
+     * Defines how to calculate the headroom.
+     */
+    enum CalculationType {
+        // Default to return the minimum headroom in a window.
+        MIN,
+        // Returns the average headroom in a window.
+        AVERAGE,
+    }
+
+    /**
+     * The calculation type.
+     */
+    CalculationType calculationType = CalculationType.MIN;
+
+    /**
+     * The device should support a superset of [50, 10000] and try to use the closest feasible
+     * window size to the provided value param.
+     */
+    int calculationWindowMillis = 1000;
+}
diff --git a/power/aidl/android/hardware/power/GpuHeadroomResult.aidl b/power/aidl/android/hardware/power/GpuHeadroomResult.aidl
new file mode 100644
index 0000000..ef3257d
--- /dev/null
+++ b/power/aidl/android/hardware/power/GpuHeadroomResult.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+/**
+ * Headroom value result depending on the request params.
+ *
+ * Each value is ranged from [0, 100], where 0 indicates no GPU resources were left
+ * during the calculation interval and the app may expect low resources to be granted.
+ */
+@VintfStability
+@JavaDerive(equals=true, toString=true)
+union GpuHeadroomResult {
+    float globalHeadroom;
+}
diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl
index e25714f..ce61af4 100644
--- a/power/aidl/android/hardware/power/IPower.aidl
+++ b/power/aidl/android/hardware/power/IPower.aidl
@@ -18,10 +18,17 @@
 
 import android.hardware.power.Boost;
 import android.hardware.power.ChannelConfig;
+import android.hardware.power.CompositionData;
+import android.hardware.power.CompositionUpdate;
+import android.hardware.power.CpuHeadroomParams;
+import android.hardware.power.CpuHeadroomResult;
+import android.hardware.power.GpuHeadroomParams;
+import android.hardware.power.GpuHeadroomResult;
 import android.hardware.power.IPowerHintSession;
 import android.hardware.power.Mode;
 import android.hardware.power.SessionConfig;
 import android.hardware.power.SessionTag;
+import android.hardware.power.SupportInfo;
 
 @VintfStability
 interface IPower {
@@ -144,4 +151,50 @@
      * @param   uid The UID to be associated with this channel.
      */
     oneway void closeSessionChannel(in int tgid, in int uid);
+
+    /**
+     * Called to get detailed information on the support status of various PowerHAL
+     * features, such as hint sessions and specific boosts.
+     *
+     * @return  a SupportInfo giving detailed support information.
+     */
+    SupportInfo getSupportInfo();
+
+    /**
+     * Provides an estimate of available CPU headroom the device based on past history.
+     * <p>
+     * @param params params to customize the CPU headroom calculation
+     * @throws EX_UNSUPPORTED_OPERATION if the API is unsupported or the request params can't be
+     *         served.
+     * @throws EX_SECURITY if the TIDs passed in do not belong to the same process.
+     * @throws EX_ILLEGAL_STATE if the TIDs passed in do not have the same core affinity setting.
+     */
+    CpuHeadroomResult getCpuHeadroom(in CpuHeadroomParams params);
+
+    /**
+     * Provides an estimate of available GPU headroom the device based on past history.
+     * <p>
+     * @param params params to customize the GPU headroom calculation
+     * @throws EX_UNSUPPORTED_OPERATION if the API is unsupported or the request params can't be
+     *         served.
+     */
+    GpuHeadroomResult getGpuHeadroom(in GpuHeadroomParams params);
+
+    /**
+     * Sent to PowerHAL when there are surface-attached sessions being composed,
+     * providing FPS and frame timing data that can be used to supplement
+     * and validate timing sent via reportActual. This call can be batched,
+     * especially in the case of a steady state or low-intensity workload.
+     *
+     * @param   data The aggregated composition data object.
+     */
+    oneway void sendCompositionData(in CompositionData[] data);
+
+    /**
+     * Sent to inform the HAL about important updates outside of the normal
+     * reporting cycle, such as lifecycle updates for displays or FrameProducers.
+     *
+     * @param   update The aggregated composition update object.
+     */
+    oneway void sendCompositionUpdate(in CompositionUpdate update);
 }
diff --git a/power/aidl/android/hardware/power/LatchedFrameData.aidl b/power/aidl/android/hardware/power/LatchedFrameData.aidl
new file mode 100644
index 0000000..0642669
--- /dev/null
+++ b/power/aidl/android/hardware/power/LatchedFrameData.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+/**
+ * Frame information for a specific frame producer on a specific composition, used to
+ * provide timing information and adjust boosting or scheduling strategies for sessions
+ * associated with that producer to compensate for observed behavior.
+ *
+ * All timestamps use SYSTEM_TIME_MONOTONIC clock, at nanosecond resolution.
+ */
+@VintfStability
+parcelable LatchedFrameData {
+    /**
+     * Timestamp for the start of this frame, will be set to -1 if unknown.
+     */
+    long frameStartTimestampNanos;
+
+    /**
+     * Original, intended presentation time of the frame.
+     *
+     * This can be used along with the buffer submission timestamp to infer
+     * if the frame was supposed to present during a previous composition and got delayed.
+     *
+     * It can be compared with the "intendedPresentTimestampNanos" on WorkDurations to
+     * determine which reported duration sessions correspond with which LatchedFrameData,
+     * for sessions that use both manual reporting and have associated FrameProducers
+     */
+    long intendedPresentTimestampNanos;
+
+    /**
+     * Timestamp of buffer submission to SF from the CPU.
+     */
+    long bufferSubmissionTimestampNanos;
+
+    /**
+     * Timestamp where the GPU fence signaled, will be set to -1 if the buffer
+     * latched unsignaled or if the GPU was not used.
+     */
+    long gpuSignalTimestampNanos;
+
+    /**
+     * True if this frame used the GPU for rendering.
+     */
+    boolean usedGpu;
+
+    /**
+     * Optional GPU fence, sent only when the buffer latches unsignaled, and if
+     * sending fences is configured on the device in SupportInfo. If the updates
+     * are batched, a fence will only be sent for the most recent update.
+     *
+     * Can be used to get accurate gpu completion timestamps, and to boost if it
+     * looks like a frame might not signal before the deadline.
+     */
+    @nullable ParcelFileDescriptor gpuAcquireFence;
+}
diff --git a/power/aidl/android/hardware/power/SessionHint.aidl b/power/aidl/android/hardware/power/SessionHint.aidl
index 1a8c505..1b8a3dd 100644
--- a/power/aidl/android/hardware/power/SessionHint.aidl
+++ b/power/aidl/android/hardware/power/SessionHint.aidl
@@ -72,4 +72,18 @@
      * baseline to prepare for an arbitrary load, and must wake up if inactive.
      */
     GPU_LOAD_RESET = 7,
+
+    /**
+     * This hint indicates an upcoming CPU workload that is abnormally large and
+     * not representative of the workload. This should be used for rare, one-time
+     * operations and should be ignored by any load tracking or session hysteresis.
+     */
+    CPU_LOAD_SPIKE = 8,
+
+    /**
+     * This hint indicates an upcoming GPU workload that is abnormally large and
+     * not representative of the workload. This should be used for rare, one-time
+     * operations and should be ignored by any load tracking or session hysteresis.
+     */
+    GPU_LOAD_SPIKE = 9,
 }
diff --git a/power/aidl/android/hardware/power/SessionMode.aidl b/power/aidl/android/hardware/power/SessionMode.aidl
index f1ee64e..5bd0e15 100644
--- a/power/aidl/android/hardware/power/SessionMode.aidl
+++ b/power/aidl/android/hardware/power/SessionMode.aidl
@@ -25,4 +25,27 @@
      * and can be safely scheduled to prefer power efficiency.
      */
     POWER_EFFICIENCY,
+
+    /**
+     * This mode indicates that the threads associated with this hint session
+     * are part of the graphics pipeline, implying that they are on a critical path
+     * which will be called of higher priority in terms of CPU resources and scheduling.
+     */
+    GRAPHICS_PIPELINE,
+
+    /**
+     * This mode indicates that the session does not intend to report CPU timing
+     * information, and that it instead will rely entirely on information from
+     * SurfaceFlinger. This mode is only supported for sessions that have
+     * GRAPHICS_PIPELINE enabled.
+     */
+    AUTO_CPU,
+
+    /**
+     * This mode indicates that the session does not intend to report GPU timing
+     * information, and that it instead will rely entirely on information from
+     * SurfaceFlinger. This mode is only supported for sessions that have
+     * GRAPHICS_PIPELINE enabled.
+     */
+    AUTO_GPU,
 }
diff --git a/power/aidl/android/hardware/power/SessionTag.aidl b/power/aidl/android/hardware/power/SessionTag.aidl
index 27bf3e3..e98cc77 100644
--- a/power/aidl/android/hardware/power/SessionTag.aidl
+++ b/power/aidl/android/hardware/power/SessionTag.aidl
@@ -46,4 +46,9 @@
      * instead.
      */
     APP,
+
+    /**
+     * This tag is used to mark hint sessions created by the system UI.
+     */
+    SYSUI,
 }
diff --git a/power/aidl/android/hardware/power/SupportInfo.aidl b/power/aidl/android/hardware/power/SupportInfo.aidl
new file mode 100644
index 0000000..55287cb
--- /dev/null
+++ b/power/aidl/android/hardware/power/SupportInfo.aidl
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.power;
+
+import android.hardware.power.Boost;
+import android.hardware.power.Mode;
+import android.hardware.power.SessionHint;
+import android.hardware.power.SessionMode;
+
+/**
+ * Tells clients the status of various PowerHAL features in a single call.
+ * SupportInfo consists of several bitsets, where each bit from the left
+ * corresponds to the support status of that same value of that enum index.
+ *
+ * For "Boost", having the first bit set would mean "INTERACTION"
+ * boost is supported, having the second bit set would mean
+ * "DISPLAY_UPDATE_IMMINENT" is supported, and so on. The expectation
+ * is that a client should be able to index the bitset like
+ * "(supportInfo.boosts >> Boost::AUDIO_LAUNCH) % 2" and it should return
+ * the support value of Boost::AUDIO_LAUNCH. This pattern is the same for
+ * all four support bitsets.
+ */
+@VintfStability
+parcelable SupportInfo {
+    /**
+     * Boolean representing whether hint sessions are supported on this device.
+     */
+    boolean usesSessions;
+
+    /**
+     * The set of "Boost" enum values that are supported by this device,
+     * each bit should correspond to a value of the "Boost.aidl" enum.
+     */
+    long boosts;
+
+    /**
+     * The set of "Mode" enum values that are supported by this device,
+     * each bit should correspond to a value of the "Mode.aidl" enum.
+     */
+    long modes;
+
+    /**
+     * The set of "SessionHint" enum values that are supported by this device,
+     * each bit should correspond to a value of the "SessionHint.aidl" enum.
+     */
+    long sessionHints;
+
+    /**
+     * The set of "SessionMode" enum values that are supported by this device,
+     * each bit should correspond to a value of the "SessionMode.aidl" enum.
+     */
+    long sessionModes;
+
+    /**
+     * The set of "SessionTag" enum values that are supported by this device,
+     * each bit should correspond to a value of the "SessionTag.aidl" enum.
+     */
+    long sessionTags;
+
+    /**
+     * Parcel detailing support info for receiving additional frame composition
+     * data when sessions are associated with frame producers.
+     */
+    CompositionDataSupportInfo compositionData;
+
+    /**
+     *  Parcel detailing support info for headroom information.
+     */
+    HeadroomSupportInfo headroom;
+
+    @VintfStability
+    parcelable CompositionDataSupportInfo {
+        /**
+         * Whether the sendCompositionData and sendCompositionUpdate APIs are
+         * supported on this device. The rest of the fields on this parcelable
+         * are ignored if this is false.
+         */
+        boolean isSupported;
+
+        /**
+         * Whether to disable sending relevant GPU fence file descriptors along with
+         * timing information when the frame callback happens.
+         */
+        boolean disableGpuFences;
+
+        /**
+         * The maximum number of updates to batch before sending. This can be ignored
+         * if "overrideIfUrgent" is set. Setting to a value less than or equal to 1
+         * disables batching entirely.
+         */
+        int maxBatchSize;
+
+        /**
+         * Whether to ignore important notifications such as FPS changes and frame
+         * deadline misses, and always send maximum size batches. By default, the
+         * framework will send batches early if these important events happen.
+         */
+        boolean alwaysBatch;
+    }
+
+    @VintfStability
+    parcelable HeadroomSupportInfo {
+        /**
+         * Whether the CPU headroom feature is supported.
+         */
+        boolean isCpuSupported;
+
+        /**
+         * Whether the GPU headroom feature is supported.
+         */
+        boolean isGpuSupported;
+
+        /**
+         * Minimum polling interval for calling getCpuHeadroom in milliseconds
+         *
+         * The getCpuHeadroom API may return cached result if called more frequent
+         * than the interval.
+         */
+        int cpuMinIntervalMillis;
+
+        /**
+         * Minimum polling interval for calling getGpuHeadroom in milliseconds.
+         *
+         * The getGpuHeadroom API may return cached result if called more frequent
+         * than the interval.
+         */
+        int gpuMinIntervalMillis;
+    }
+}
diff --git a/power/aidl/android/hardware/power/WorkDuration.aidl b/power/aidl/android/hardware/power/WorkDuration.aidl
index fcd638b..bcf279a 100644
--- a/power/aidl/android/hardware/power/WorkDuration.aidl
+++ b/power/aidl/android/hardware/power/WorkDuration.aidl
@@ -19,7 +19,7 @@
 @VintfStability
 parcelable WorkDuration {
     /**
-     * Time stamp in nanoseconds based on CLOCK_MONOTONIC when the duration
+     * Timestamp in nanoseconds based on CLOCK_MONOTONIC when the duration
      * sample was measured.
      */
     long timeStampNanos;
@@ -49,4 +49,21 @@
      * SDK/NDK reportActualWorkDuration API.
      */
     long gpuDurationNanos;
+
+    /**
+     * Timestamp indicating the approximate time when this frame is intended to
+     * present by the app, and will be required for all sessions associated with
+     * frame producers. This should always be provided if the session is associated
+     * with a pipeline, even if it is not using the GRAPHICS_PIPELINE mode.
+     *
+     * This timestamp is intended to be used for correlating CompositionData timing
+     * information with reported WorkDurations from apps. WorkDurations for
+     * sessions associated with a frame producers, without a reasonable value set
+     * for this field should be discarded.
+     *
+     * Intended vsync times can be inferred or retrieved from Choreographer callbacks.
+     * While this timestamp is not required to be perfectly accurate, it should
+     * roughly correspond with an expected vsync time, and should be discarded otherwise.
+     */
+    long intendedPresentTimestampNanos;
 }
diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp
index 64294e5..0a9c90f 100644
--- a/power/aidl/default/Power.cpp
+++ b/power/aidl/default/Power.cpp
@@ -33,6 +33,8 @@
 using ::aidl::android::hardware::common::fmq::MQDescriptor;
 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using ::aidl::android::hardware::power::ChannelMessage;
+using ::aidl::android::hardware::power::CompositionData;
+using ::aidl::android::hardware::power::CompositionUpdate;
 using ::android::AidlMessageQueue;
 
 using ndk::ScopedAStatus;
@@ -41,6 +43,11 @@
                                      ndk::enum_range<Boost>().end()};
 const std::vector<Mode> MODE_RANGE{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};
 
+template <class T>
+constexpr size_t enum_size() {
+    return static_cast<size_t>(*(ndk::enum_range<T>().end() - 1)) + 1;
+}
+
 ScopedAStatus Power::setMode(Mode type, bool enabled) {
     LOG(VERBOSE) << "Power setMode: " << static_cast<int32_t>(type) << " to: " << enabled;
     return ScopedAStatus::ok();
@@ -64,6 +71,14 @@
     return ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus Power::getCpuHeadroom(const CpuHeadroomParams&, CpuHeadroomResult*) {
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Power::getGpuHeadroom(const GpuHeadroomParams&, GpuHeadroomResult*) {
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
 ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector<int32_t>& tids, int64_t,
                                        std::shared_ptr<IPowerHintSession>* _aidl_return) {
     if (tids.size() == 0) {
@@ -105,11 +120,50 @@
     return ndk::ScopedAStatus::ok();
 }
 
-ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
+ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t* outNanoseconds) {
     *outNanoseconds = std::chrono::nanoseconds(1ms).count();
     return ScopedAStatus::ok();
 }
 
+template <class E>
+int64_t bitsForEnum() {
+    return static_cast<int64_t>(std::bitset<enum_size<E>()>().set().to_ullong());
+}
+
+ndk::ScopedAStatus Power::getSupportInfo(SupportInfo* _aidl_return) {
+    static SupportInfo supportInfo = {.usesSessions = false,
+                                      .modes = bitsForEnum<Mode>(),
+                                      .boosts = bitsForEnum<Boost>(),
+                                      .sessionHints = 0,
+                                      .sessionModes = 0,
+                                      .sessionTags = 0,
+                                      .compositionData = {
+                                              .isSupported = false,
+                                              .disableGpuFences = false,
+                                              .maxBatchSize = 1,
+                                              .alwaysBatch = false,
+                                      },
+                                      .headroom = {
+                                              .isCpuSupported = false,
+                                              .isGpuSupported = false,
+                                              .cpuMinIntervalMillis = 0,
+                                              .gpuMinIntervalMillis = 0,
+                                      }};
+    // Copy the support object into the binder
+    *_aidl_return = supportInfo;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::sendCompositionData(const std::vector<CompositionData>&) {
+    LOG(INFO) << "Composition data received!";
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Power::sendCompositionUpdate(const CompositionUpdate&) {
+    LOG(INFO) << "Composition update received!";
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace example
 }  // namespace impl
 }  // namespace power
diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h
index baabaa7..118097f 100644
--- a/power/aidl/default/Power.h
+++ b/power/aidl/default/Power.h
@@ -44,6 +44,14 @@
     ndk::ScopedAStatus getSessionChannel(int32_t tgid, int32_t uid,
                                          ChannelConfig* _aidl_return) override;
     ndk::ScopedAStatus closeSessionChannel(int32_t tgid, int32_t uid) override;
+    ndk::ScopedAStatus getSupportInfo(SupportInfo* _aidl_return) override;
+    ndk::ScopedAStatus getCpuHeadroom(const CpuHeadroomParams& params,
+                                      CpuHeadroomResult* _aidl_return) override;
+
+    ndk::ScopedAStatus getGpuHeadroom(const GpuHeadroomParams& params,
+                                      GpuHeadroomResult* _aidl_return) override;
+    ndk::ScopedAStatus sendCompositionData(const std::vector<CompositionData>& in_data) override;
+    ndk::ScopedAStatus sendCompositionUpdate(const CompositionUpdate& in_update) override;
 
   private:
     std::vector<std::shared_ptr<IPowerHintSession>> mPowerHintSessions;
diff --git a/power/aidl/default/power-default.xml b/power/aidl/default/power-default.xml
index 418fb83..1bb73f3 100644
--- a/power/aidl/default/power-default.xml
+++ b/power/aidl/default/power-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.power</name>
-        <version>5</version>
+        <version>6</version>
         <fqname>IPower/default</fqname>
     </hal>
 </manifest>
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index 272674f..87797ae 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -30,21 +30,30 @@
 #include <unistd.h>
 #include <cstdint>
 #include "aidl/android/hardware/common/fmq/SynchronizedReadWrite.h"
+#include "aidl/android/hardware/power/CpuHeadroomParams.h"
+#include "aidl/android/hardware/power/GpuHeadroomParams.h"
 
 namespace aidl::android::hardware::power {
 namespace {
 
+using namespace std::chrono_literals;
+
 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using ::android::AidlMessageQueue;
 using ::android::hardware::EventFlag;
 using android::hardware::power::Boost;
 using android::hardware::power::ChannelConfig;
 using android::hardware::power::ChannelMessage;
+using android::hardware::power::CpuHeadroomParams;
+using android::hardware::power::CpuHeadroomResult;
+using android::hardware::power::GpuHeadroomParams;
+using android::hardware::power::GpuHeadroomResult;
 using android::hardware::power::IPower;
 using android::hardware::power::IPowerHintSession;
 using android::hardware::power::Mode;
 using android::hardware::power::SessionHint;
 using android::hardware::power::SessionMode;
+using android::hardware::power::SupportInfo;
 using android::hardware::power::WorkDuration;
 using ChannelMessageContents = ChannelMessage::ChannelMessageContents;
 using ModeSetter = ChannelMessage::ChannelMessageContents::SessionModeSetter;
@@ -83,6 +92,16 @@
         static_cast<SessionMode>(static_cast<int32_t>(kSessionModes.back()) + 1),
 };
 
+template <class T>
+constexpr size_t enum_size() {
+    return static_cast<size_t>(*(ndk::enum_range<T>().end() - 1)) + 1;
+}
+
+template <class E>
+bool supportFromBitset(int64_t& supportInt, E type) {
+    return (supportInt >> static_cast<int>(type)) % 2;
+}
+
 class DurationWrapper : public WorkDuration {
   public:
     DurationWrapper(int64_t dur, int64_t time) {
@@ -126,12 +145,17 @@
             status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &mSession);
             mSessionSupport = status.isOk();
         }
+        if (mServiceVersion >= 6) {
+            mSupportInfo = std::make_optional<SupportInfo>();
+            ASSERT_TRUE(power->getSupportInfo(&(*mSupportInfo)).isOk());
+        }
     }
 
     std::shared_ptr<IPower> power;
     int32_t mServiceVersion;
     std::shared_ptr<IPowerHintSession> mSession;
     bool mSessionSupport = false;
+    std::optional<SupportInfo> mSupportInfo = std::nullopt;
 };
 
 class HintSessionAidl : public PowerAidl {
@@ -280,6 +304,42 @@
     ASSERT_NE(nullptr, session);
 }
 
+TEST_P(PowerAidl, getCpuHeadroom) {
+    if (mServiceVersion < 6) {
+        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
+    }
+    CpuHeadroomParams params;
+    CpuHeadroomResult headroom;
+    auto ret = power->getCpuHeadroom(params, &headroom);
+    if (!mSupportInfo->headroom.isCpuSupported) {
+        ASSERT_EQ(ret.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+        GTEST_SKIP() << "power->getCpuHeadroom is not supported";
+    }
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_GE(mSupportInfo->headroom.cpuMinIntervalMillis, 0);
+    ASSERT_EQ(headroom.getTag(), CpuHeadroomResult::globalHeadroom);
+    ASSERT_GE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 0.0f);
+    ASSERT_LE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 100.00f);
+}
+
+TEST_P(PowerAidl, getGpuHeadroom) {
+    if (mServiceVersion < 6) {
+        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
+    }
+    GpuHeadroomParams params;
+    GpuHeadroomResult headroom;
+    auto ret = power->getGpuHeadroom(params, &headroom);
+    if (!mSupportInfo->headroom.isGpuSupported) {
+        ASSERT_EQ(ret.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+        GTEST_SKIP() << "power->getGpuHeadroom is not supported";
+    }
+    ASSERT_TRUE(ret.isOk());
+    ASSERT_GE(mSupportInfo->headroom.gpuMinIntervalMillis, 0);
+    ASSERT_EQ(headroom.getTag(), GpuHeadroomResult::globalHeadroom);
+    ASSERT_GE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 0.0f);
+    ASSERT_LE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 100.00f);
+}
+
 // FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
 // or later
 TEST_P(PowerAidl, hasFixedPerformance) {
@@ -288,6 +348,50 @@
     ASSERT_TRUE(supported);
 }
 
+TEST_P(PowerAidl, hasSupportInfo) {
+    if (mServiceVersion < 6) {
+        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
+    }
+    ASSERT_TRUE(mSupportInfo.has_value());
+    for (Mode mode : kModes) {
+        bool supported;
+        power->isModeSupported(mode, &supported);
+        ASSERT_EQ(supported, supportFromBitset(mSupportInfo->modes, mode));
+    }
+    for (Boost boost : kBoosts) {
+        bool supported;
+        power->isBoostSupported(boost, &supported);
+        ASSERT_EQ(supported, supportFromBitset(mSupportInfo->boosts, boost));
+    }
+}
+
+TEST_P(PowerAidl, receivesCompositionData) {
+    if (mServiceVersion < 6) {
+        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
+    }
+    if (mSupportInfo->compositionData.isSupported) {
+        GTEST_SKIP() << "Composition data marked as unsupported.";
+    }
+    // Sending an empty object is fine, we just want to confirm it accepts the tx
+    std::vector<CompositionData> out{};
+    out.emplace_back();
+    auto status = power->sendCompositionData(out);
+    ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(PowerAidl, receivesCompositionUpdate) {
+    if (mServiceVersion < 6) {
+        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
+    }
+    if (mSupportInfo->compositionData.isSupported) {
+        GTEST_SKIP() << "Composition data marked as unsupported.";
+    }
+
+    CompositionUpdate out{};
+    auto status = power->sendCompositionUpdate(out);
+    ASSERT_TRUE(status.isOk());
+}
+
 TEST_P(HintSessionAidl, createAndCloseHintSession) {
     if (!mSessionSupport) {
         GTEST_SKIP() << "DEVICE not support Hint Session.";
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
index bba6bdd..ded4835 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfig.aidl
@@ -53,4 +53,6 @@
   oneway void setResponseFunctions(in android.hardware.radio.config.IRadioConfigResponse radioConfigResponse, in android.hardware.radio.config.IRadioConfigIndication radioConfigIndication);
   oneway void setSimSlotsMapping(in int serial, in android.hardware.radio.config.SlotPortMapping[] slotMap);
   oneway void getSimultaneousCallingSupport(in int serial);
+  oneway void getSimTypeInfo(in int serial);
+  oneway void setSimType(in int serial, in android.hardware.radio.config.SimType[] simTypes);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
index 6ff7bd0..4e0e133 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -43,4 +43,6 @@
   oneway void setPreferredDataModemResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setSimSlotsMappingResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void getSimultaneousCallingSupportResponse(in android.hardware.radio.RadioResponseInfo info, in int[] enabledLogicalSlots);
+  oneway void getSimTypeInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.config.SimTypeInfo[] simTypeInfo);
+  oneway void setSimTypeResponse(in android.hardware.radio.RadioResponseInfo info);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimType.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimType.aidl
index a5eda52..b27c86f 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimType.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.radio.config;
+/* @hide */
+@Backing(type="int") @JavaDerive(toString=true) @VintfStability
+enum SimType {
+  UNKNOWN = 0,
+  PHYSICAL = (1 << 0) /* 1 */,
+  ESIM = (1 << 1) /* 2 */,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl
similarity index 86%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl
index a5eda52..cba5dd9 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.config/current/android/hardware/radio/config/SimTypeInfo.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.radio.config;
+/* @hide */
+@JavaDerive(toString=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.data/current/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
index a0ca4bf..1f8cbdc 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataCallFailCause.aidl
@@ -169,6 +169,9 @@
   MAX_PPP_INACTIVITY_TIMER_EXPIRED = 0x7FE,
   IPV6_ADDRESS_TRANSFER_FAILED = 0x7FF,
   TRAT_SWAP_FAILED = 0x800,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EHRPD_TO_HRPD_FALLBACK = 0x801,
   MIP_CONFIG_FAILURE = 0x802,
   PDN_INACTIVITY_TIMER_EXPIRED = 0x803,
@@ -192,11 +195,29 @@
   NON_IP_NOT_SUPPORTED = 0x815,
   PDN_NON_IP_CALL_THROTTLED = 0x816,
   PDN_NON_IP_CALL_DISALLOWED = 0x817,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_LOCK = 0x818,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_INTERCEPT = 0x819,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_REORDER = 0x81A,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_RELEASE_DUE_TO_SO_REJECTION = 0x81B,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_INCOMING_CALL = 0x81C,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_ALERT_STOP = 0x81D,
   CHANNEL_ACQUISITION_FAILURE = 0x81E,
   MAX_ACCESS_PROBE = 0x81F,
@@ -204,8 +225,14 @@
   NO_RESPONSE_FROM_BASE_STATION = 0x821,
   REJECTED_BY_BASE_STATION = 0x822,
   CONCURRENT_SERVICES_INCOMPATIBLE = 0x823,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   NO_CDMA_SERVICE = 0x824,
   RUIM_NOT_PRESENT = 0x825,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_RETRY_ORDER = 0x826,
   ACCESS_BLOCK = 0x827,
   ACCESS_BLOCK_ALL = 0x828,
@@ -324,12 +351,33 @@
   LOWER_LAYER_REGISTRATION_FAILURE = 0x895,
   DATA_PLAN_EXPIRED = 0x896,
   UMTS_HANDOVER_TO_IWLAN = 0x897,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 0x898,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 0x899,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_HDR_CHANGED = 0x89A,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_HDR_EXITED = 0x89B,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_HDR_NO_SESSION = 0x89C,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 0x89D,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 0x89E,
   FAILED_TO_ACQUIRE_COLOCATED_HDR = 0x89F,
   OTASP_COMMIT_IN_PROGRESS = 0x8A0,
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 abfb308..99ab0ea 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
@@ -35,7 +35,16 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaBroadcastSmsConfigInfo {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int serviceCategory;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int language;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   boolean selected;
 }
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 ee8371c..00e584b 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
@@ -35,6 +35,12 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsAck {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   boolean errorClass;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int smsCauseCode;
 }
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 7382b1f..6a64595 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
@@ -35,35 +35,128 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsAddress {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int digitMode;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   boolean isNumberModeDataNetwork;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int numberType;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int numberPlan;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte[] digits;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int DIGIT_MODE_FOUR_BIT = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int DIGIT_MODE_EIGHT_BIT = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_UNKNOWN = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_TELEPHONY = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_2 = 2;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_DATA = 3;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_TELEX = 4;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_5 = 5;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_6 = 6;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_7 = 7;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_8 = 8;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_PRIVATE = 9;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_10 = 10;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_11 = 11;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_12 = 12;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_13 = 13;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_14 = 14;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_RESERVED_15 = 15;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_UNKNOWN = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_INTERNATIONAL_OR_DATA_IP = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_NATIONAL_OR_INTERNET_MAIL = 2;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_NETWORK = 3;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_SUBSCRIBER = 4;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_ALPHANUMERIC = 5;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_ABBREVIATED = 6;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_RESERVED_7 = 7;
 }
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 0e98f4b..bbf8983 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
@@ -35,10 +35,28 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsMessage {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int teleserviceId;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   boolean isServicePresent;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int serviceCategory;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.messaging.CdmaSmsAddress address;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.messaging.CdmaSmsSubaddress subAddress;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte[] bearerData;
 }
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 9982395..95bfd4c 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
@@ -35,9 +35,24 @@
 /* @hide */
 @JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaSmsSubaddress {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int subaddressType;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   boolean odd;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte[] digits;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int SUBADDRESS_TYPE_NSAP = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int SUBADDRESS_TYPE_USER_SPECIFIED = 1;
 }
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 d6292e7..759407f 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
@@ -35,10 +35,28 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaSmsWriteArgs {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int status;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.messaging.CdmaSmsMessage message;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int STATUS_REC_UNREAD = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int STATUS_REC_READ = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int STATUS_STO_UNSENT = 2;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int STATUS_STO_SENT = 3;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
index bf5fde5..c69fcac 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessaging.aidl
@@ -36,26 +36,50 @@
 @VintfStability
 interface IRadioMessaging {
   oneway void acknowledgeIncomingGsmSmsWithPdu(in int serial, in boolean success, in String ackPdu);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void acknowledgeLastIncomingCdmaSms(in int serial, in android.hardware.radio.messaging.CdmaSmsAck smsAck);
   oneway void acknowledgeLastIncomingGsmSms(in int serial, in boolean success, in android.hardware.radio.messaging.SmsAcknowledgeFailCause cause);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void deleteSmsOnRuim(in int serial, in int index);
   oneway void deleteSmsOnSim(in int serial, in int index);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void getCdmaBroadcastConfig(in int serial);
   oneway void getGsmBroadcastConfig(in int serial);
   oneway void getSmscAddress(in int serial);
   oneway void reportSmsMemoryStatus(in int serial, in boolean available);
   oneway void responseAcknowledgement();
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void sendCdmaSms(in int serial, in android.hardware.radio.messaging.CdmaSmsMessage sms);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void sendCdmaSmsExpectMore(in int serial, in android.hardware.radio.messaging.CdmaSmsMessage sms);
   oneway void sendImsSms(in int serial, in android.hardware.radio.messaging.ImsSmsMessage message);
   oneway void sendSms(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message);
   oneway void sendSmsExpectMore(in int serial, in android.hardware.radio.messaging.GsmSmsMessage message);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void setCdmaBroadcastActivation(in int serial, in boolean activate);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void setCdmaBroadcastConfig(in int serial, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configInfo);
   oneway void setGsmBroadcastActivation(in int serial, in boolean activate);
   oneway void setGsmBroadcastConfig(in int serial, in android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configInfo);
   oneway void setResponseFunctions(in android.hardware.radio.messaging.IRadioMessagingResponse radioMessagingResponse, in android.hardware.radio.messaging.IRadioMessagingIndication radioMessagingIndication);
   oneway void setSmscAddress(in int serial, in String smsc);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void writeSmsToRuim(in int serial, in android.hardware.radio.messaging.CdmaSmsWriteArgs cdmaSms);
   oneway void writeSmsToSim(in int serial, in android.hardware.radio.messaging.SmsWriteArgs smsWriteArgs);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
index 389fb26..a5cde9a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
@@ -35,7 +35,13 @@
 /* @hide */
 @VintfStability
 interface IRadioMessagingIndication {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void cdmaNewSms(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.messaging.CdmaSmsMessage msg);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void cdmaRuimSmsStorageFull(in android.hardware.radio.RadioIndicationType type);
   oneway void newBroadcastSms(in android.hardware.radio.RadioIndicationType type, in byte[] data);
   oneway void newSms(in android.hardware.radio.RadioIndicationType type, in byte[] pdu);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
index 9b10464..c2403e4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.messaging/current/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -36,25 +36,49 @@
 @VintfStability
 interface IRadioMessagingResponse {
   oneway void acknowledgeIncomingGsmSmsWithPduResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void acknowledgeLastIncomingCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void acknowledgeLastIncomingGsmSmsResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void acknowledgeRequest(in int serial);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void deleteSmsOnRuimResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void deleteSmsOnSimResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void getCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configs);
   oneway void getGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configs);
   oneway void getSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info, in String smsc);
   oneway void reportSmsMemoryStatusResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void sendCdmaSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void sendCdmaSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
   oneway void sendImsSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
   oneway void sendSmsExpectMoreResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
   oneway void sendSmsResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.messaging.SendSmsResult sms);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void setCdmaBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void setCdmaBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setGsmBroadcastActivationResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setGsmBroadcastConfigResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setSmscAddressResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void writeSmsToRuimResponse(in android.hardware.radio.RadioResponseInfo info, in int index);
   oneway void writeSmsToSimResponse(in android.hardware.radio.RadioResponseInfo info, in int index);
 }
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 ff4a111..3af0f8d 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
@@ -38,6 +38,9 @@
   android.hardware.radio.RadioTechnologyFamily tech = android.hardware.radio.RadioTechnologyFamily.THREE_GPP;
   boolean retry;
   int messageRef;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.messaging.CdmaSmsMessage[] cdmaMessage;
   android.hardware.radio.messaging.GsmSmsMessage[] gsmMessage;
 }
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 3f1d120..ae398a9 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
@@ -35,7 +35,16 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable SendSmsResult {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int messageRef;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   String ackPDU;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int errorCode;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
index e9937f0..33c0d70 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.modem/current/android/hardware/radio/modem/ResetNvType.aidl
@@ -36,6 +36,12 @@
 @Backing(type="int") @JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 enum ResetNvType {
   RELOAD,
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
   ERASE,
+  /**
+   * @deprecated NV APIs are deprecated starting from Android U.
+   */
   FACTORY_RESET,
 }
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 667a8a7..36b9cdd 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
@@ -36,6 +36,9 @@
 @JavaDerive(toString=true) @VintfStability
 union AccessTechnologySpecificInfo {
   boolean noinit;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.Cdma2000RegistrationInfo cdmaInfo;
   android.hardware.radio.network.EutranRegistrationInfo eutranInfo;
   android.hardware.radio.network.NrVopsInfo ngranNrVopsInfo;
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 bc9c0ba..5fbd6c4 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
@@ -35,11 +35,32 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable Cdma2000RegistrationInfo {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   boolean cssSupported;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int roamingIndicator;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int systemIsInPrl;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int defaultRoamingIndicator;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int PRL_INDICATOR_NOT_REGISTERED = (-1) /* -1 */;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int PRL_INDICATOR_NOT_IN_PRL = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int PRL_INDICATOR_IN_PRL = 1;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
index 84532e3..ed9a9eb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/CdmaRoamingType.aidl
@@ -35,7 +35,16 @@
 /* @hide */
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaRoamingType {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   HOME_NETWORK,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   AFFILIATED_ROAM,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   ANY_ROAM,
 }
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 94430a8..6e68665 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
@@ -35,6 +35,12 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaSignalStrength {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int dbm;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int ecio;
 }
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 ba27b39..dbd1575 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
@@ -39,6 +39,9 @@
   android.hardware.radio.network.CellIdentityGsm gsm;
   android.hardware.radio.network.CellIdentityWcdma wcdma;
   android.hardware.radio.network.CellIdentityTdscdma tdscdma;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.CellIdentityCdma cdma;
   android.hardware.radio.network.CellIdentityLte lte;
   android.hardware.radio.network.CellIdentityNr nr;
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 63571bb..548afd2 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
@@ -35,10 +35,28 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CellIdentityCdma {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int networkId;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int systemId;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int baseStationId;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int longitude;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int latitude;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.OperatorInfo operatorNames;
 }
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 6d76a26..18c9496 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
@@ -35,7 +35,16 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CellInfoCdma {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.CellIdentityCdma cellIdentityCdma;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.CdmaSignalStrength signalStrengthCdma;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.EvdoSignalStrength signalStrengthEvdo;
 }
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 fd3239d..732e70f 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
@@ -40,5 +40,8 @@
   android.hardware.radio.network.CellInfoTdscdma tdscdma;
   android.hardware.radio.network.CellInfoLte lte;
   android.hardware.radio.network.CellInfoNr nr;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.CellInfoCdma cdma;
 }
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 e97e17d..2a7eccb 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
@@ -35,7 +35,16 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable EvdoSignalStrength {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int dbm;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int ecio;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int signalNoiseRatio;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
index 8af617f..ad7473b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
@@ -36,9 +36,15 @@
 @VintfStability
 interface IRadioNetwork {
   oneway void getAllowedNetworkTypesBitmap(in int serial);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void getAvailableBandModes(in int serial);
   oneway void getAvailableNetworks(in int serial);
   oneway void getBarringInfo(in int serial);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void getCdmaRoamingPreference(in int serial);
   oneway void getCellInfoList(in int serial);
   oneway void getDataRegistrationState(in int serial);
@@ -55,18 +61,30 @@
   oneway void isNrDualConnectivityEnabled(in int serial);
   oneway void responseAcknowledgement();
   oneway void setAllowedNetworkTypesBitmap(in int serial, in int networkTypeBitmap);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void setBandMode(in int serial, in android.hardware.radio.network.RadioBandMode mode);
   oneway void setBarringPassword(in int serial, in String facility, in String oldPassword, in String newPassword);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void setCdmaRoamingPreference(in int serial, in android.hardware.radio.network.CdmaRoamingType type);
   oneway void setCellInfoListRate(in int serial, in int rate);
   oneway void setIndicationFilter(in int serial, in int indicationFilter);
   oneway void setLinkCapacityReportingCriteria(in int serial, in int hysteresisMs, in int hysteresisDlKbps, in int hysteresisUlKbps, in int[] thresholdsDownlinkKbps, in int[] thresholdsUplinkKbps, in android.hardware.radio.AccessNetwork accessNetwork);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void setLocationUpdates(in int serial, in boolean enable);
   oneway void setNetworkSelectionModeAutomatic(in int serial);
   oneway void setNetworkSelectionModeManual(in int serial, in String operatorNumeric, in android.hardware.radio.AccessNetwork ran);
   oneway void setNrDualConnectivityState(in int serial, in android.hardware.radio.network.NrDualConnectivityState nrDualConnectivityState);
   oneway void setResponseFunctions(in android.hardware.radio.network.IRadioNetworkResponse radioNetworkResponse, in android.hardware.radio.network.IRadioNetworkIndication radioNetworkIndication);
   oneway void setSignalStrengthReportingCriteria(in int serial, in android.hardware.radio.network.SignalThresholdInfo[] signalThresholdInfos);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void setSuppServiceNotifications(in int serial, in boolean enable);
   oneway void setSystemSelectionChannels(in int serial, in boolean specifyChannels, in android.hardware.radio.network.RadioAccessSpecifier[] specifiers);
   oneway void startNetworkScan(in int serial, in android.hardware.radio.network.NetworkScanRequest request);
@@ -86,4 +104,7 @@
   oneway void setCellularIdentifierTransparencyEnabled(in int serial, in boolean enabled);
   oneway void setSecurityAlgorithmsUpdatedEnabled(in int serial, boolean enable);
   oneway void isSecurityAlgorithmsUpdatedEnabled(in int serial);
+  oneway void setSatellitePlmn(in int serial, in int simSlot, in String[] carrierPlmnArray, in String[] allSatellitePlmnArray);
+  oneway void setSatelliteEnabledForCarrier(in int serial, in int simSlot, boolean satelliteEnabled);
+  oneway void isSatelliteEnabledForCarrier(in int serial, in int simSlot);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
index 8eea14f..d4d6118 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -36,6 +36,9 @@
 @VintfStability
 interface IRadioNetworkIndication {
   oneway void barringInfoChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellIdentity cellIdentity, in android.hardware.radio.network.BarringInfo[] barringInfos);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void cdmaPrlChanged(in android.hardware.radio.RadioIndicationType type, in int version);
   oneway void cellInfoList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.CellInfo[] records);
   oneway void currentLinkCapacityEstimate(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.network.LinkCapacityEstimate lce);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
index e7f2918..3c220ab 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -37,9 +37,15 @@
 interface IRadioNetworkResponse {
   oneway void acknowledgeRequest(in int serial);
   oneway void getAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info, in int networkTypeBitmap);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void getAvailableBandModesResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RadioBandMode[] bandModes);
   oneway void getAvailableNetworksResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.OperatorInfo[] networkInfos);
   oneway void getBarringInfoResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellIdentity cellIdentity, in android.hardware.radio.network.BarringInfo[] barringInfos);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void getCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CdmaRoamingType type);
   oneway void getCellInfoListResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.CellInfo[] cellInfo);
   oneway void getDataRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult dataRegResponse);
@@ -55,17 +61,29 @@
   oneway void getVoiceRegistrationStateResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.network.RegStateResult voiceRegResponse);
   oneway void isNrDualConnectivityEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
   oneway void setAllowedNetworkTypesBitmapResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void setBandModeResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setBarringPasswordResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void setCdmaRoamingPreferenceResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setCellInfoListRateResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setIndicationFilterResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setLinkCapacityReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void setLocationUpdatesResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setNetworkSelectionModeAutomaticResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setNetworkSelectionModeManualResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setNrDualConnectivityStateResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setSignalStrengthReportingCriteriaResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void setSuppServiceNotificationsResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setSystemSelectionChannelsResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void startNetworkScanResponse(in android.hardware.radio.RadioResponseInfo info);
@@ -85,4 +103,7 @@
   oneway void setCellularIdentifierTransparencyEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setSecurityAlgorithmsUpdatedEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void isSecurityAlgorithmsUpdatedEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
+  oneway void setSatellitePlmnResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void setSatelliteEnabledForCarrierResponse(in android.hardware.radio.RadioResponseInfo info);
+  oneway void isSatelliteEnabledForCarrierResponse(in android.hardware.radio.RadioResponseInfo info, boolean isEnabled);
 }
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 da7db9a..196ff19 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
@@ -36,7 +36,13 @@
 @JavaDerive(toString=true) @VintfStability
 parcelable SignalStrength {
   android.hardware.radio.network.GsmSignalStrength gsm;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.CdmaSignalStrength cdma;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.network.EvdoSignalStrength evdo;
   android.hardware.radio.network.LteSignalStrength lte;
   android.hardware.radio.network.TdscdmaSignalStrength tdscdma;
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 0d7e48a..788a2dc 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
@@ -38,6 +38,9 @@
   int cardState;
   android.hardware.radio.sim.PinState universalPinState = android.hardware.radio.sim.PinState.UNKNOWN;
   int gsmUmtsSubscriptionAppIndex;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int cdmaSubscriptionAppIndex;
   int imsSubscriptionAppIndex;
   android.hardware.radio.sim.AppStatus[] applications;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
index 13b06e7..d3e8295 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
@@ -35,6 +35,12 @@
 /* @hide */
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaSubscriptionSource {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   RUIM_SIM,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   NV,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
index 1728e41..c868f81 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSim.aidl
@@ -40,7 +40,13 @@
   oneway void changeIccPinForApp(in int serial, in String oldPin, in String newPin, in String aid);
   oneway void enableUiccApplications(in int serial, in boolean enable);
   oneway void getAllowedCarriers(in int serial);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void getCdmaSubscription(in int serial);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void getCdmaSubscriptionSource(in int serial);
   oneway void getFacilityLockForApp(in int serial, in String facility, in String password, in int serviceClass, in String appId);
   oneway void getIccCardStatus(in int serial);
@@ -63,10 +69,16 @@
   oneway void sendTerminalResponseToSim(in int serial, in String contents);
   oneway void setAllowedCarriers(in int serial, in android.hardware.radio.sim.CarrierRestrictions carriers, in android.hardware.radio.sim.SimLockMultiSimPolicy multiSimPolicy);
   oneway void setCarrierInfoForImsiEncryption(in int serial, in android.hardware.radio.sim.ImsiEncryptionInfo imsiEncryptionInfo);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void setCdmaSubscriptionSource(in int serial, in android.hardware.radio.sim.CdmaSubscriptionSource cdmaSub);
   oneway void setFacilityLockForApp(in int serial, in String facility, in boolean lockState, in String password, in int serviceClass, in String appId);
   oneway void setResponseFunctions(in android.hardware.radio.sim.IRadioSimResponse radioSimResponse, in android.hardware.radio.sim.IRadioSimIndication radioSimIndication);
   oneway void setSimCardPower(in int serial, in android.hardware.radio.sim.CardPowerState powerUp);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void setUiccSubscription(in int serial, in android.hardware.radio.sim.SelectUiccSub uiccSub);
   oneway void supplyIccPin2ForApp(in int serial, in String pin2, in String aid);
   oneway void supplyIccPinForApp(in int serial, in String pin, in String aid);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimIndication.aidl
index a74b65a..0c4df06 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimIndication.aidl
@@ -36,6 +36,9 @@
 @VintfStability
 interface IRadioSimIndication {
   oneway void carrierInfoForImsiEncryption(in android.hardware.radio.RadioIndicationType info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void cdmaSubscriptionSourceChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.sim.CdmaSubscriptionSource cdmaSource);
   oneway void simPhonebookChanged(in android.hardware.radio.RadioIndicationType type);
   oneway void simPhonebookRecordsReceived(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.sim.PbReceivedStatus status, in android.hardware.radio.sim.PhonebookRecordInfo[] records);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
index c653847..6526d8b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.sim/current/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -41,7 +41,13 @@
   oneway void changeIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
   oneway void enableUiccApplicationsResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void getAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CarrierRestrictions carriers, in android.hardware.radio.sim.SimLockMultiSimPolicy multiSimPolicy);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void getCdmaSubscriptionResponse(in android.hardware.radio.RadioResponseInfo info, in String mdn, in String hSid, in String hNid, in String min, in String prl);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void getCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CdmaSubscriptionSource source);
   oneway void getFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int response);
   oneway void getIccCardStatusResponse(in android.hardware.radio.RadioResponseInfo info, in android.hardware.radio.sim.CardStatus cardStatus);
@@ -63,9 +69,15 @@
   oneway void sendTerminalResponseToSimResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setAllowedCarriersResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setCarrierInfoForImsiEncryptionResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void setCdmaSubscriptionSourceResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void setFacilityLockForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int retry);
   oneway void setSimCardPowerResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Android Telephony framework doesn't use this.
+   */
   oneway void setUiccSubscriptionResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void supplyIccPin2ForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
   oneway void supplyIccPinForAppResponse(in android.hardware.radio.RadioResponseInfo info, in int remainingRetries);
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 27130b4..33af1fd 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
@@ -42,6 +42,9 @@
   boolean isMT;
   byte als;
   boolean isVoice;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   boolean isVoicePrivacy;
   String number;
   int numberPresentation;
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 0b36be4..7eb8c4e 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
@@ -35,24 +35,84 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaCallWaiting {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   String number;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int numberPresentation;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   String name;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaSignalInfoRecord signalInfoRecord;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int numberType;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int numberPlan;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_UNKNOWN = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_ISDN = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_DATA = 3;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_TELEX = 4;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_NATIONAL = 8;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PLAN_PRIVATE = 9;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PRESENTATION_ALLOWED = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PRESENTATION_RESTRICTED = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_PRESENTATION_UNKNOWN = 2;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_UNKNOWN = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_INTERNATIONAL = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_NATIONAL = 2;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_NETWORK_SPECIFIC = 3;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NUMBER_TYPE_SUBSCRIBER = 4;
 }
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 0142792..a673c93 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
@@ -35,6 +35,12 @@
 /* @hide */
 @JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaDisplayInfoRecord {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   String alphaBuf;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
 }
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 c71a8be..143409f 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
@@ -35,24 +35,84 @@
 /* @hide */
 @JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaInformationRecord {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int name;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaDisplayInfoRecord[] display;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaNumberInfoRecord[] number;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaSignalInfoRecord[] signal;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaRedirectingNumberInfoRecord[] redir;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaLineControlInfoRecord[] lineCtrl;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaT53ClirInfoRecord[] clir;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaT53AudioControlInfoRecord[] audioCtrl;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int CDMA_MAX_NUMBER_OF_INFO_RECS = 10;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_DISPLAY = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_CALLED_PARTY_NUMBER = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_CALLING_PARTY_NUMBER = 2;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_CONNECTED_NUMBER = 3;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_SIGNAL = 4;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_REDIRECTING_NUMBER = 5;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_LINE_CONTROL = 6;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_EXTENDED_DISPLAY = 7;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_T53_CLIR = 8;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_T53_RELEASE = 9;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int NAME_T53_AUDIO_CONTROL = 10;
 }
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 4e4a7ee..6968a8a 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
@@ -35,8 +35,20 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaLineControlInfoRecord {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte lineCtrlPolarityIncluded;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte lineCtrlToggle;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte lineCtrlReverse;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte lineCtrlPowerDenial;
 }
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 974e795..684b171 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
@@ -35,10 +35,28 @@
 /* @hide */
 @JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaNumberInfoRecord {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   String number;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte numberType;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte numberPlan;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte pi;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte si;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int CDMA_NUMBER_INFO_BUFFER_LENGTH = 81;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
index ae35fba..0bf802d 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
@@ -35,16 +35,52 @@
 /* @hide */
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum CdmaOtaProvisionStatus {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   SPL_UNLOCKED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   SPC_RETRIES_EXCEEDED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   A_KEY_EXCHANGED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   SSD_UPDATED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   NAM_DOWNLOADED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   MDN_DOWNLOADED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   IMSI_DOWNLOADED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   PRL_DOWNLOADED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   COMMITTED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   OTAPA_STARTED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   OTAPA_STOPPED,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   OTAPA_ABORTED,
 }
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 818d107..ce7c7c6 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
@@ -35,13 +35,40 @@
 /* @hide */
 @JavaDerive(toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
 parcelable CdmaRedirectingNumberInfoRecord {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   android.hardware.radio.voice.CdmaNumberInfoRecord redirectingNumber;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   int redirectingReason;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int REDIRECTING_REASON_UNKNOWN = 0;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int REDIRECTING_REASON_CALL_FORWARDING_NO_REPLY = 2;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int REDIRECTING_REASON_CALLED_DTE_OUT_OF_ORDER = 9;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int REDIRECTING_REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int REDIRECTING_REASON_CALL_FORWARDING_UNCONDITIONAL = 15;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   const int REDIRECTING_REASON_RESERVED = 16;
 }
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 69447b4..04e7bdc 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
@@ -35,8 +35,20 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaSignalInfoRecord {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   boolean isPresent;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte signalType;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte alertPitch;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte signal;
 }
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 69d79aa..733d822 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
@@ -35,6 +35,12 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaT53AudioControlInfoRecord {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte upLink;
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte downLink;
 }
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 83b6fb9..9cf931c 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
@@ -35,5 +35,8 @@
 /* @hide */
 @JavaDerive(toString=true) @VintfStability
 parcelable CdmaT53ClirInfoRecord {
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   byte cause;
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
index d0a9451..d519bd9 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoice.aidl
@@ -59,6 +59,9 @@
   oneway void rejectCall(in int serial);
   oneway void responseAcknowledgement();
   oneway void sendBurstDtmf(in int serial, in String dtmf, in int on, in int off);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void sendCdmaFeatureCode(in int serial, in String featureCode);
   oneway void sendDtmf(in int serial, in String s);
   oneway void sendUssd(in int serial, in String ussd);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index 4614ee1..fac27f4 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -37,8 +37,17 @@
 interface IRadioVoiceIndication {
   oneway void callRing(in android.hardware.radio.RadioIndicationType type, in boolean isGsm, in android.hardware.radio.voice.CdmaSignalInfoRecord record);
   oneway void callStateChanged(in android.hardware.radio.RadioIndicationType type);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void cdmaCallWaiting(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void cdmaInfoRec(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaInformationRecord[] records);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void cdmaOtaProvisionStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.CdmaOtaProvisionStatus status);
   oneway void currentEmergencyNumberList(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList);
   oneway void enterEmergencyCallbackMode(in android.hardware.radio.RadioIndicationType type);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index 46927c2..8a0af44 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -59,6 +59,9 @@
   oneway void isVoNrEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean enable);
   oneway void rejectCallResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void sendBurstDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   oneway void sendCdmaFeatureCodeResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void sendDtmfResponse(in android.hardware.radio.RadioResponseInfo info);
   oneway void sendUssdResponse(in android.hardware.radio.RadioResponseInfo info);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
index 17a039f..e6c223c 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.voice/current/android/hardware/radio/voice/LastCallFailCause.aidl
@@ -106,15 +106,45 @@
   RADIO_RELEASE_ABNORMAL = 259,
   ACCESS_CLASS_BLOCKED = 260,
   NETWORK_DETACH = 261,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_DROP = 1001,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_INTERCEPT = 1002,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_REORDER = 1003,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_SO_REJECT = 1004,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_RETRY_ORDER = 1005,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_ACCESS_FAILURE = 1006,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_PREEMPTED = 1007,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_NOT_EMERGENCY = 1008,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA_ACCESS_BLOCKED = 1009,
   OEM_CAUSE_1 = 0xf001,
   OEM_CAUSE_2 = 0xf002,
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
index 73a267b..c719846 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/AccessNetwork.aidl
@@ -39,6 +39,9 @@
   GERAN,
   UTRAN,
   EUTRAN,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   CDMA2000,
   IWLAN,
   NGRAN,
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
index 1298ab0..471916f 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioAccessFamily.aidl
@@ -39,15 +39,36 @@
   GPRS = (1 << android.hardware.radio.RadioTechnology.GPRS) /* 2 */,
   EDGE = (1 << android.hardware.radio.RadioTechnology.EDGE) /* 4 */,
   UMTS = (1 << android.hardware.radio.RadioTechnology.UMTS) /* 8 */,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   IS95A = (1 << android.hardware.radio.RadioTechnology.IS95A) /* 16 */,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   IS95B = (1 << android.hardware.radio.RadioTechnology.IS95B) /* 32 */,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   ONE_X_RTT = (1 << android.hardware.radio.RadioTechnology.ONE_X_RTT) /* 64 */,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_0 = (1 << android.hardware.radio.RadioTechnology.EVDO_0) /* 128 */,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_A = (1 << android.hardware.radio.RadioTechnology.EVDO_A) /* 256 */,
   HSDPA = (1 << android.hardware.radio.RadioTechnology.HSDPA) /* 512 */,
   HSUPA = (1 << android.hardware.radio.RadioTechnology.HSUPA) /* 1024 */,
   HSPA = (1 << android.hardware.radio.RadioTechnology.HSPA) /* 2048 */,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_B = (1 << android.hardware.radio.RadioTechnology.EVDO_B) /* 4096 */,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EHRPD = (1 << android.hardware.radio.RadioTechnology.EHRPD) /* 8192 */,
   LTE = (1 << android.hardware.radio.RadioTechnology.LTE) /* 16384 */,
   HSPAP = (1 << android.hardware.radio.RadioTechnology.HSPAP) /* 32768 */,
@@ -59,4 +80,5 @@
    */
   LTE_CA = (1 << android.hardware.radio.RadioTechnology.LTE_CA) /* 524288 */,
   NR = (1 << android.hardware.radio.RadioTechnology.NR) /* 1048576 */,
+  NB_IOT_NTN = (1 << android.hardware.radio.RadioTechnology.NB_IOT_NTN) /* 2097152 */,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
index 7c6a657..201e694 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnology.aidl
@@ -39,15 +39,36 @@
   GPRS,
   EDGE,
   UMTS,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   IS95A,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   IS95B,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   ONE_X_RTT,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_0,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_A,
   HSDPA,
   HSUPA,
   HSPA,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EVDO_B,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   EHRPD,
   LTE,
   HSPAP,
@@ -59,4 +80,5 @@
    */
   LTE_CA,
   NR,
+  NB_IOT_NTN,
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
index 85e9850..9b05c97 100644
--- a/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio/current/android/hardware/radio/RadioTechnologyFamily.aidl
@@ -36,5 +36,8 @@
 @Backing(type="int") @JavaDerive(toString=true) @VintfStability
 enum RadioTechnologyFamily {
   THREE_GPP,
+  /**
+   * @deprecated Legacy CDMA is unsupported.
+   */
   THREE_GPP2,
 }
diff --git a/radio/aidl/android/hardware/radio/AccessNetwork.aidl b/radio/aidl/android/hardware/radio/AccessNetwork.aidl
index 4099f83..0d10009 100644
--- a/radio/aidl/android/hardware/radio/AccessNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/AccessNetwork.aidl
@@ -39,6 +39,7 @@
     EUTRAN,
     /**
      * CDMA 2000 network
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA2000,
     /**
diff --git a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
index 9ab4583..8c10bb9 100644
--- a/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioAccessFamily.aidl
@@ -27,15 +27,22 @@
     GPRS = 1 << RadioTechnology.GPRS,
     EDGE = 1 << RadioTechnology.EDGE,
     UMTS = 1 << RadioTechnology.UMTS,
+    /** @deprecated Legacy CDMA is unsupported. */
     IS95A = 1 << RadioTechnology.IS95A,
+    /** @deprecated Legacy CDMA is unsupported. */
     IS95B = 1 << RadioTechnology.IS95B,
+    /** @deprecated Legacy CDMA is unsupported. */
     ONE_X_RTT = 1 << RadioTechnology.ONE_X_RTT,
+    /** @deprecated Legacy CDMA is unsupported. */
     EVDO_0 = 1 << RadioTechnology.EVDO_0,
+    /** @deprecated Legacy CDMA is unsupported. */
     EVDO_A = 1 << RadioTechnology.EVDO_A,
     HSDPA = 1 << RadioTechnology.HSDPA,
     HSUPA = 1 << RadioTechnology.HSUPA,
     HSPA = 1 << RadioTechnology.HSPA,
+    /** @deprecated Legacy CDMA is unsupported. */
     EVDO_B = 1 << RadioTechnology.EVDO_B,
+    /** @deprecated Legacy CDMA is unsupported. */
     EHRPD = 1 << RadioTechnology.EHRPD,
     LTE = 1 << RadioTechnology.LTE,
     HSPAP = 1 << RadioTechnology.HSPAP,
@@ -48,4 +55,8 @@
      * 5G NR. This is only use in 5G Standalone mode.
      */
     NR = 1 << RadioTechnology.NR,
+    /**
+     * 3GPP NB-IOT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
+     */
+    NB_IOT_NTN = 1 << RadioTechnology.NB_IOT_NTN,
 }
diff --git a/radio/aidl/android/hardware/radio/RadioError.aidl b/radio/aidl/android/hardware/radio/RadioError.aidl
index 6ce8f67..6a28893 100644
--- a/radio/aidl/android/hardware/radio/RadioError.aidl
+++ b/radio/aidl/android/hardware/radio/RadioError.aidl
@@ -61,12 +61,11 @@
      */
     SMS_SEND_FAIL_RETRY = 10,
     /**
-     * Fail to set the location where CDMA subscription shall be retrieved because of SIM or
-     * RUIM card absent
+     * SIM or RUIM card absent
      */
     SIM_ABSENT = 11,
     /**
-     * Fail to find CDMA subscription from specified location
+     * Failed to find subscription from specified location
      */
     SUBSCRIPTION_NOT_AVAILABLE = 12,
     /**
diff --git a/radio/aidl/android/hardware/radio/RadioTechnology.aidl b/radio/aidl/android/hardware/radio/RadioTechnology.aidl
index 7ae428b..843bfd0 100644
--- a/radio/aidl/android/hardware/radio/RadioTechnology.aidl
+++ b/radio/aidl/android/hardware/radio/RadioTechnology.aidl
@@ -25,15 +25,22 @@
     GPRS,
     EDGE,
     UMTS,
+    /** @deprecated Legacy CDMA is unsupported. */
     IS95A,
+    /** @deprecated Legacy CDMA is unsupported. */
     IS95B,
+    /** @deprecated Legacy CDMA is unsupported. */
     ONE_X_RTT,
+    /** @deprecated Legacy CDMA is unsupported. */
     EVDO_0,
+    /** @deprecated Legacy CDMA is unsupported. */
     EVDO_A,
     HSDPA,
     HSUPA,
     HSPA,
+    /** @deprecated Legacy CDMA is unsupported. */
     EVDO_B,
+    /** @deprecated Legacy CDMA is unsupported. */
     EHRPD,
     LTE,
     /**
@@ -55,4 +62,8 @@
      * 5G NR. This is only used in 5G Standalone mode.
      */
     NR,
+    /**
+     * 3GPP NB-IOT (Narrowband Internet of Things) over Non-Terrestrial-Networks technology.
+     */
+    NB_IOT_NTN,
 }
diff --git a/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl b/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl
index 4b5498c..a13c358 100644
--- a/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl
+++ b/radio/aidl/android/hardware/radio/RadioTechnologyFamily.aidl
@@ -27,6 +27,7 @@
     THREE_GPP,
     /**
      * 3GPP2 Technologies - CDMA
+     * @deprecated Legacy CDMA is unsupported.
      */
     THREE_GPP2,
 }
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
index 936315c..e819fe0 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfig.aidl
@@ -27,6 +27,7 @@
 
 import android.hardware.radio.config.IRadioConfigIndication;
 import android.hardware.radio.config.IRadioConfigResponse;
+import android.hardware.radio.config.SimType;
 import android.hardware.radio.config.SlotPortMapping;
 
 /** @hide */
@@ -208,4 +209,39 @@
      * This is available when android.hardware.telephony is defined.
      */
     void getSimultaneousCallingSupport(in int serial);
+
+    /**
+     * Get the sim type information.
+     *
+     * Response provides the current active sim type and supported sim types associated with each
+     * active physical slot ids.
+     *
+     * @param serial Serial number of request.
+     *
+     * Response callback is IRadioConfigResponse.getSimTypeInfoResponse()
+     *
+     * This is available when android.hardware.telephony.subscription is defined.
+     */
+    void getSimTypeInfo(in int serial);
+
+    /**
+     * Set the sim type associated with the physical slot id and activate if the sim type is
+     * currently inactive.
+     *
+     * Example: There are 2 active physical slot ids and 3 physical sims(2 pSIM and 1 eSIM). First
+     * physical slot id is always linked pSIM and 2nd physical slot id supports either pSIM/eSIM one
+     * at a time. In order to activate eSIM on 2nd physical slot id, caller should pass
+     * corresponding sim type.
+     *
+     * simTypes[0] = pSIM
+     * simTypes[1] = eSIM
+     *
+     * @param serial Serial number of request.
+     * @param simTypes SimType to be activated on each logical slot
+     *
+     * Response callback is IRadioConfigResponse.setSimTypeResponse()
+     *
+     * This is available when android.hardware.telephony.subscription is defined.
+     */
+    void setSimType(in int serial, in SimType[] simTypes);
 }
diff --git a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
index 8182cd1..d526c51 100644
--- a/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
+++ b/radio/aidl/android/hardware/radio/config/IRadioConfigResponse.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.radio.config.PhoneCapability;
 import android.hardware.radio.config.SimSlotStatus;
+import android.hardware.radio.config.SimTypeInfo;
 
 /**
  * Interface declaring response functions to solicited radio config requests.
@@ -152,4 +153,40 @@
      */
     void getSimultaneousCallingSupportResponse(
             in android.hardware.radio.RadioResponseInfo info, in int[] enabledLogicalSlots);
+
+    /**
+     * Response to the asynchronous {@link IRadioConfig#getSimTypeInfo} request.
+     *
+     * @param info Response info struct containing response type, serial number and error
+     * @param simTypeInfos Currently active and supported sim types associated with active
+     * physical slot ids.
+     *
+     * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony.subscription is not
+     *                                    defined
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:NO_MEMORY
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:MODEM_ERR
+     */
+    void getSimTypeInfoResponse(
+            in android.hardware.radio.RadioResponseInfo info, in SimTypeInfo[] simTypeInfo);
+
+    /**
+     * Response to the asynchronous {@link IRadioConfig#setSimType} request.
+     *
+     * @param info Response info struct containing response type, serial number and error
+     *
+     * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED when android.hardware.telephony.subscription is not
+     *                                    defined
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:NO_MEMORY
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:MODEM_ERR
+     */
+    void setSimTypeResponse(in android.hardware.radio.RadioResponseInfo info);
 }
diff --git a/radio/aidl/android/hardware/radio/config/SimType.aidl b/radio/aidl/android/hardware/radio/config/SimType.aidl
new file mode 100644
index 0000000..fc9915e
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/config/SimType.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.config;
+
+/** @hide */
+@VintfStability
+@Backing(type="int")
+@JavaDerive(toString=true)
+enum SimType {
+    /**
+     * Unknown
+     **/
+    UNKNOWN = 0,
+    /**
+     * Physical SIM (can be eUICC capable)
+     **/
+    PHYSICAL = 1 << 0,
+    /**
+     * Embedded SIM
+     **/
+    ESIM = 1 << 1,
+}
diff --git a/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl b/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl
new file mode 100644
index 0000000..0534626
--- /dev/null
+++ b/radio/aidl/android/hardware/radio/config/SimTypeInfo.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.radio.config;
+
+import android.hardware.radio.config.SimType;
+
+/** @hide */
+@VintfStability
+@JavaDerive(toString=true)
+parcelable SimTypeInfo {
+    /**
+     * Current SimType on the physical slot id.
+     **/
+    SimType currentSimType = SimType.UNKNOWN;
+    /**
+     * Bitmask of the sim types supported by the physical slot id. Physical slot can support more
+     * than one SimType.
+     * Example:
+     * if the physical slot id supports either pSIM/eSIM and currently pSIM is active,
+     * currentSimType will be SimType::PHYSICAL and supportedSimTypes will be
+     * SimType::PHYSICAL | SimType::ESIM.
+     **/
+    int supportedSimTypes;
+}
diff --git a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
index 6f043d9..592fde6 100644
--- a/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataCallFailCause.aidl
@@ -421,6 +421,7 @@
     TRAT_SWAP_FAILED = 0x800,
     /**
      * Device falls back from eHRPD to HRPD.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EHRPD_TO_HRPD_FALLBACK = 0x801,
     /**
@@ -521,26 +522,32 @@
     PDN_NON_IP_CALL_DISALLOWED = 0x817,
     /**
      * Device in CDMA locked state.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA_LOCK = 0x818,
     /**
      * Received an intercept order from the base station.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA_INTERCEPT = 0x819,
     /**
      * Receiving a reorder from the base station.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA_REORDER = 0x81A,
     /**
      * Receiving a release from the base station with a SO (Service Option) Reject reason.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA_RELEASE_DUE_TO_SO_REJECTION = 0x81B,
     /**
      * Receiving an incoming call from the base station.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA_INCOMING_CALL = 0x81C,
     /**
      * Received an alert stop from the base station due to incoming only.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA_ALERT_STOP = 0x81D,
     /**
@@ -570,6 +577,7 @@
     CONCURRENT_SERVICES_INCOMPATIBLE = 0x823,
     /**
      * Device does not have CDMA service.
+     * @deprecated Legacy CDMA is unsupported.
      */
     NO_CDMA_SERVICE = 0x824,
     /**
@@ -578,6 +586,7 @@
     RUIM_NOT_PRESENT = 0x825,
     /**
      * Receiving a retry order from the base station.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA_RETRY_ORDER = 0x826,
     /**
@@ -1062,30 +1071,37 @@
     UMTS_HANDOVER_TO_IWLAN = 0x897,
     /**
      * Received a connection deny due to general or network busy on EVDO network.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 0x898,
     /**
      * Received a connection deny due to billing or authentication failure on EVDO network.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 0x899,
     /**
      * HDR system has been changed due to redirection or the PRL was not preferred.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EVDO_HDR_CHANGED = 0x89A,
     /**
      * Device exited HDR due to redirection or the PRL was not preferred.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EVDO_HDR_EXITED = 0x89B,
     /**
      * Device does not have an HDR session.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EVDO_HDR_NO_SESSION = 0x89C,
     /**
      * It is ending an HDR call origination in favor of a GPS fix.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 0x89D,
     /**
      * Connection setup on the HDR system was time out.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 0x89E,
     /**
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
index 35a6a8d..cef8f5d 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaBroadcastSmsConfigInfo.aidl
@@ -23,15 +23,18 @@
     /**
      * Defines a broadcast message identifier whose value is 0x0000 - 0xFFFF as defined in
      * C.R1001G 9.3.1 and 9.3.2.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int serviceCategory;
     /**
      * Language code of broadcast message whose value is 0x00 - 0x07 as defined in C.R1001G 9.2.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int language;
     /**
      * Selected false means message types specified in serviceCategory are not accepted,
      * while true means accepted.
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean selected;
 }
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
index 2544ab5..ea5d8b2 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAck.aidl
@@ -20,10 +20,12 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CdmaSmsAck {
+    /** @deprecated Legacy CDMA is unsupported. */
     boolean errorClass;
     /**
      * SMS cause code as defined in N.S00005, 6.5.2.125.
      * Currently, only 35 (resource shortage) and 39 (other terminal problem) are reported.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int smsCauseCode;
 }
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
index a7ad233..11d953b 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsAddress.aidl
@@ -22,40 +22,60 @@
 parcelable CdmaSmsAddress {
     /**
      * DTMF digits
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int DIGIT_MODE_FOUR_BIT = 0;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int DIGIT_MODE_EIGHT_BIT = 1;
 
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_UNKNOWN = 0;
     /**
      * CCITT E.164 and E.163, including ISDN plan
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int NUMBER_PLAN_TELEPHONY = 1;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_2 = 2;
     /**
      * CCITT X.121
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int NUMBER_PLAN_DATA = 3;
     /**
      * CCITT F.69
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int NUMBER_PLAN_TELEX = 4;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_5 = 5;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_6 = 6;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_7 = 7;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_8 = 8;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_PRIVATE = 9;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_10 = 10;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_11 = 11;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_12 = 12;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_13 = 13;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_14 = 14;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_RESERVED_15 = 15;
 
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_UNKNOWN = 0;
     /**
      * INTERNATIONAL is used when number mode is not data network address. DATA_IP is used when the
      * number mode is data network address.
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int NUMBER_TYPE_INTERNATIONAL_OR_DATA_IP = 1;
     /**
@@ -63,25 +83,33 @@
      * when the number mode is data network address. For INTERNET_MAIL, in the address data
      * "digits", each byte contains an ASCII character. Examples are: "x@y.com,a@b.com"
      * Ref TIA/EIA-637A 3.4.3.3
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int NUMBER_TYPE_NATIONAL_OR_INTERNET_MAIL = 2;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_NETWORK = 3;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_SUBSCRIBER = 4;
     /**
      * GSM SMS: address value is GSM 7-bit chars
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int NUMBER_TYPE_ALPHANUMERIC = 5;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_ABBREVIATED = 6;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_RESERVED_7 = 7;
 
     /**
      * CdmaSmsDigitMode is of two types : 4 bit and 8 bit.
      * For 4-bit type, only "digits" field defined below in this struct is used.
      * Values are DIGIT_MODE_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int digitMode;
     /**
      * Used only when digitMode is 8-bit.
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean isNumberModeDataNetwork;
     /**
@@ -92,15 +120,18 @@
      * numberPlan = TELEPHONY
      * digits = ASCII digits, e.g. '1', '2', '3', '4', and '5'
      * Values are NUMBER_TYPE_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int numberType;
     /**
      * Used only when digitMode is 8-bit.
      * Values are NUMBER_PLAN_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int numberPlan;
     /**
      * Each byte in this array represents a 4 bit or 8-bit digit of address data.
+     * @deprecated Legacy CDMA is unsupported.
      */
     byte[] digits;
 }
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
index 51388b6..5332d82 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsMessage.aidl
@@ -23,13 +23,19 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CdmaSmsMessage {
+    /** @deprecated Legacy CDMA is unsupported. */
     int teleserviceId;
+    /** @deprecated Legacy CDMA is unsupported. */
     boolean isServicePresent;
+    /** @deprecated Legacy CDMA is unsupported. */
     int serviceCategory;
+    /** @deprecated Legacy CDMA is unsupported. */
     CdmaSmsAddress address;
+    /** @deprecated Legacy CDMA is unsupported. */
     CdmaSmsSubaddress subAddress;
     /**
      * 3GPP2 C.S0015-B, v2.0
+     * @deprecated Legacy CDMA is unsupported.
      */
     byte[] bearerData;
 }
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
index 8c494bb..132bbbb 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsSubaddress.aidl
@@ -23,23 +23,28 @@
 parcelable CdmaSmsSubaddress {
     /**
      * CCITT X.213 or ISO 8348 AD2
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int SUBADDRESS_TYPE_NSAP = 0;
     /**
      * e.g. X.25
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int SUBADDRESS_TYPE_USER_SPECIFIED = 1;
 
     /**
      * Values are SUBADDRESS_TYPE_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int subaddressType;
     /**
      * True means the last byte's lower 4 bits must be ignored
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean odd;
     /**
      * Each byte represents an 8-bit digit of subaddress data
+     * @deprecated Legacy CDMA is unsupported.
      */
     byte[] digits;
 }
diff --git a/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl b/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
index 897ec80..3047859 100644
--- a/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/CdmaSmsWriteArgs.aidl
@@ -22,15 +22,21 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CdmaSmsWriteArgs {
+    /** @deprecated Legacy CDMA is unsupported. */
     const int STATUS_REC_UNREAD = 0;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int STATUS_REC_READ = 1;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int STATUS_STO_UNSENT = 2;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int STATUS_STO_SENT = 3;
 
     /**
      * Status of message. See TS 27.005 3.1
      * Values are STATUS_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int status;
+    /** @deprecated Legacy CDMA is unsupported. */
     CdmaSmsMessage message;
 }
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
index 945453c..b60a225 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessaging.aidl
@@ -65,6 +65,8 @@
      * Response function is IRadioMessagingResponse.acknowledgeLastIncomingCdmaSmsResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void acknowledgeLastIncomingCdmaSms(in int serial, in CdmaSmsAck smsAck);
 
@@ -94,6 +96,8 @@
      * Response function is IRadioMessagingResponse.deleteSmsOnRuimResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void deleteSmsOnRuim(in int serial, in int index);
 
@@ -117,6 +121,8 @@
      * Response function is IRadioMessagingResponse.getCdmaBroadcastConfigResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void getCdmaBroadcastConfig(in int serial);
 
@@ -173,6 +179,8 @@
      * Response function is IRadioMessagingResponse.sendCdmaSmsResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void sendCdmaSms(in int serial, in CdmaSmsMessage sms);
 
@@ -186,6 +194,8 @@
      * Response function is IRadioMessagingResponse.sendCdmaSmsExpectMoreResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void sendCdmaSmsExpectMore(in int serial, in CdmaSmsMessage sms);
 
@@ -243,6 +253,8 @@
      * Response function is IRadioMessagingResponse.setCdmaBroadcastActivationResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void setCdmaBroadcastActivation(in int serial, in boolean activate);
 
@@ -255,6 +267,8 @@
      * Response function is IRadioMessagingResponse.setCdmaBroadcastConfigResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void setCdmaBroadcastConfig(in int serial, in CdmaBroadcastSmsConfigInfo[] configInfo);
 
@@ -315,6 +329,8 @@
      * Response function is IRadioMessagingResponse.writeSmsToRuimResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void writeSmsToRuim(in int serial, in CdmaSmsWriteArgs cdmaSms);
 
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
index a177c2c..4c6529b 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingIndication.aidl
@@ -32,6 +32,7 @@
      *
      * @param type Type of radio indication
      * @param msg Cdma Sms Message
+     * @deprecated Legacy CDMA is unsupported.
      */
     void cdmaNewSms(in RadioIndicationType type, in CdmaSmsMessage msg);
 
@@ -40,6 +41,7 @@
      * space is freed.
      *
      * @param type Type of radio indication
+     * @deprecated Legacy CDMA is unsupported.
      */
     void cdmaRuimSmsStorageFull(in RadioIndicationType type);
 
diff --git a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
index f0d7999..9b6e461 100644
--- a/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/IRadioMessagingResponse.aidl
@@ -62,6 +62,7 @@
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     * @deprecated Legacy CDMA is unsupported.
      */
     void acknowledgeLastIncomingCdmaSmsResponse(in RadioResponseInfo info);
 
@@ -108,6 +109,7 @@
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:OPERATION_NOT_ALLOWED
      *   RadioError:SIM_ABSENT
+     * @deprecated Legacy CDMA is unsupported.
      */
     void deleteSmsOnRuimResponse(in RadioResponseInfo info);
 
@@ -153,6 +155,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     * @deprecated Legacy CDMA is unsupported.
      */
     void getCdmaBroadcastConfigResponse(
             in RadioResponseInfo info, in CdmaBroadcastSmsConfigInfo[] configs);
@@ -257,6 +260,7 @@
      *   RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED
      *   RadioError:ACCESS_BARRED
      *   RadioError:BLOCKED_DUE_TO_CALL
+     * @deprecated Legacy CDMA is unsupported.
      */
     void sendCdmaSmsExpectMoreResponse(in RadioResponseInfo info, in SendSmsResult sms);
 
@@ -291,6 +295,7 @@
      *   RadioError:SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED
      *   RadioError:ACCESS_BARRED
      *   RadioError:BLOCKED_DUE_TO_CALL
+     * @deprecated Legacy CDMA is unsupported.
      */
     void sendCdmaSmsResponse(in RadioResponseInfo info, in SendSmsResult sms);
 
@@ -407,6 +412,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     * @deprecated Legacy CDMA is unsupported.
      */
     void setCdmaBroadcastActivationResponse(in RadioResponseInfo info);
 
@@ -427,6 +433,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
+     * @deprecated Legacy CDMA is unsupported.
      */
     void setCdmaBroadcastConfigResponse(in RadioResponseInfo info);
 
@@ -520,6 +527,7 @@
      *   RadioError:CANCELLED
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:SIM_ABSENT
+     * @deprecated Legacy CDMA is unsupported.
      */
     void writeSmsToRuimResponse(in RadioResponseInfo info, in int index);
 
diff --git a/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl b/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
index bbcd1cb..c205323 100644
--- a/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/ImsSmsMessage.aidl
@@ -37,6 +37,7 @@
     /**
      * Valid field if tech is 3GPP2 and size = 1 else must be empty. Only one of cdmaMessage and
      * gsmMessage must be of size 1 based on the RadioTechnologyFamily and the other must be size 0.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaSmsMessage[] cdmaMessage;
     /**
diff --git a/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl b/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
index ea93727..da41d84 100644
--- a/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
+++ b/radio/aidl/android/hardware/radio/messaging/SendSmsResult.aidl
@@ -23,15 +23,18 @@
     /**
      * TP-Message-Reference for GSM, and BearerData MessageId for CDMA.
      * See 3GPP2 C.S0015-B, v2.0, table 4.5-1
+     * @deprecated Legacy CDMA is unsupported.
      */
     int messageRef;
     /**
      * Ack PDU or empty string if n/a
+     * @deprecated Legacy CDMA is unsupported.
      */
     String ackPDU;
     /**
      * See 3GPP 27.005, 3.2.5 for GSM/UMTS, 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA.
      * -1 if unknown or not applicable.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int errorCode;
 }
diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
index bfca5a9..15a833e 100644
--- a/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
+++ b/radio/aidl/android/hardware/radio/modem/IRadioModem.aidl
@@ -139,15 +139,15 @@
     void nvReadItem(in int serial, in NvItem itemId);
 
     /**
-     * Reset the radio NV configuration to the factory state.
-     * This is used for device configuration by some CDMA operators.
+     * Reboots modem.
+     *
+     * This was historically used to reset NV configuration, but starting from Android U, NV APIs
+     * are deprecated.
      *
      * @param serial Serial number of request.
-     * @param resetType ResetNvType
+     * @param resetType Always ResetNvType.RELOAD.
      *
      * Response function is IRadioModemResponse.nvResetConfigResponse()
-     *
-     * Note: This will be deprecated in favor of a rebootModem API in Android U.
      */
     void nvResetConfig(in int serial, in ResetNvType resetType);
 
diff --git a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
index 6d2504c..498f228 100644
--- a/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
+++ b/radio/aidl/android/hardware/radio/modem/IRadioModemResponse.aidl
@@ -175,8 +175,6 @@
      * Valid errors returned:
      *   RadioError:NONE
      *   RadioError:RADIO_NOT_AVAILABLE
-     *
-     * Note: This will be deprecated in favor of a rebootModemResponse API in Android U.
      */
     void nvResetConfigResponse(in RadioResponseInfo info);
 
diff --git a/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
index b6be54d..95fa0d7 100644
--- a/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
+++ b/radio/aidl/android/hardware/radio/modem/ResetNvType.aidl
@@ -17,7 +17,6 @@
 package android.hardware.radio.modem;
 
 /**
- * Note: This will be deprecated along with nvResetConfig in Android U.
  * @hide
  */
 @VintfStability
@@ -26,15 +25,21 @@
 @SuppressWarnings(value={"redundant-name"})
 enum ResetNvType {
     /**
-     * Reload all NV items
+     * Reboot modem.
+     *
+     * Historically, this has been also reloading all NV items.
      */
     RELOAD,
     /**
      * Erase NV reset (SCRTN)
+     *
+     * @deprecated NV APIs are deprecated starting from Android U.
      */
     ERASE,
     /**
      * Factory reset (RTN)
+     *
+     * @deprecated NV APIs are deprecated starting from Android U.
      */
     FACTORY_RESET,
 }
diff --git a/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
index 9c48a8d..10421d6 100644
--- a/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/AccessTechnologySpecificInfo.aidl
@@ -25,6 +25,7 @@
 @JavaDerive(toString=true)
 union AccessTechnologySpecificInfo {
     boolean noinit;
+    /** @deprecated Legacy CDMA is unsupported. */
     Cdma2000RegistrationInfo cdmaInfo;
     EutranRegistrationInfo eutranInfo;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl b/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
index 91b8500..333a6c4 100644
--- a/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/Cdma2000RegistrationInfo.aidl
@@ -20,29 +20,36 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable Cdma2000RegistrationInfo {
+    /** @deprecated Legacy CDMA is unsupported. */
     const int PRL_INDICATOR_NOT_REGISTERED = -1;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int PRL_INDICATOR_NOT_IN_PRL = 0;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int PRL_INDICATOR_IN_PRL = 1;
     /**
      * Concurrent services support indicator. if registered on a CDMA system.
      * false - Concurrent services not supported,
      * true - Concurrent services supported
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean cssSupported;
     /**
      * TSB-58 Roaming Indicator if registered on a CDMA or EVDO system or -1 if not.
      * Valid values are 0-255.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int roamingIndicator;
     /**
      * Indicates whether the current system is in the PRL if registered on a CDMA or EVDO system
      * or -1 if not. 0=not in the PRL, 1=in the PRL.
      * Values are PRL_INDICATOR_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int systemIsInPrl;
     /**
      * Default Roaming Indicator from the PRL if registered on a CDMA or EVDO system or -1 if not.
      * Valid values are 0-255.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int defaultRoamingIndicator;
 }
diff --git a/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl b/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl
index 0bb7c04..4cad136 100644
--- a/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl
+++ b/radio/aidl/android/hardware/radio/network/CdmaRoamingType.aidl
@@ -21,7 +21,10 @@
 @Backing(type="int")
 @JavaDerive(toString=true)
 enum CdmaRoamingType {
+    /** @deprecated Legacy CDMA is unsupported. */
     HOME_NETWORK,
+    /** @deprecated Legacy CDMA is unsupported. */
     AFFILIATED_ROAM,
+    /** @deprecated Legacy CDMA is unsupported. */
     ANY_ROAM,
 }
diff --git a/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
index 0e241d3..214a512 100644
--- a/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/CdmaSignalStrength.aidl
@@ -23,11 +23,13 @@
     /**
      * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75,
      * then this response value will be 75. RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int dbm;
     /**
      * This value is the actual Ec/Io multiplied by -10. Example: If the actual Ec/Io is -12.5 dB,
      * then this response value will be 125. RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int ecio;
 }
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentity.aidl b/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
index 6142087..76a6675 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentity.aidl
@@ -34,6 +34,7 @@
     CellIdentityGsm gsm;
     CellIdentityWcdma wcdma;
     CellIdentityTdscdma tdscdma;
+    /** @deprecated Legacy CDMA is unsupported. */
     CellIdentityCdma cdma;
     CellIdentityLte lte;
     CellIdentityNr nr;
diff --git a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
index acf3db1..7f33d2d 100644
--- a/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellIdentityCdma.aidl
@@ -24,30 +24,36 @@
 parcelable CellIdentityCdma {
     /**
      * Network Id 0..65535, RadioConst:VALUE_UNAVAILABLE if unknown
+     * @deprecated Legacy CDMA is unsupported.
      */
     int networkId;
     /**
      * CDMA System Id 0..32767, RadioConst:VALUE_UNAVAILABLE if unknown
+     * @deprecated Legacy CDMA is unsupported.
      */
     int systemId;
     /**
      * Base Station Id 0..65535, RadioConst:VALUE_UNAVAILABLE if unknown
+     * @deprecated Legacy CDMA is unsupported.
      */
     int baseStationId;
     /**
      * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. It is represented in
      * units of 0.25 seconds and ranges from -2592000 to 2592000, both values inclusive
      * (corresponding to a range of -180 to +180 degrees). RadioConst:VALUE_UNAVAILABLE if unknown
+     * @deprecated Legacy CDMA is unsupported.
      */
     int longitude;
     /**
      * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. It is represented in
      * units of 0.25 seconds and ranges from -1296000 to 1296000, both values inclusive
      * (corresponding to a range of -90 to +90 degrees). RadioConst:VALUE_UNAVAILABLE if unknown
+     * @deprecated Legacy CDMA is unsupported.
      */
     int latitude;
     /**
      * OperatorInfo containing alphaLong and alphaShort
+     * @deprecated Legacy CDMA is unsupported.
      */
     OperatorInfo operatorNames;
 }
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl b/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
index 0a2bc54..0a0c0c0 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoCdma.aidl
@@ -24,7 +24,10 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CellInfoCdma {
+    /** @deprecated Legacy CDMA is unsupported. */
     CellIdentityCdma cellIdentityCdma;
+    /** @deprecated Legacy CDMA is unsupported. */
     CdmaSignalStrength signalStrengthCdma;
+    /** @deprecated Legacy CDMA is unsupported. */
     EvdoSignalStrength signalStrengthEvdo;
 }
diff --git a/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl b/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
index 10a4a5f..eebed9e 100644
--- a/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/CellInfoRatSpecificInfo.aidl
@@ -37,6 +37,7 @@
     CellInfoNr nr;
     /**
      * 3gpp2 CellInfo types;
+     * @deprecated Legacy CDMA is unsupported.
      */
     CellInfoCdma cdma;
 }
diff --git a/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
index ac6928e..e89eb88 100644
--- a/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/EvdoSignalStrength.aidl
@@ -23,16 +23,19 @@
     /**
      * This value is the actual RSSI value multiplied by -1. Example: If the actual RSSI is -75,
      * then this response value will be 75; RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int dbm;
     /**
      * This value is the actual Ec/Io multiplied by -10. Example: If the actual Ec/Io is -12.5 dB,
      * then this response value will be 125; RadioConst:VALUE_UNAVAILABLE means invalid/unreported.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int ecio;
     /**
      * Valid values are 0-8. 8 is the highest signal to noise ratio; RadioConst:VALUE_UNAVAILABLE
      * means invalid/unreported.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int signalNoiseRatio;
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 81d21e1..2509b6d 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -61,6 +61,8 @@
      * Response function is IRadioNetworkResponse.getAvailableBandModesResponse()
      *
      * This is available when android.hardware.telephony.radio.access is defined.
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void getAvailableBandModes(in int serial);
 
@@ -94,6 +96,8 @@
      * Response function is IRadioNetworkResponse.getCdmaRoamingPreferenceResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void getCdmaRoamingPreference(in int serial);
 
@@ -245,6 +249,8 @@
      * Response function is IRadioNetworkResponse.setBandModeResponse()
      *
      * This is available when android.hardware.telephony.radio.access is defined.
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void setBandMode(in int serial, in RadioBandMode mode);
 
@@ -272,6 +278,8 @@
      * Response function is IRadioNetworkResponse.setCdmaRoamingPreferenceResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void setCdmaRoamingPreference(in int serial, in CdmaRoamingType type);
 
@@ -334,7 +342,7 @@
 
     /**
      * Enables/disables network state change notifications due to changes in LAC and/or CID (for
-     * GSM) or BID/SID/NID/latitude/longitude (for CDMA). Basically +CREG=2 vs. +CREG=1 (TS 27.007).
+     * GSM). Basically +CREG=2 vs. +CREG=1 (TS 27.007).
      * The Radio implementation must default to "updates enabled" when the screen is on and
      * "updates disabled" when the screen is off.
      *
@@ -344,6 +352,8 @@
      * Response function is IRadioNetworkResponse.setLocationUpdatesResponse()
      *
      * This is available when android.hardware.telephony.radio.access is defined.
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void setLocationUpdates(in int serial, in boolean enable);
 
@@ -437,6 +447,8 @@
      * Response function is IRadioNetworkResponse.setSuppServiceNotificationsResponse()
      *
      * This is available when android.hardware.telephony.calling is defined.
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void setSuppServiceNotifications(in int serial, in boolean enable);
 
@@ -713,4 +725,60 @@
      * This is available when android.hardware.telephony.access is defined.
      */
     void isSecurityAlgorithmsUpdatedEnabled(in int serial);
+
+    /**
+     * Set the non-terrestrial PLMN with lower priority than terrestrial networks.
+     * MCC/MNC broadcast by the non-terrestrial networks may not be included in OPLMNwACT file on
+     * SIM profile. Acquisition of satellite based system is lower priority to terrestrial
+     * networks. UE shall make all attempts to acquire terrestrial service prior to camping on
+     * satellite LTE service.
+     *
+     * @param serial Serial number of request
+     * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use
+     *                this information to determine the relevant carrier.
+     * @param carrierPlmnArray Array of roaming PLMN used for connecting to satellite networks
+     *                         supported by user subscription.
+     * @param allSatellitePlmnArray allSatellitePlmnArray contains all the PLMNs present in
+     *                              carrierPlmnArray and also list of satellite PLMNs that are not
+     *                              supported by the carrier.
+     *                              Modem should use the allSatellitePlmnArray to identify satellite
+     *                              PLMNs that are not supported by the carrier and make sure not to
+     *                              attach to them.
+     *
+     * Response function is IRadioNetworkResponse.setSatellitePlmnResponse()
+     *
+     * This is available when android.hardware.telephony.radio.access is defined.
+     */
+    void setSatellitePlmn(in int serial, in int simSlot, in String[] carrierPlmnArray,
+            in String[] allSatellitePlmnArray);
+
+    /**
+     * Enable or disable satellite in the cellular modem associated with a carrier.
+     *
+     * Refer setSatellitePlmn for the details of satellite PLMN scanning process. Once modem is
+     * disabled, modem should not attach to any of the PLMNs present in allSatellitePlmnArray.
+     * If modem is enabled, modem should attach to only PLMNs present in carrierPlmnArray.
+     *
+     * @param serial Serial number of request
+     * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use
+     *                this information to determine the relevant carrier.
+     * @param satelliteEnabled {@code true} to enable satellite, {@code false} to disable satellite.
+     *
+     * Response function is IRadioNetworkResponse.setSatelliteEnabledForCarrier()
+     *
+     * This is available when android.hardware.telephony.radio.access is defined.
+     */
+    void setSatelliteEnabledForCarrier(in int serial, in int simSlot, boolean satelliteEnabled);
+
+    /**
+     * Check whether satellite is enabled in the cellular modem associated with a carrier.
+     *
+     * @param serial Serial number of request
+     * @param simSlot Indicates the SIM slot to which this API will be applied.
+     *
+     * Response function is IRadioNetworkResponse.isSatelliteEnabledForCarrier()
+     *
+     * This is available when android.hardware.telephony.radio.access is defined.
+     */
+    void isSatelliteEnabledForCarrier(in int serial, in int simSlot);
 }
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index 7b6fc6e..295061b 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -63,6 +63,7 @@
      *
      * @param type Type of radio indication
      * @param version PRL version after PRL changes
+     * @deprecated Legacy CDMA is unsupported.
      */
     void cdmaPrlChanged(in RadioIndicationType type, in int version);
 
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 5dcdb69..fd332fc 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -80,6 +80,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void getAvailableBandModesResponse(in RadioResponseInfo info, in RadioBandMode[] bandModes);
 
@@ -136,6 +138,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
+     * @deprecated Legacy CDMA is unsupported.
      */
     void getCdmaRoamingPreferenceResponse(in RadioResponseInfo info, in CdmaRoamingType type);
 
@@ -331,6 +334,8 @@
      *   RadioError:MODEM_ERR
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void setBandModeResponse(in RadioResponseInfo info);
 
@@ -372,6 +377,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
+     * @deprecated Legacy CDMA is unsupported.
      */
     void setCdmaRoamingPreferenceResponse(in RadioResponseInfo info);
 
@@ -435,6 +441,8 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void setLocationUpdatesResponse(in RadioResponseInfo info);
 
@@ -526,6 +534,8 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void setSuppServiceNotificationsResponse(in RadioResponseInfo info);
 
@@ -814,4 +824,53 @@
      */
     void isSecurityAlgorithmsUpdatedEnabledResponse(
             in RadioResponseInfo info, in boolean isEnabled);
+
+    /**
+     * Response of setSatellitePlmn.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_STATE
+     */
+    void setSatellitePlmnResponse(in RadioResponseInfo info);
+
+    /**
+     * Response of setSatelliteEnabledForCarrier.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     *
+     * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_STATE
+     */
+    void setSatelliteEnabledForCarrierResponse(in RadioResponseInfo info);
+
+    /**
+     * Response of isSatelliteEnabledForCarrier.
+     * This is an optional API.
+     *
+     * @param info Response info struct containing response type, serial no. and error.
+     * @param isEnabled Indicates whether satellite is enabled for carrier or not.
+     *
+     * Valid errors returned:
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:NONE
+     *   RadioError:RADIO_NOT_AVAILABLE
+     *   RadioError:INTERNAL_ERR
+     *   RadioError:REQUEST_NOT_SUPPORTED
+     *   RadioError:INVALID_STATE
+     */
+    void isSatelliteEnabledForCarrierResponse(in RadioResponseInfo info, boolean isEnabled);
 }
diff --git a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
index a7857ef..a4cb647 100644
--- a/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
+++ b/radio/aidl/android/hardware/radio/network/RegStateResult.aidl
@@ -27,7 +27,7 @@
 @JavaDerive(toString=true)
 parcelable RegStateResult {
     /**
-     * Registration state. If the RAT is indicated as a GERAN, UTRAN, or CDMA2000 technology, this
+     * Registration state. If the RAT is indicated as a GERAN or UTRAN technology, this
      * value reports registration in the Circuit-switched domain. If the RAT is indicated as an
      * EUTRAN, NGRAN, or another technology that does not support circuit-switched services, this
      * value reports registration in the Packet-switched domain.
@@ -57,7 +57,7 @@
      */
     String registeredPlmn;
     /**
-     * Access-technology-specific registration information, such as for CDMA2000.
+     * Access-technology-specific registration information.
      */
     AccessTechnologySpecificInfo accessTechnologySpecificInfo;
 }
diff --git a/radio/aidl/android/hardware/radio/network/SignalStrength.aidl b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
index fbe3be2..4e3bcf0 100644
--- a/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalStrength.aidl
@@ -36,11 +36,13 @@
     /**
      * If CDMA measurements are provided, this structure must contain valid measurements; otherwise
      * all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaSignalStrength cdma;
     /**
      * If EvDO measurements are provided, this structure must contain valid measurements; otherwise
      * all fields should be set to RadioConst:VALUE_UNAVAILABLE to mark them as invalid.
+     * @deprecated Legacy CDMA is unsupported.
      */
     EvdoSignalStrength evdo;
     /**
diff --git a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
index 3933889..1305a2c 100644
--- a/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
+++ b/radio/aidl/android/hardware/radio/network/SignalThresholdInfo.aidl
@@ -29,7 +29,7 @@
     /**
      * Received Signal Strength Indication.
      * Range: -113 dBm and -51 dBm
-     * Used RAN: GERAN, CDMA2000
+     * Used RAN: GERAN
      * Reference: 3GPP TS 27.007 section 8.5.
      */
     const int SIGNAL_MEASUREMENT_TYPE_RSSI = 1;
diff --git a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
index 90aa8e0..7321b36 100644
--- a/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CardStatus.aidl
@@ -54,7 +54,8 @@
      */
     int gsmUmtsSubscriptionAppIndex;
     /**
-     * Value < RadioConst:CARD_MAX_APPS, -1 if none
+     * Value ignored.
+     * @deprecated Legacy CDMA is unsupported.
      */
     int cdmaSubscriptionAppIndex;
     /**
diff --git a/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl b/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
index 4c6c1ef..2dbd6a8 100644
--- a/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
+++ b/radio/aidl/android/hardware/radio/sim/CdmaSubscriptionSource.aidl
@@ -21,6 +21,8 @@
 @Backing(type="int")
 @JavaDerive(toString=true)
 enum CdmaSubscriptionSource {
+    /** @deprecated Legacy CDMA is unsupported. */
     RUIM_SIM,
+    /** @deprecated Legacy CDMA is unsupported. */
     NV,
 }
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
index 1e010b9..16573f4 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSim.aidl
@@ -123,6 +123,8 @@
      * Response function is IRadioSimResponse.getCdmaSubscriptionResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void getCdmaSubscription(in int serial);
 
@@ -134,6 +136,8 @@
      * Response function is IRadioSimResponse.getCdmaSubscriptionSourceResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void getCdmaSubscriptionSource(in int serial);
 
@@ -255,7 +259,7 @@
 
     /**
      * Request APDU exchange on the basic channel. This command reflects TS 27.007
-     * "generic SIM access" operation (+CSIM). The modem must ensure proper function of GSM/CDMA,
+     * "generic SIM access" operation (+CSIM). The modem must ensure proper function of GSM,
      * and filter commands appropriately. It must filter channel management and SELECT by DF
      * name commands. "sessionId" field is always 0 (for aid="") and may be ignored.
      *
@@ -406,6 +410,8 @@
      * Response function is IRadioSimResponse.setCdmaSubscriptionSourceResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void setCdmaSubscriptionSource(in int serial, in CdmaSubscriptionSource cdmaSub);
 
@@ -479,6 +485,8 @@
      * Response function is IRadioSimResponse.setUiccSubscriptionResponse()
      *
      * This is available when android.hardware.telephony.subscription is defined.
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void setUiccSubscription(in int serial, in SelectUiccSub uiccSub);
 
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl
index fc6355d..d9735d3 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimIndication.aidl
@@ -41,6 +41,7 @@
      *
      * @param type Type of radio indication
      * @param cdmaSource New CdmaSubscriptionSource
+     * @deprecated Legacy CDMA is unsupported.
      */
     void cdmaSubscriptionSourceChanged(
             in RadioIndicationType type, in CdmaSubscriptionSource cdmaSource);
diff --git a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
index cf08bad..62fa674 100644
--- a/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
+++ b/radio/aidl/android/hardware/radio/sim/IRadioSimResponse.aidl
@@ -145,6 +145,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
+     * @deprecated Legacy CDMA is unsupported.
      */
     void getCdmaSubscriptionResponse(in RadioResponseInfo info, in String mdn, in String hSid,
             in String hNid, in String min, in String prl);
@@ -163,6 +164,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:SIM_ABSENT
+     * @deprecated Legacy CDMA is unsupported.
      */
     void getCdmaSubscriptionSourceResponse(
             in RadioResponseInfo info, in CdmaSubscriptionSource source);
@@ -381,6 +383,7 @@
      *   RadioError:INVALID_MODEM_STATE
      *   RadioError:SIM_ERR
      *   RadioError:INVALID_ARGUMENTS
+     *   RadioError:REQUEST_NOT_SUPPORTED
      */
     void requestIccSimAuthenticationResponse(in RadioResponseInfo info, in IccIoResult result);
 
@@ -483,6 +486,7 @@
      *   RadioError:NO_MEMORY
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     * @deprecated Legacy CDMA is unsupported.
      */
     void setCdmaSubscriptionSourceResponse(in RadioResponseInfo info);
 
@@ -540,6 +544,8 @@
      *   RadioError:INVALID_ARGUMENTS
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
+     *
+     * @deprecated Android Telephony framework doesn't use this.
      */
     void setUiccSubscriptionResponse(in RadioResponseInfo info);
 
diff --git a/radio/aidl/android/hardware/radio/voice/Call.aidl b/radio/aidl/android/hardware/radio/voice/Call.aidl
index 9990f28..5f62faa 100644
--- a/radio/aidl/android/hardware/radio/voice/Call.aidl
+++ b/radio/aidl/android/hardware/radio/voice/Call.aidl
@@ -77,6 +77,7 @@
     boolean isVoice;
     /**
      * true if CDMA voice privacy mode is active
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean isVoicePrivacy;
     /**
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl b/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
index d97b319..c77f3ec 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaCallWaiting.aidl
@@ -22,44 +22,64 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CdmaCallWaiting {
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_UNKNOWN = 0;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_ISDN = 1;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_DATA = 3;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_TELEX = 4;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_NATIONAL = 8;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PLAN_PRIVATE = 9;
 
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PRESENTATION_ALLOWED = 0;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PRESENTATION_RESTRICTED = 1;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_PRESENTATION_UNKNOWN = 2;
 
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_UNKNOWN = 0;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_INTERNATIONAL = 1;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_NATIONAL = 2;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_NETWORK_SPECIFIC = 3;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NUMBER_TYPE_SUBSCRIBER = 4;
 
     /**
      * Remote party number
+     * @deprecated Legacy CDMA is unsupported.
      */
     String number;
     /**
      * Values are NUMBER_PRESENTATION_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int numberPresentation;
     /**
      * Remote party name
+     * @deprecated Legacy CDMA is unsupported.
      */
     String name;
+    /** @deprecated Legacy CDMA is unsupported. */
     CdmaSignalInfoRecord signalInfoRecord;
     /**
      * Required to support International Call Waiting
      * Values are NUMBER_TYPE_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int numberType;
     /**
      * Required to support International Call Waiting
      * Values are NUMBER_PLAN_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int numberPlan;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
index 90b2715..bba6e4d 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaDisplayInfoRecord.aidl
@@ -28,9 +28,11 @@
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
 parcelable CdmaDisplayInfoRecord {
+    /** @deprecated Legacy CDMA is unsupported. */
     const int CDMA_ALPHA_INFO_BUFFER_LENGTH = 64;
     /**
      * Max length = CDMA_ALPHA_INFO_BUFFER_LENGTH
+     * @deprecated Legacy CDMA is unsupported.
      */
     String alphaBuf;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
index 19903c6..7232eba 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaInformationRecord.aidl
@@ -32,54 +32,74 @@
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
 parcelable CdmaInformationRecord {
+    /** @deprecated Legacy CDMA is unsupported. */
     const int CDMA_MAX_NUMBER_OF_INFO_RECS = 10;
     /**
      * Names of the CDMA info records (C.S0005 section 3.7.5)
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int NAME_DISPLAY = 0;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_CALLED_PARTY_NUMBER = 1;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_CALLING_PARTY_NUMBER = 2;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_CONNECTED_NUMBER = 3;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_SIGNAL = 4;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_REDIRECTING_NUMBER = 5;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_LINE_CONTROL = 6;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_EXTENDED_DISPLAY = 7;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_T53_CLIR = 8;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_T53_RELEASE = 9;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int NAME_T53_AUDIO_CONTROL = 10;
 
     /**
      * Based on CdmaInfoRecName, only one of the below vectors must have size = 1.
      * All other vectors must have size 0.
      * Values are NAME_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int name;
     /**
      * Display and extended display info rec
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaDisplayInfoRecord[] display;
     /**
      * Called party number, calling party number, connected number info rec
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaNumberInfoRecord[] number;
     /**
      * Signal info rec
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaSignalInfoRecord[] signal;
     /**
      * Redirecting number info rec
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaRedirectingNumberInfoRecord[] redir;
     /**
      * Line control info rec
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaLineControlInfoRecord[] lineCtrl;
     /**
      * T53 CLIR info rec
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaT53ClirInfoRecord[] clir;
     /**
      * T53 Audio Control info rec
+     * @deprecated Legacy CDMA is unsupported.
      */
     CdmaT53AudioControlInfoRecord[] audioCtrl;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
index 15c22a0..9cf0103 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaLineControlInfoRecord.aidl
@@ -23,8 +23,12 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CdmaLineControlInfoRecord {
+    /** @deprecated Legacy CDMA is unsupported. */
     byte lineCtrlPolarityIncluded;
+    /** @deprecated Legacy CDMA is unsupported. */
     byte lineCtrlToggle;
+    /** @deprecated Legacy CDMA is unsupported. */
     byte lineCtrlReverse;
+    /** @deprecated Legacy CDMA is unsupported. */
     byte lineCtrlPowerDenial;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
index 3a00cae..bc00acb 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaNumberInfoRecord.aidl
@@ -26,13 +26,19 @@
 @JavaDerive(toString=true)
 @SuppressWarnings(value={"redundant-name"})
 parcelable CdmaNumberInfoRecord {
+    /** @deprecated Legacy CDMA is unsupported. */
     const int CDMA_NUMBER_INFO_BUFFER_LENGTH = 81;
     /**
      * Max length = CDMA_NUMBER_INFO_BUFFER_LENGTH
+     * @deprecated Legacy CDMA is unsupported.
      */
     String number;
+    /** @deprecated Legacy CDMA is unsupported. */
     byte numberType;
+    /** @deprecated Legacy CDMA is unsupported. */
     byte numberPlan;
+    /** @deprecated Legacy CDMA is unsupported. */
     byte pi;
+    /** @deprecated Legacy CDMA is unsupported. */
     byte si;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl b/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
index b6444ab..1f003a8 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaOtaProvisionStatus.aidl
@@ -21,16 +21,28 @@
 @Backing(type="int")
 @JavaDerive(toString=true)
 enum CdmaOtaProvisionStatus {
+    /** @deprecated Legacy CDMA is unsupported. */
     SPL_UNLOCKED,
+    /** @deprecated Legacy CDMA is unsupported. */
     SPC_RETRIES_EXCEEDED,
+    /** @deprecated Legacy CDMA is unsupported. */
     A_KEY_EXCHANGED,
+    /** @deprecated Legacy CDMA is unsupported. */
     SSD_UPDATED,
+    /** @deprecated Legacy CDMA is unsupported. */
     NAM_DOWNLOADED,
+    /** @deprecated Legacy CDMA is unsupported. */
     MDN_DOWNLOADED,
+    /** @deprecated Legacy CDMA is unsupported. */
     IMSI_DOWNLOADED,
+    /** @deprecated Legacy CDMA is unsupported. */
     PRL_DOWNLOADED,
+    /** @deprecated Legacy CDMA is unsupported. */
     COMMITTED,
+    /** @deprecated Legacy CDMA is unsupported. */
     OTAPA_STARTED,
+    /** @deprecated Legacy CDMA is unsupported. */
     OTAPA_STOPPED,
+    /** @deprecated Legacy CDMA is unsupported. */
     OTAPA_ABORTED,
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
index cb30da8..514b8e1 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaRedirectingNumberInfoRecord.aidl
@@ -25,19 +25,28 @@
 parcelable CdmaRedirectingNumberInfoRecord {
     /**
      * Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11
+     * @deprecated Legacy CDMA is unsupported.
      */
     const int REDIRECTING_REASON_UNKNOWN = 0;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int REDIRECTING_REASON_CALL_FORWARDING_NO_REPLY = 2;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int REDIRECTING_REASON_CALLED_DTE_OUT_OF_ORDER = 9;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int REDIRECTING_REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int REDIRECTING_REASON_CALL_FORWARDING_UNCONDITIONAL = 15;
+    /** @deprecated Legacy CDMA is unsupported. */
     const int REDIRECTING_REASON_RESERVED = 16;
 
+    /** @deprecated Legacy CDMA is unsupported. */
     CdmaNumberInfoRecord redirectingNumber;
     /**
      * Set to UNKNOWN if not included.
      * Values are REDIRECTING_REASON_
+     * @deprecated Legacy CDMA is unsupported.
      */
     int redirectingReason;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
index 4302ba4..2ada10b 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaSignalInfoRecord.aidl
@@ -25,18 +25,22 @@
 parcelable CdmaSignalInfoRecord {
     /**
      * True if signal information record is present
+     * @deprecated Legacy CDMA is unsupported.
      */
     boolean isPresent;
     /**
      * Defined in 3.7.5.5-1
+     * @deprecated Legacy CDMA is unsupported.
      */
     byte signalType;
     /**
      * Defined in 3.7.5.5-2
+     * @deprecated Legacy CDMA is unsupported.
      */
     byte alertPitch;
     /**
      * Defined in 3.7.5.5-3, 3.7.5.5-4 or 3.7.5.5-5
+     * @deprecated Legacy CDMA is unsupported.
      */
     byte signal;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
index 44ac2b4..68b19b8 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaT53AudioControlInfoRecord.aidl
@@ -23,6 +23,8 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CdmaT53AudioControlInfoRecord {
+    /** @deprecated Legacy CDMA is unsupported. */
     byte upLink;
+    /** @deprecated Legacy CDMA is unsupported. */
     byte downLink;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl b/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
index 564d761..6a1b992 100644
--- a/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
+++ b/radio/aidl/android/hardware/radio/voice/CdmaT53ClirInfoRecord.aidl
@@ -23,5 +23,6 @@
 @VintfStability
 @JavaDerive(toString=true)
 parcelable CdmaT53ClirInfoRecord {
+    /** @deprecated Legacy CDMA is unsupported. */
     byte cause;
 }
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
index 0c2b51d..74b1d5f 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoice.aidl
@@ -369,6 +369,8 @@
      * Response function is IRadioVoiceResponse.sendCdmaFeatureCodeResponse()
      *
      * This is available when android.hardware.telephony.cdma is defined.
+     *
+     * @deprecated Legacy CDMA is unsupported.
      */
     void sendCdmaFeatureCode(in int serial, in String featureCode);
 
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
index 9de6364..f8bd999 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceIndication.aidl
@@ -42,8 +42,8 @@
      * value of 3000 (3 seconds) if absent.
      *
      * @param type Type of radio indication
-     * @param isGsm true for GSM & false for CDMA
-     * @param record Cdma Signal Information
+     * @param isGsm Always true (Legacy CDMA is unsupported)
+     * @param record Always empty (Legacy CDMA is unsupported)
      */
     void callRing(in RadioIndicationType type, in boolean isGsm, in CdmaSignalInfoRecord record);
 
@@ -62,6 +62,7 @@
      *
      * @param type Type of radio indication
      * @param callWaitingRecord Cdma CallWaiting information
+     * @deprecated Legacy CDMA is unsupported.
      */
     void cdmaCallWaiting(in RadioIndicationType type, in CdmaCallWaiting callWaitingRecord);
 
@@ -71,6 +72,7 @@
      * @param type Type of radio indication
      * @param records New CDMA information records.
      *        Max length is RadioConst:CDMA_MAX_NUMBER_OF_INFO_RECS
+     * @deprecated Legacy CDMA is unsupported.
      */
     void cdmaInfoRec(in RadioIndicationType type, in CdmaInformationRecord[] records);
 
@@ -79,6 +81,7 @@
      *
      * @param type Type of radio indication
      * @param status Cdma OTA provision status
+     * @deprecated Legacy CDMA is unsupported.
      */
     void cdmaOtaProvisionStatus(in RadioIndicationType type, in CdmaOtaProvisionStatus status);
 
diff --git a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
index a904eaa..cf36ef9 100644
--- a/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
+++ b/radio/aidl/android/hardware/radio/voice/IRadioVoiceResponse.aidl
@@ -564,6 +564,7 @@
      *   RadioError:NO_RESOURCES
      *   RadioError:CANCELLED
      *   RadioError:OPERATION_NOT_ALLOWED
+     * @deprecated Legacy CDMA is unsupported.
      */
     void sendCdmaFeatureCodeResponse(in RadioResponseInfo info);
 
diff --git a/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl b/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl
index 7737e94..f6f4585 100644
--- a/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl
+++ b/radio/aidl/android/hardware/radio/voice/LastCallFailCause.aidl
@@ -142,18 +142,28 @@
      * Explicit network detach
      */
     NETWORK_DETACH = 261,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_DROP = 1001,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_INTERCEPT = 1002,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_REORDER = 1003,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_SO_REJECT = 1004,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_RETRY_ORDER = 1005,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_ACCESS_FAILURE = 1006,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_PREEMPTED = 1007,
     /**
      * For non-emergency number dialed during emergency callback mode
+     * @deprecated Legacy CDMA is unsupported.
      */
     CDMA_NOT_EMERGENCY = 1008,
+    /** @deprecated Legacy CDMA is unsupported. */
     CDMA_ACCESS_BLOCKED = 1009,
     /**
      * OEM specific error codes. Used to distinguish error from
diff --git a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
index 837c626..3834ecc 100644
--- a/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
+++ b/radio/aidl/compat/libradiocompat/config/RadioConfig.cpp
@@ -109,4 +109,19 @@
     return ok();
 }
 
+ScopedAStatus RadioConfig::getSimTypeInfo(int32_t serial) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " getSimTypeInfo is unsupported by HIDL HALs";
+    respond()->getSimTypeInfoResponse(notSupported(serial), {});
+    return ok();
+}
+
+ScopedAStatus RadioConfig::setSimType(
+        int32_t serial, const std::vector<aidl::SimType>& /*simTypes*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setSimType is unsupported by HIDL HALs";
+    respond()->setSimTypeResponse(notSupported(serial));
+    return ok();
+}
+
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
index 17d5985..a1e48dc 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioConfig.h
@@ -55,7 +55,11 @@
             int32_t serial,
             const std::vector<aidl::android::hardware::radio::config::SlotPortMapping>& slotMap)
             override;
-
+    ::ndk::ScopedAStatus getSimTypeInfo(int32_t serial) override;
+    ::ndk::ScopedAStatus setSimType(
+            int32_t serial,
+            const std::vector<aidl::android::hardware::radio::config::SimType>& simTypes)
+            override;
   protected:
     std::shared_ptr<::aidl::android::hardware::radio::config::IRadioConfigResponse> respond();
 
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
index 56724ae..c9a3270 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -114,6 +114,13 @@
     ::ndk::ScopedAStatus setSecurityAlgorithmsUpdatedEnabled(int32_t serial, bool enabled) override;
     ::ndk::ScopedAStatus isSecurityAlgorithmsUpdatedEnabled(int32_t serial) override;
 
+    ::ndk::ScopedAStatus setSatellitePlmn(
+            int32_t serial, int32_t simSlot, const std::vector<std::string>& carrierPlmnArray,
+            const std::vector<std::string>& allSatellitePlmnArray) override;
+    ::ndk::ScopedAStatus setSatelliteEnabledForCarrier(int32_t serial, int32_t simSlot,
+                                                       bool satelliteEnabled) override;
+    ::ndk::ScopedAStatus isSatelliteEnabledForCarrier(int32_t serial, int32_t simSlot) override;
+
   protected:
     std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> respond();
 
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index 1e43789..b5aee5c 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -402,4 +402,28 @@
     return ok();
 }
 
+ScopedAStatus RadioNetwork::setSatellitePlmn(
+        int32_t serial, int32_t /*simSlot*/, const std::vector<std::string>& /*carrierPlmnArray*/,
+        const std::vector<std::string>& /*allSatellitePlmnArray*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setSatellitePlmn is unsupported by HIDL HALs";
+    respond()->setSatellitePlmnResponse(notSupported(serial));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::setSatelliteEnabledForCarrier(int32_t serial, int32_t /*simSlot*/,
+                                                          bool /*enable*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " setSatelliteEnabledForCarrier is unsupported by HIDL HALs";
+    respond()->setSatelliteEnabledForCarrierResponse(notSupported(serial));
+    return ok();
+}
+
+ScopedAStatus RadioNetwork::isSatelliteEnabledForCarrier(int32_t serial, int32_t /*simSlot*/) {
+    LOG_CALL << serial;
+    LOG(ERROR) << " isSatelliteEnabledForCarrier is unsupported by HIDL HALs";
+    respond()->isSatelliteEnabledForCarrierResponse(notSupported(serial), false);
+    return ok();
+}
+
 }  // namespace android::hardware::radio::compat
diff --git a/radio/aidl/vts/radio_config_response.cpp b/radio/aidl/vts/radio_config_response.cpp
index c532440..49439fa 100644
--- a/radio/aidl/vts/radio_config_response.cpp
+++ b/radio/aidl/vts/radio_config_response.cpp
@@ -75,3 +75,17 @@
     parent_config.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus RadioConfigResponse::getSimTypeInfoResponse(const RadioResponseInfo& info,
+        const std::vector<SimTypeInfo>& /* simTypeInfo */) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioConfigResponse::setSimTypeResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_config.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
diff --git a/radio/aidl/vts/radio_config_utils.h b/radio/aidl/vts/radio_config_utils.h
index 84c74fc..cdcc1bc 100644
--- a/radio/aidl/vts/radio_config_utils.h
+++ b/radio/aidl/vts/radio_config_utils.h
@@ -62,6 +62,11 @@
 
     virtual ndk::ScopedAStatus getHalDeviceCapabilitiesResponse(
             const RadioResponseInfo& info, bool modemReducedFeatureSet1) override;
+
+    virtual ndk::ScopedAStatus getSimTypeInfoResponse(
+            const RadioResponseInfo& info, const std::vector<SimTypeInfo>& simTypeInfo) override;
+
+    virtual ndk::ScopedAStatus setSimTypeResponse(const RadioResponseInfo& info) override;
 };
 
 /* Callback class for radio config indication */
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
index 4d452d0..df59687 100644
--- a/radio/aidl/vts/radio_network_response.cpp
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -350,3 +350,24 @@
     parent_network.notify(info.serial);
     return ndk::ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus RadioNetworkResponse::setSatellitePlmnResponse(const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSatelliteEnabledForCarrierResponse(
+        const RadioResponseInfo& info) {
+    rspInfo = info;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::isSatelliteEnabledForCarrierResponse(
+        const RadioResponseInfo& info, bool enabled) {
+    rspInfo = info;
+    this->isSatelliteEnabledForCarrier = enabled;
+    parent_network.notify(info.serial);
+    return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 914cad0..1778c3f 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -609,6 +609,11 @@
         }
     }
 
+    if (!deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        GTEST_SKIP() << "Skipping setSignalStrengthReportingCriteria_Cdma2000 "
+                        "due to undefined FEATURE_TELEPHONY_CDMA";
+    }
+
     serial = GetRandomSerialNumber();
 
     SignalThresholdInfo signalThresholdInfo;
@@ -824,9 +829,12 @@
     signalThresholdInfoNgran.isEnabled = true;
     signalThresholdInfoNgran.ran = AccessNetwork::NGRAN;
 
-    const static std::vector<SignalThresholdInfo> candidateSignalThresholdInfos = {
+    std::vector<SignalThresholdInfo> candidateSignalThresholdInfos = {
             signalThresholdInfoGeran, signalThresholdInfoUtran, signalThresholdInfoEutran,
-            signalThresholdInfoCdma2000, signalThresholdInfoNgran};
+            signalThresholdInfoNgran};
+    if (deviceSupportsFeature(FEATURE_TELEPHONY_CDMA)) {
+        candidateSignalThresholdInfos.push_back(signalThresholdInfoCdma2000);
+    }
 
     std::vector<SignalThresholdInfo> supportedSignalThresholdInfos;
     for (size_t i = 0; i < candidateSignalThresholdInfos.size(); i++) {
@@ -2606,3 +2614,82 @@
                                  {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
                                   RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
 }
+
+/*
+ * Test IRadioNetwork.setSatellitePlmn for the response returned.
+ */
+TEST_P(RadioNetworkTest, setSatellitePlmn) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 4) {
+        ALOGI("Skipped the test since"
+              " setSatellitePlmn is not supported on version < 4");
+        GTEST_SKIP();
+    }
+
+    serial = GetRandomSerialNumber();
+    radio_network->setSatellitePlmn(serial, 0, {"123456"}, {"123456, 3456789"});
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setSatelliteEnabledForCarrier for the response returned.
+ */
+TEST_P(RadioNetworkTest, setSatelliteEnabledForCarrier) {
+    int32_t aidl_version;
+    ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+    ASSERT_OK(aidl_status);
+    if (aidl_version < 4) {
+        ALOGI("Skipped the test since"
+              " setSatelliteEnabledForCarrier is not supported on version < 4");
+        GTEST_SKIP();
+    }
+
+    // Get current value
+    serial = GetRandomSerialNumber();
+    radio_network->isSatelliteEnabledForCarrier(serial, 0);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    bool originalSatelliteEnabledSetting = radioRsp_network->isSatelliteEnabledForCarrier;
+
+    // We want to test flipping the value, so we are going to set it to the opposite of what
+    // the existing setting is. The test for isSatelliteEnabledForCarrier should check
+    // for the right default value.
+    bool valueToSet = !originalSatelliteEnabledSetting;
+    serial = GetRandomSerialNumber();
+    radio_network->setSatelliteEnabledForCarrier(serial, 0, valueToSet);
+    EXPECT_EQ(std::cv_status::no_timeout, wait());
+    EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+    EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+    ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                 {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                  RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+
+    if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+        // Assert the value has changed
+        serial = GetRandomSerialNumber();
+        ndk::ScopedAStatus res = radio_network->isSatelliteEnabledForCarrier(serial, 0);
+
+        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);
+        ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+                                     {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+                                      RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+        EXPECT_EQ(valueToSet, radioRsp_network->isSatelliteEnabledForCarrier);
+
+        // Reset original state
+        radio_network->setSatelliteEnabledForCarrier(serial, 0, originalSatelliteEnabledSetting);
+        EXPECT_EQ(std::cv_status::no_timeout, wait());
+        EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+        EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+    }
+}
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index ad530eb..17c0896 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -48,6 +48,7 @@
     std::vector<RadioAccessSpecifier> specifiers;
     bool isCellularIdentifierTransparencyEnabled = false;
     bool isSecurityAlgorithmsUpdatedEnabled = false;
+    bool isSatelliteEnabledForCarrier = false;
 
     virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
 
@@ -183,6 +184,14 @@
 
     virtual ndk::ScopedAStatus setSecurityAlgorithmsUpdatedEnabledResponse(
             const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSatellitePlmnResponse(const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus setSatelliteEnabledForCarrierResponse(
+            const RadioResponseInfo& info) override;
+
+    virtual ndk::ScopedAStatus isSatelliteEnabledForCarrierResponse(const RadioResponseInfo& info,
+                                                                    bool isEnabled) override;
 };
 
 /* Callback class for radio network indication */
diff --git a/security/see/hdcp/README.md b/security/see/hdcp/README.md
new file mode 100644
index 0000000..76b8670
--- /dev/null
+++ b/security/see/hdcp/README.md
@@ -0,0 +1,65 @@
+# IHDCPAuthControl as a Trusted HAL service
+
+IHDCPAuthControl is expected to be a service implemented in a TEE.
+We provide a default reference implementation and its integration in Trusty
+as an example.
+
+The VTS test for a Trusted HAL service ought to run in the VM.
+We provide an integration of the VTS test in a Trusty VM,
+and later in a Microdroid VM (b/380632474).
+
+This interface shall not be exposed to the host and thus shall be part of
+the list of excluded interfaces from
+[compatibility_matrices/exclude/fcm_exclude.cpp](../../../compatibility_matrices/exclude/fcm_exclude.cpp)
+
+## 1. Mock Implementation
+
+The mock implementation under default/src/lib.rs is expected to be integrated in a
+TEE. For AOSP testing we offer two virtual device testing options:
+
+- Cuttlefish AVD, where the reference implementation is integrated in an AVF VM, emulating a TEE.
+- Trusty QEMU AVD, where the reference implementation is integrated in a Trusty TEE image (executed in secure world)
+
+### 1.1. Cuttlefish: Integrate in an AVF HAL pVM (Trusty)
+
+In Cuttlefish, we emulate a TEE with an AVF Trusty pVM.
+The VM2TZ IPC is emulated with a vsock port forward utility (b/379582767).
+
+Until vsock port forwarding is supported, the trusty_test_vm is used temporarily.
+(VTS tests and HAL implementation will be in same pVM).
+
+TODO: complete when trusty_hal_vm is created
+
+In order to add the mock HdcpAuthControlService to the trusty_test_vm, make sure
+that `hardware/interfaces/security/see/hdcp/default` is added to the
+trusty_test_vm makefile, by adding it to
+[trusty/device/x86/generic-x86_64/project/generic-x86_64-inc.mk](../../../../../trusty/device/x86/generic-x86_64/project/generic-x86_64-inc.mk)
+
+### 1.2. Trusty QEMU AVD: Integrate as a TA in Trusty TEE
+
+In order to add the mock HdcpAuthControlService to the Trusty TEE, make sure
+that `hardware/interfaces/security/see/hdcp/default` is added to
+[trusty/device/arm/generic-arm64/project/generic-arm-inc.mk](../../../../../trusty/device/arm/generic-arm64/project/generic-arm-inc.mk)
+
+
+## 2. VTS Tests
+
+IHdcpAuthControl service is expected to only be exposed to AVF pVM.
+
+The VTS tests shall verify:
+
+- IHdcpAuthControl cannot be accessed from the Android Host:
+
+   see [aidl/vts/src/host_test.rs](aidl/vts/host_test.rs)
+
+- IHdcpAuthControl can be accessed from an AVF pVM:
+
+   see [aidl/vts/src/vm_test.rs](aidl/vts/src/vm_test.rs)
+   see [aidl/vts/AndroidTest.xml](aidl/vts/AndroidTest.xml)
+
+
+To integrate the VTS test in the trusty_test_vm:
+
+1.
+1. add the test to [hardware/interfaces/security/see/usertests-rust-inc.mk](../usertests-rust-inc.mk)
+
diff --git a/security/see/hdcp/aidl/Android.bp b/security/see/hdcp/aidl/Android.bp
new file mode 100644
index 0000000..ad1db37
--- /dev/null
+++ b/security/see/hdcp/aidl/Android.bp
@@ -0,0 +1,57 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_team: "trendy_team_trusty",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+    name: "android.hardware.security.see.hdcp",
+    vendor_available: true,
+    srcs: ["android/hardware/security/see/hdcp/*.aidl"],
+    imports: [
+        "android.hardware.drm.common-V1",
+    ],
+    stability: "vintf",
+    frozen: false,
+    backend: {
+        java: {
+            enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+        ndk: {
+            min_sdk_version: "34",
+        },
+        rust: {
+            enabled: true,
+            gen_mockall: true,
+            additional_rustlibs: [
+                "libmockall",
+            ],
+        },
+    },
+}
+
+// A rust_defaults that includes the latest hdcp AIDL library.
+// Modules that depend on hdcp directly can include this rust_defaults to avoid
+// managing dependency versions explicitly.
+rust_defaults {
+    name: "hdcp_use_latest_hal_aidl_rust",
+    rustlibs: [
+        "android.hardware.security.see.hdcp-V1-rust",
+    ],
+}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/security/see/hdcp/aidl/aidl_api/android.hardware.security.see.hdcp/current/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
similarity index 63%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to security/see/hdcp/aidl/aidl_api/android.hardware.security.see.hdcp/current/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
index a5eda52..b73d554 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/security/see/hdcp/aidl/aidl_api/android.hardware.security.see.hdcp/current/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,28 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.security.see.hdcp;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface IHdcpAuthControl {
+  android.hardware.drm.HdcpLevels getHdcpLevels();
+  void trySetHdcpLevel(in android.hardware.drm.HdcpLevel level);
+  android.hardware.security.see.hdcp.IHdcpAuthControl.PendingHdcpLevelResult getPendingHdcpLevel();
+  parcelable HalErrorCode {
+    const int NO_ERROR = 0;
+    const int GENERIC_ERROR = (-1) /* -1 */;
+    const int BAD_STATE = (-2) /* -2 */;
+    const int UNSUPPORTED = (-3) /* -3 */;
+    const int SERIALIZATION_ERROR = (-4) /* -4 */;
+    const int ALLOCATION_ERROR = (-5) /* -5 */;
+    const int BAD_PARAMETER = (-7) /* -7 */;
+    const int UNAUTHORIZED = (-8) /* -8 */;
+  }
+  parcelable PendingHdcpLevelResult {
+    android.hardware.security.see.hdcp.IHdcpAuthControl.PendingHdcpLevelResult.Status status;
+    android.hardware.drm.HdcpLevel level;
+    enum Status {
+      NONE,
+      PENDING,
+    }
+  }
 }
diff --git a/security/see/hdcp/aidl/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl b/security/see/hdcp/aidl/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
new file mode 100644
index 0000000..b9a1fe5
--- /dev/null
+++ b/security/see/hdcp/aidl/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.security.see.hdcp;
+
+/**
+ * IHdcpAuthControl is used by the OEMCrypto Trusted Application to interact
+ * with a HDCP Encryption Trusted Application in order to control the
+ * HDCP Authentication Levels.
+ */
+@VintfStability
+interface IHdcpAuthControl {
+    /*
+     * Service error codes. Will be returned as service specific errors.
+     */
+    parcelable HalErrorCode {
+        /* Success */
+        const int NO_ERROR = 0;
+
+        /* Generic error */
+        const int GENERIC_ERROR = -1;
+
+        /* Desired operation cannot be performed because of the server current state */
+        const int BAD_STATE = -2;
+
+        /* Operation or parameters are not supported by the server */
+        const int UNSUPPORTED = -3;
+
+        /* Error encountered when parsing parameters */
+        const int SERIALIZATION_ERROR = -4;
+
+        /* Server ran out of memory when performing operation */
+        const int ALLOCATION_ERROR = -5;
+
+        /* Bad parameter supplied for the desired operation */
+        const int BAD_PARAMETER = -7;
+
+        /* Caller is not authorized to make this call */
+        const int UNAUTHORIZED = -8;
+    }
+    /**
+     * Result returned from the getPendingHdcpLevelResult API.
+     */
+    parcelable PendingHdcpLevelResult {
+        enum Status {
+            /**
+             * No pending HdcpLevel request
+             */
+            NONE,
+            /**
+             * a HdcpLevel request is pending, its level is provided in the
+             * |level| attribute
+             */
+            PENDING,
+        }
+        Status status;
+        android.hardware.drm.HdcpLevel level;
+    }
+
+    /**
+     * Return the currently negotiated and max supported HDCP levels.
+     *
+     * The current level is based on the display(s) the device is connected to.
+     * If multiple HDCP-capable displays are simultaneously connected to
+     * separate interfaces, this method returns the lowest negotiated HDCP level
+     * of all interfaces.
+     *
+     * The maximum HDCP level is the highest level that can potentially be
+     * negotiated. It is a constant for any device, i.e. it does not depend on
+     * downstream receiving devices that could be connected. For example, if
+     * the device has HDCP 1.x keys and is capable of negotiating HDCP 1.x, but
+     * does not have HDCP 2.x keys, then the maximum HDCP capability would be
+     * reported as 1.x. If multiple HDCP-capable interfaces are present, it
+     * indicates the highest of the maximum HDCP levels of all interfaces.
+     *
+     * This method should only be used for informational purposes, not for
+     * enforcing compliance with HDCP requirements. Trusted enforcement of HDCP
+     * policies must be handled by the DRM system.
+     *
+     * @return HdcpLevels parcelable
+     */
+    android.hardware.drm.HdcpLevels getHdcpLevels();
+
+    /**
+     * Attempts to set the device's HDCP auth level to |level|.
+     *
+     * @param level: desired HDCP level
+     *
+     * @return:
+     *     a service specific error based on <code>HalErrorCode</code>,
+     *     specifically:
+     *       + BAD_PARAMETER: when HDCP_UNKNOWN is requested
+     *       + UNSUPPORTED: when |level| is greater than the MaxLevel supported
+     *       + BAD_STATE: when the HDCP's service currentLevel is HDCP_NO_OUTPUT
+     *
+     */
+    void trySetHdcpLevel(in android.hardware.drm.HdcpLevel level);
+
+    /**
+     * Retrieve the pending level currently being processed by the HDCP service.
+     * The pending HDCP protection level might be higher than the level initially
+     * requested. This can occur when multiple applications or services are
+     * using HDCP concurrently, and a higher level is needed to satisfy
+     * all requirements.
+     *
+     * @return:
+     *      PendingHdcpLevelResult on success, which contains a status
+     *      and an optional level; on error a service specific error based on
+     *      <code>HalErrorCode</code> otherwise.
+     *
+     */
+    PendingHdcpLevelResult getPendingHdcpLevel();
+}
diff --git a/security/see/hdcp/aidl/trusty/drm/rust/rules.mk b/security/see/hdcp/aidl/trusty/drm/rust/rules.mk
new file mode 100644
index 0000000..742b6ab
--- /dev/null
+++ b/security/see/hdcp/aidl/trusty/drm/rust/rules.mk
@@ -0,0 +1,39 @@
+# 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+AIDL_DIR := hardware/interfaces/drm/aidl
+
+MODULE_AIDL_FLAGS := \
+	--stability=vintf \
+	--version=1 \
+
+MODULE_CRATE_NAME := android_hardware_drm
+
+MODULE_AIDL_LANGUAGE := rust
+
+MODULE_AIDL_PACKAGE := android/hardware/drm
+
+MODULE_AIDL_INCLUDES := \
+	-I $(AIDL_DIR) \
+
+MODULE_AIDLS := \
+    $(AIDL_DIR)/$(MODULE_AIDL_PACKAGE)/HdcpLevel.aidl   \
+    $(AIDL_DIR)/$(MODULE_AIDL_PACKAGE)/HdcpLevels.aidl   \
+
+include make/aidl.mk
diff --git a/security/see/hdcp/aidl/trusty/hdcp/rust/rules.mk b/security/see/hdcp/aidl/trusty/hdcp/rust/rules.mk
new file mode 100644
index 0000000..beab655
--- /dev/null
+++ b/security/see/hdcp/aidl/trusty/hdcp/rust/rules.mk
@@ -0,0 +1,47 @@
+# 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+AIDL_DIR := hardware/interfaces/security/see/hdcp/aidl
+DRM_AIDL_DIR := hardware/interfaces/drm/aidl
+
+MODULE_AIDL_FLAGS := \
+	--mockall \
+	--version=1 \
+
+MODULE_CRATE_NAME := android_hardware_security_see_hdcp
+
+MODULE_AIDL_LANGUAGE := rust
+
+MODULE_AIDL_PACKAGE := android/hardware/security/see/hdcp
+
+MODULE_AIDL_INCLUDES := \
+	-I $(AIDL_DIR) \
+	-I $(DRM_AIDL_DIR) \
+
+MODULE_AIDLS := \
+    $(AIDL_DIR)/$(MODULE_AIDL_PACKAGE)/IHdcpAuthControl.aidl   \
+
+MODULE_AIDL_RUST_DEPS := \
+	android_hardware_drm
+
+MODULE_LIBRARY_DEPS := \
+	hardware/interfaces/security/see/hdcp/aidl/trusty/drm/rust \
+	$(call FIND_CRATE,mockall) \
+
+include make/aidl.mk
diff --git a/security/see/hdcp/aidl/vts/Android.bp b/security/see/hdcp/aidl/vts/Android.bp
new file mode 100644
index 0000000..eadb9cd
--- /dev/null
+++ b/security/see/hdcp/aidl/vts/Android.bp
@@ -0,0 +1,36 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["Android-Apache-2.0"],
+    default_team: "trendy_team_trusty",
+}
+
+rust_test {
+    name: "VtsAidlHdcpNonExistentTest",
+    srcs: ["src/host_test.rs"],
+    require_root: true,
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+}
diff --git a/security/see/hdcp/aidl/vts/src/host_test.rs b/security/see/hdcp/aidl/vts/src/host_test.rs
new file mode 100644
index 0000000..f64de20
--- /dev/null
+++ b/security/see/hdcp/aidl/vts/src/host_test.rs
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+//! Test for asserting the non-existence of an IHdcpAuthControl.aidl
+
+#![cfg(test)]
+
+use binder;
+
+const HDCP_INTERFACE_NAME: &str = "android.hardware.security.see.hdcp.IHdcpAuthControl";
+
+#[test]
+fn test_hdcp_auth_control_non_existence() {
+    let hdcp_instances =  match binder::get_declared_instances(HDCP_INTERFACE_NAME) {
+        Ok(vec) => vec,
+        Err(e) => {
+            panic!("failed to retrieve the declared interfaces for HdcpAuthControl: {:?}", e);
+        }
+    };
+    assert!(hdcp_instances.is_empty());
+}
diff --git a/sensors/aidl/Android.bp b/sensors/aidl/Android.bp
index 8877e6e..63ace90 100644
--- a/sensors/aidl/Android.bp
+++ b/sensors/aidl/Android.bp
@@ -43,6 +43,6 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 
 }
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/AdditionalInfo.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/AdditionalInfo.aidl
index 5184723..a35b54c 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/AdditionalInfo.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/AdditionalInfo.aidl
@@ -54,23 +54,23 @@
   enum AdditionalInfoType {
     AINFO_BEGIN = 0,
     AINFO_END = 1,
-    AINFO_UNTRACKED_DELAY = 65536,
-    AINFO_INTERNAL_TEMPERATURE = 65537,
-    AINFO_VEC3_CALIBRATION = 65538,
-    AINFO_SENSOR_PLACEMENT = 65539,
-    AINFO_SAMPLING = 65540,
-    AINFO_CHANNEL_NOISE = 131072,
-    AINFO_CHANNEL_SAMPLER = 131073,
-    AINFO_CHANNEL_FILTER = 131074,
-    AINFO_CHANNEL_LINEAR_TRANSFORM = 131075,
-    AINFO_CHANNEL_NONLINEAR_MAP = 131076,
-    AINFO_CHANNEL_RESAMPLER = 131077,
-    AINFO_LOCAL_GEOMAGNETIC_FIELD = 196608,
-    AINFO_LOCAL_GRAVITY = 196609,
-    AINFO_DOCK_STATE = 196610,
-    AINFO_HIGH_PERFORMANCE_MODE = 196611,
-    AINFO_MAGNETIC_FIELD_CALIBRATION = 196612,
-    AINFO_CUSTOM_START = 268435456,
-    AINFO_DEBUGGING_START = 1073741824,
+    AINFO_UNTRACKED_DELAY = 0x10000,
+    AINFO_INTERNAL_TEMPERATURE,
+    AINFO_VEC3_CALIBRATION,
+    AINFO_SENSOR_PLACEMENT,
+    AINFO_SAMPLING,
+    AINFO_CHANNEL_NOISE = 0x20000,
+    AINFO_CHANNEL_SAMPLER,
+    AINFO_CHANNEL_FILTER,
+    AINFO_CHANNEL_LINEAR_TRANSFORM,
+    AINFO_CHANNEL_NONLINEAR_MAP,
+    AINFO_CHANNEL_RESAMPLER,
+    AINFO_LOCAL_GEOMAGNETIC_FIELD = 0x30000,
+    AINFO_LOCAL_GRAVITY,
+    AINFO_DOCK_STATE,
+    AINFO_HIGH_PERFORMANCE_MODE,
+    AINFO_MAGNETIC_FIELD_CALIBRATION,
+    AINFO_CUSTOM_START = 0x10000000,
+    AINFO_DEBUGGING_START = 0x40000000,
   }
 }
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
index b26040b..0566a64 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/ISensors.aidl
@@ -44,28 +44,28 @@
   int registerDirectChannel(in android.hardware.sensors.ISensors.SharedMemInfo mem);
   void setOperationMode(in android.hardware.sensors.ISensors.OperationMode mode);
   void unregisterDirectChannel(in int channelHandle);
-  const int ERROR_NO_MEMORY = -12;
-  const int ERROR_BAD_VALUE = -22;
+  const int ERROR_NO_MEMORY = (-12) /* -12 */;
+  const int ERROR_BAD_VALUE = (-22) /* -22 */;
   const int WAKE_LOCK_TIMEOUT_SECONDS = 1;
-  const int EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS = 1;
-  const int EVENT_QUEUE_FLAG_BITS_EVENTS_READ = 2;
-  const int WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN = 1;
-  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD = 0;
-  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN = 4;
-  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE = 8;
-  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER = 12;
-  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP = 16;
-  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 24;
-  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 88;
+  const int EVENT_QUEUE_FLAG_BITS_READ_AND_PROCESS = (1 << 0) /* 1 */;
+  const int EVENT_QUEUE_FLAG_BITS_EVENTS_READ = (1 << 1) /* 2 */;
+  const int WAKE_LOCK_QUEUE_FLAG_BITS_DATA_WRITTEN = (1 << 0) /* 1 */;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_FIELD = 0x0;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_REPORT_TOKEN = 0x4;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_SENSOR_TYPE = 0x8;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_ATOMIC_COUNTER = 0xC;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_TIMESTAMP = 0x10;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_DATA = 0x18;
+  const int DIRECT_REPORT_SENSOR_EVENT_OFFSET_SIZE_RESERVED = 0x58;
   const int DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH = 104;
-  const int RUNTIME_SENSORS_HANDLE_BASE = 1593835520;
-  const int RUNTIME_SENSORS_HANDLE_END = 1610612735;
+  const int RUNTIME_SENSORS_HANDLE_BASE = 0x5F000000;
+  const int RUNTIME_SENSORS_HANDLE_END = 0x5FFFFFFF;
   @Backing(type="int") @VintfStability
   enum RateLevel {
-    STOP = 0,
-    NORMAL = 1,
-    FAST = 2,
-    VERY_FAST = 3,
+    STOP,
+    NORMAL,
+    FAST,
+    VERY_FAST,
   }
   @Backing(type="int") @VintfStability
   enum OperationMode {
@@ -85,7 +85,7 @@
     @Backing(type="int") @VintfStability
     enum SharedMemType {
       ASHMEM = 1,
-      GRALLOC = 2,
+      GRALLOC,
     }
   }
 }
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorInfo.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorInfo.aidl
index 996be3d..677e6c4 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorInfo.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorInfo.aidl
@@ -54,14 +54,14 @@
   const int SENSOR_FLAG_BITS_ON_CHANGE_MODE = 2;
   const int SENSOR_FLAG_BITS_ONE_SHOT_MODE = 4;
   const int SENSOR_FLAG_BITS_SPECIAL_REPORTING_MODE = 6;
-  const int SENSOR_FLAG_BITS_DATA_INJECTION = 16;
-  const int SENSOR_FLAG_BITS_DYNAMIC_SENSOR = 32;
-  const int SENSOR_FLAG_BITS_ADDITIONAL_INFO = 64;
-  const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM = 1024;
-  const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC = 2048;
-  const int SENSOR_FLAG_BITS_MASK_REPORTING_MODE = 14;
-  const int SENSOR_FLAG_BITS_MASK_DIRECT_REPORT = 896;
-  const int SENSOR_FLAG_BITS_MASK_DIRECT_CHANNEL = 3072;
+  const int SENSOR_FLAG_BITS_DATA_INJECTION = 0x10;
+  const int SENSOR_FLAG_BITS_DYNAMIC_SENSOR = 0x20;
+  const int SENSOR_FLAG_BITS_ADDITIONAL_INFO = 0x40;
+  const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_ASHMEM = 0x400;
+  const int SENSOR_FLAG_BITS_DIRECT_CHANNEL_GRALLOC = 0x800;
+  const int SENSOR_FLAG_BITS_MASK_REPORTING_MODE = 0xE;
+  const int SENSOR_FLAG_BITS_MASK_DIRECT_REPORT = 0x380;
+  const int SENSOR_FLAG_BITS_MASK_DIRECT_CHANNEL = 0xC00;
   const int SENSOR_FLAG_SHIFT_REPORTING_MODE = 1;
   const int SENSOR_FLAG_SHIFT_DATA_INJECTION = 4;
   const int SENSOR_FLAG_SHIFT_DYNAMIC_SENSOR = 5;
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorStatus.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorStatus.aidl
index 4521710..f401dac 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorStatus.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorStatus.aidl
@@ -34,7 +34,7 @@
 package android.hardware.sensors;
 @Backing(type="byte") @VintfStability
 enum SensorStatus {
-  NO_CONTACT = -1,
+  NO_CONTACT = (-1) /* -1 */,
   UNRELIABLE = 0,
   ACCURACY_LOW = 1,
   ACCURACY_MEDIUM = 2,
diff --git a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
index 8c864e9..9332c63 100644
--- a/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
+++ b/sensors/aidl/aidl_api/android.hardware.sensors/current/android/hardware/sensors/SensorType.aidl
@@ -76,5 +76,6 @@
   ACCELEROMETER_LIMITED_AXES_UNCALIBRATED = 40,
   GYROSCOPE_LIMITED_AXES_UNCALIBRATED = 41,
   HEADING = 42,
-  DEVICE_PRIVATE_BASE = 65536,
+  MOISTURE_INTRUSION = 43,
+  DEVICE_PRIVATE_BASE = 0x10000,
 }
diff --git a/sensors/aidl/android/hardware/sensors/Event.aidl b/sensors/aidl/android/hardware/sensors/Event.aidl
index b95299c..7775cfc 100644
--- a/sensors/aidl/android/hardware/sensors/Event.aidl
+++ b/sensors/aidl/android/hardware/sensors/Event.aidl
@@ -88,7 +88,7 @@
          * SensorType::GLANCE_GESTURE, SensorType::PICK_UP_GESTURE,
          * SensorType::WRIST_TILT_GESTURE, SensorType::STATIONARY_DETECT,
          * SensorType::MOTION_DETECT, SensorType::HEART_BEAT,
-         * SensorType::LOW_LATENCY_OFFBODY_DETECT
+         * SensorType::LOW_LATENCY_OFFBODY_DETECT, SensorType::MOISTURE_INTRUSION
          */
         float scalar;
 
diff --git a/sensors/aidl/android/hardware/sensors/SensorType.aidl b/sensors/aidl/android/hardware/sensors/SensorType.aidl
index 4904c3f..adaf8e6 100644
--- a/sensors/aidl/android/hardware/sensors/SensorType.aidl
+++ b/sensors/aidl/android/hardware/sensors/SensorType.aidl
@@ -718,6 +718,20 @@
     HEADING = 42,
 
     /**
+     * MOISTURE_INTRUSION
+     * trigger mode: on-change
+     *
+     * Detects moisture intrusion in the chassis of device. This detection is
+     * one-way and persistent. Once a device is detected to have water damage,
+     * it will always report 1 (across factory reset /reboot) even if moisture
+     * is no longer present, until the device has been repaired.
+     * The only allowed values to return are:
+     *   0.0: no moisture intrusion detected in relevant history
+     *   1.0: moisture intrusion detected now or previously
+     */
+    MOISTURE_INTRUSION = 43,
+
+    /**
      * Base of the range reserved for device manufacturers' private sensor
      * types. These sensor types aren't documented in the SDK.
      */
diff --git a/sensors/aidl/convert/Android.bp b/sensors/aidl/convert/Android.bp
index 7217b2f..548308e 100644
--- a/sensors/aidl/convert/Android.bp
+++ b/sensors/aidl/convert/Android.bp
@@ -36,7 +36,7 @@
         "libhardware",
         "libbase",
         "libutils",
-        "android.hardware.sensors-V2-ndk",
+        "android.hardware.sensors-V3-ndk",
     ],
     whole_static_libs: [
         "sensors_common_convert",
diff --git a/sensors/aidl/default/Android.bp b/sensors/aidl/default/Android.bp
index 6f011ee..4bdcfb0 100644
--- a/sensors/aidl/default/Android.bp
+++ b/sensors/aidl/default/Android.bp
@@ -32,7 +32,7 @@
         "libfmq",
         "libpower",
         "libbinder_ndk",
-        "android.hardware.sensors-V2-ndk",
+        "android.hardware.sensors-V3-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
@@ -58,7 +58,7 @@
     static_libs: [
         "android.hardware.common-V2-ndk",
         "android.hardware.common.fmq-V1-ndk",
-        "android.hardware.sensors-V2-ndk",
+        "android.hardware.sensors-V3-ndk",
         "android.system.suspend-V1-ndk",
         "libbase",
         "libcutils",
diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp
index 7482ffe..6ca81d9 100644
--- a/sensors/aidl/default/multihal/Android.bp
+++ b/sensors/aidl/default/multihal/Android.bp
@@ -39,7 +39,7 @@
         "android.hardware.sensors@1.0",
         "android.hardware.sensors@2.0",
         "android.hardware.sensors@2.1",
-        "android.hardware.sensors-V2-ndk",
+        "android.hardware.sensors-V3-ndk",
     ],
     export_include_dirs: ["include"],
     srcs: [
diff --git a/sensors/aidl/default/sensors-default.xml b/sensors/aidl/default/sensors-default.xml
index 36b28ed..bed2538 100644
--- a/sensors/aidl/default/sensors-default.xml
+++ b/sensors/aidl/default/sensors-default.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.sensors</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>ISensors/default</fqname>
     </hal>
 </manifest>
diff --git a/sensors/aidl/multihal/Android.bp b/sensors/aidl/multihal/Android.bp
index cac5fc2..cee3db6 100644
--- a/sensors/aidl/multihal/Android.bp
+++ b/sensors/aidl/multihal/Android.bp
@@ -41,7 +41,7 @@
         "android.hardware.sensors@2.0-ScopedWakelock",
         "android.hardware.sensors@2.0",
         "android.hardware.sensors@2.1",
-        "android.hardware.sensors-V2-ndk",
+        "android.hardware.sensors-V3-ndk",
         "libbase",
         "libcutils",
         "libfmq",
diff --git a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
index 5da4fbd..9186f64 100644
--- a/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
+++ b/sensors/aidl/multihal/android.hardware.sensors-multihal.xml
@@ -17,7 +17,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.sensors</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>ISensors/default</fqname>
     </hal>
 </manifest>
diff --git a/sensors/aidl/vts/Android.bp b/sensors/aidl/vts/Android.bp
index 1f96bb4..63371cd 100644
--- a/sensors/aidl/vts/Android.bp
+++ b/sensors/aidl/vts/Android.bp
@@ -42,7 +42,7 @@
         "android.hardware.common.fmq-V1-ndk",
     ],
     static_libs: [
-        "android.hardware.sensors-V2-ndk",
+        "android.hardware.sensors-V3-ndk",
         "VtsHalSensorsTargetTestUtils",
         "libaidlcommonsupport",
     ],
diff --git a/thermal/aidl/Android.bp b/thermal/aidl/Android.bp
index 597a166..db77783 100644
--- a/thermal/aidl/Android.bp
+++ b/thermal/aidl/Android.bp
@@ -48,8 +48,7 @@
             version: "2",
             imports: [],
         },
-
     ],
-    frozen: true,
+    frozen: false,
 
 }
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl
index 904496c..3cff780 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermal.aidl
@@ -46,4 +46,5 @@
   void unregisterThermalChangedCallback(in android.hardware.thermal.IThermalChangedCallback callback);
   void registerCoolingDeviceChangedCallbackWithType(in android.hardware.thermal.ICoolingDeviceChangedCallback callback, in android.hardware.thermal.CoolingType type);
   void unregisterCoolingDeviceChangedCallback(in android.hardware.thermal.ICoolingDeviceChangedCallback callback);
+  float forecastSkinTemperature(in int forecastSeconds);
 }
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermalChangedCallback.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermalChangedCallback.aidl
index 5e1d753..779544b 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermalChangedCallback.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/IThermalChangedCallback.aidl
@@ -36,4 +36,5 @@
 @VintfStability
 interface IThermalChangedCallback {
   oneway void notifyThrottling(in android.hardware.thermal.Temperature temperature);
+  oneway void notifyThresholdChanged(in android.hardware.thermal.TemperatureThreshold threshold);
 }
diff --git a/thermal/aidl/android/hardware/thermal/IThermal.aidl b/thermal/aidl/android/hardware/thermal/IThermal.aidl
index 4aa4090..7c0ee24 100644
--- a/thermal/aidl/android/hardware/thermal/IThermal.aidl
+++ b/thermal/aidl/android/hardware/thermal/IThermal.aidl
@@ -225,4 +225,20 @@
      *         getMessage() must be populated with human-readable error message.
      */
     void unregisterCoolingDeviceChangedCallback(in ICoolingDeviceChangedCallback callback);
+
+    /**
+     * Retrieves the forecasted {@link TemperatureType#SKIN} type temperature in Celsius.
+     *
+     * @param forecastSeconds the number of seconds to forecast the skin temperature, it should
+     *                        support any value from a superset of range [0, 60] seconds.
+     *
+     * @return forecasted skin temperature in Celsius unit at the forecasted seconds in future.
+     *
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully
+     * @throws EX_ILLEGAL_ARGUMENT If the provided forecastSeconds is negative
+     * @throws EX_UNSUPPORTED_OPERATION if API is not supported or the forecastSeconds exceeds the
+     *         supported range. And the getMessage() must be populated with human-readable
+     *         error message.
+     */
+    float forecastSkinTemperature(in int forecastSeconds);
 }
diff --git a/thermal/aidl/android/hardware/thermal/IThermalChangedCallback.aidl b/thermal/aidl/android/hardware/thermal/IThermalChangedCallback.aidl
index 105f085..b40b7c2 100644
--- a/thermal/aidl/android/hardware/thermal/IThermalChangedCallback.aidl
+++ b/thermal/aidl/android/hardware/thermal/IThermalChangedCallback.aidl
@@ -17,6 +17,7 @@
 package android.hardware.thermal;
 
 import android.hardware.thermal.Temperature;
+import android.hardware.thermal.TemperatureThreshold;
 
 /**
  * IThermalChangedCallback send throttling notification to clients.
@@ -25,11 +26,24 @@
 @VintfStability
 interface IThermalChangedCallback {
     /**
-     * Send a thermal throttling event to all ThermalHAL
-     * thermal event listeners.
+     * Send a thermal throttling event to all Thermal HAL thermal event listeners.
      *
      * @param temperature The temperature associated with the
      *    throttling event.
      */
     oneway void notifyThrottling(in Temperature temperature);
+
+    /**
+     * Send a thermal threshold change event to all Thermal HAL thermal event listeners.
+     *
+     * Some devices may change the thresholds based on hardware state or app workload changes.
+     * While this is generally not recommended, it should be used with caution at low frequency
+     * especially for the {@link TemperatureType#SKIN} type temperature thresholds. Since such
+     * a skin type callback to system may trigger notifications to apps that have preivously
+     * registered thermal headroom listeners with a new set of headroom and thresholds in case
+     * any of them changed.
+     *
+     * @param threshold The temperature threshold that changed.
+     */
+    oneway void notifyThresholdChanged(in TemperatureThreshold threshold);
 }
diff --git a/thermal/aidl/default/Android.bp b/thermal/aidl/default/Android.bp
index 9fe62ce..9d89903 100644
--- a/thermal/aidl/default/Android.bp
+++ b/thermal/aidl/default/Android.bp
@@ -27,7 +27,7 @@
     vendor: true,
     stl: "c++_static",
     static_libs: [
-        "android.hardware.thermal-V2-ndk",
+        "android.hardware.thermal-V3-ndk",
         "libbase",
     ],
     shared_libs: [
diff --git a/thermal/aidl/default/Thermal.cpp b/thermal/aidl/default/Thermal.cpp
index 41d0be8..04efbd6 100644
--- a/thermal/aidl/default/Thermal.cpp
+++ b/thermal/aidl/default/Thermal.cpp
@@ -47,27 +47,85 @@
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus Thermal::getTemperatures(std::vector<Temperature>* /* out_temperatures */) {
+ScopedAStatus Thermal::getTemperatures(std::vector<Temperature>* out_temperatures) {
     LOG(VERBOSE) << __func__;
+    std::vector<Temperature> temperatures;
+    temperatures.push_back(Temperature{
+            .name = "skin",
+            .type = TemperatureType::SKIN,
+            .value = 30.1f,
+    });
+    temperatures.push_back(Temperature{
+            .name = "battery",
+            .type = TemperatureType::BATTERY,
+            .value = 30.2f,
+    });
+    *out_temperatures = temperatures;
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus Thermal::getTemperaturesWithType(TemperatureType in_type,
-                                               std::vector<Temperature>* /* out_temperatures */) {
+                                               std::vector<Temperature>* out_temperatures) {
     LOG(VERBOSE) << __func__ << " TemperatureType: " << static_cast<int32_t>(in_type);
+    if (in_type == TemperatureType::SKIN) {
+        std::vector<Temperature> temperatures;
+        temperatures.push_back(Temperature{
+                .name = "skin",
+                .type = TemperatureType::SKIN,
+                .value = 30.1f,
+        });
+        *out_temperatures = temperatures;
+    } else if (in_type == TemperatureType::BATTERY) {
+        std::vector<Temperature> temperatures;
+        temperatures.push_back(Temperature{
+                .name = "battery",
+                .type = TemperatureType::BATTERY,
+                .value = 30.2f,
+        });
+        *out_temperatures = temperatures;
+    }
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus Thermal::getTemperatureThresholds(
-        std::vector<TemperatureThreshold>* /* out_temperatureThresholds */) {
+        std::vector<TemperatureThreshold>* out_temperatureThresholds) {
     LOG(VERBOSE) << __func__;
+    std::vector<TemperatureThreshold> temperatureThresholds;
+    temperatureThresholds.push_back(TemperatureThreshold{
+            .name = "skin",
+            .type = TemperatureType::SKIN,
+            .hotThrottlingThresholds = {30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f},
+    });
+    temperatureThresholds.push_back(TemperatureThreshold{
+            .name = "battery",
+            .type = TemperatureType::BATTERY,
+            .hotThrottlingThresholds = {30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f},
+    });
+    *out_temperatureThresholds = temperatureThresholds;
     return ScopedAStatus::ok();
 }
 
 ScopedAStatus Thermal::getTemperatureThresholdsWithType(
         TemperatureType in_type,
-        std::vector<TemperatureThreshold>* /* out_temperatureThresholds */) {
+        std::vector<TemperatureThreshold>* out_temperatureThresholds) {
     LOG(VERBOSE) << __func__ << " TemperatureType: " << static_cast<int32_t>(in_type);
+    if (in_type == TemperatureType::SKIN) {
+        std::vector<TemperatureThreshold> temperatureThresholds;
+        temperatureThresholds.push_back(TemperatureThreshold{
+                .name = "skin",
+                .type = TemperatureType::SKIN,
+                .hotThrottlingThresholds = {30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f},
+        });
+        *out_temperatureThresholds = temperatureThresholds;
+    } else if (in_type == TemperatureType::BATTERY) {
+        std::vector<TemperatureThreshold> temperatureThresholds;
+        temperatureThresholds.push_back(TemperatureThreshold{
+                .name = "battery",
+                .type = TemperatureType::BATTERY,
+                .hotThrottlingThresholds = {30.0f, 31.0f, 32.0f, 33.0f, 34.0f, 35.0f, 36.0f},
+        });
+        *out_temperatureThresholds = temperatureThresholds;
+    }
     return ScopedAStatus::ok();
 }
 
@@ -191,4 +249,9 @@
     }
     return ScopedAStatus::ok();
 }
+
+ndk::ScopedAStatus Thermal::forecastSkinTemperature(int32_t, float*) {
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
 }  // namespace aidl::android::hardware::thermal::impl::example
diff --git a/thermal/aidl/default/Thermal.h b/thermal/aidl/default/Thermal.h
index d3d8874..a4d8b00 100644
--- a/thermal/aidl/default/Thermal.h
+++ b/thermal/aidl/default/Thermal.h
@@ -60,6 +60,8 @@
 
     ndk::ScopedAStatus unregisterCoolingDeviceChangedCallback(
             const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback) override;
+    ndk::ScopedAStatus forecastSkinTemperature(int32_t forecastSeconds,
+                                               float* _aidl_return) override;
 
   private:
     std::mutex thermal_callback_mutex_;
diff --git a/thermal/aidl/default/thermal-example.xml b/thermal/aidl/default/thermal-example.xml
index 08dc68c..148ddbf 100644
--- a/thermal/aidl/default/thermal-example.xml
+++ b/thermal/aidl/default/thermal-example.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.thermal</name>
-        <version>2</version>
+        <version>3</version>
         <fqname>IThermal/default</fqname>
     </hal>
 </manifest>
diff --git a/thermal/aidl/vts/Android.bp b/thermal/aidl/vts/Android.bp
index 35f7649..18cb051 100644
--- a/thermal/aidl/vts/Android.bp
+++ b/thermal/aidl/vts/Android.bp
@@ -33,7 +33,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "android.hardware.thermal-V2-ndk",
+        "android.hardware.thermal-V3-ndk",
     ],
     test_suites: [
         "vts",
diff --git a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
index 7f33e2d..17653b4 100644
--- a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
+++ b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
@@ -93,6 +93,10 @@
         return ndk::ScopedAStatus::ok();
     }
 
+    ndk::ScopedAStatus notifyThresholdChanged(const TemperatureThreshold&) {
+        return ndk::ScopedAStatus::ok();
+    }
+
     template <typename R, typename P>
     [[nodiscard]] bool waitForCallback(std::chrono::duration<R, P> duration) {
         std::unique_lock<std::mutex> lock(mMutex);
@@ -422,6 +426,23 @@
     }
 }
 
+// Test Thermal->forecastSkinTemperature.
+TEST_P(ThermalAidlTest, ForecastSkinTemperatureTest) {
+    auto apiLevel = ::android::base::GetIntProperty<int32_t>("ro.vendor.api_level", 0);
+    if (apiLevel < 202504) {
+        GTEST_SKIP() << "Skipping test as the vendor level is below 202504: " << apiLevel;
+    }
+    float temperature = 0.0f;
+    ::ndk::ScopedAStatus status = mThermal->forecastSkinTemperature(1, &temperature);
+    if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+        GTEST_SKIP() << "Skipping test as temperature forecast is not supported";
+    }
+    for (int i = 0; i <= 60; i++) {
+        status = mThermal->forecastSkinTemperature(i, &temperature);
+        ASSERT_NE(NAN, temperature);
+    }
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalAidlTest);
 INSTANTIATE_TEST_SUITE_P(
         Thermal, ThermalAidlTest,
diff --git a/tv/input/aidl/Android.bp b/tv/input/aidl/Android.bp
index afc811a..8d36ab1 100644
--- a/tv/input/aidl/Android.bp
+++ b/tv/input/aidl/Android.bp
@@ -45,5 +45,5 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
index 84fe2fb..2ff2719 100644
--- a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
@@ -40,6 +40,8 @@
   void setCallback(in android.hardware.tv.input.ITvInputCallback callback);
   void setTvMessageEnabled(int deviceId, int streamId, in android.hardware.tv.input.TvMessageEventType type, boolean enabled);
   void getTvMessageQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue, int deviceId, int streamId);
+  void setPictureProfileId(in int deviceId, in int streamId, in long profileId);
+  void setSoundProfileId(in int deviceId, in int streamId, in long profileId);
   const int STATUS_UNKNOWN = 1;
   const int STATUS_NO_RESOURCE = 2;
   const int STATUS_INVALID_ARGUMENTS = 3;
diff --git a/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
index c63e0ac..e57edf9 100644
--- a/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
+++ b/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
@@ -109,4 +109,28 @@
      */
     void getTvMessageQueueDesc(
             out MQDescriptor<byte, SynchronizedReadWrite> queue, int deviceId, int streamId);
+
+    /**
+     * Set the picture profile ID for a specific stream in a device.
+     *
+     * @param deviceId Device ID for the stream to use the profile.
+     * @param streamId Stream ID for the stream to  use the profile. Must be one of the
+     *         stream IDs returned from getStreamConfigurations().
+     * @param profileId Picture profile ID for the stream. The ID is assigned by the framework,
+     *         and can be set by applications or TV input framework. See
+     *         android.media.quality.PictureQuality for more details.
+     */
+    void setPictureProfileId(in int deviceId, in int streamId, in long profileId);
+
+    /**
+     * Set the sound profile ID for a specific stream in a device.
+     *
+     * @param deviceId Device ID for the stream to use the profile.
+     * @param streamId Stream ID for the stream to  use the profile. Must be one of the
+     *         stream IDs returned from getStreamConfigurations().
+     * @param profileId Sound profile ID for the stream. The ID is assigned by the framework,
+     *         and can be set by applications or TV input framework. See
+     *         android.media.quality.SoundQuality for more details.
+     */
+    void setSoundProfileId(in int deviceId, in int streamId, in long profileId);
 }
diff --git a/tv/mediaquality/OWNERS b/tv/mediaquality/OWNERS
new file mode 100644
index 0000000..35ca732
--- /dev/null
+++ b/tv/mediaquality/OWNERS
@@ -0,0 +1,3 @@
+quxiangfang@google.com
+shubang@google.com
+haofanw@google.com
\ No newline at end of file
diff --git a/tv/mediaquality/aidl/Android.bp b/tv/mediaquality/aidl/Android.bp
new file mode 100644
index 0000000..49cfd80
--- /dev/null
+++ b/tv/mediaquality/aidl/Android.bp
@@ -0,0 +1,39 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+aidl_interface {
+    name: "android.hardware.tv.mediaquality",
+    vendor_available: true,
+    owner: "haofanw",
+    srcs: [
+        "android/hardware/tv/mediaquality/*.aidl",
+    ],
+    imports: [
+        "android.hardware.graphics.common-V5",
+    ],
+    stability: "vintf",
+    backend: {
+        java: {
+            enabled: true,
+            platform_apis: true,
+        },
+        ndk: {
+            enabled: true,
+            min_sdk_version: "31",
+        },
+        rust: {
+            enabled: true,
+            min_sdk_version: "31",
+        },
+        cpp: {
+            enabled: false,
+        },
+    },
+    frozen: false,
+}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightCompressAlgorithm.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightCompressAlgorithm.aidl
index a5eda52..d441370 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightCompressAlgorithm.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum AmbientBacklightCompressAlgorithm {
+  NONE = 0,
+  RLE = 1,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightEvent.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightEvent.aidl
index a5eda52..2fc2cc6 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightEvent.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+union AmbientBacklightEvent {
+  boolean enabled;
+  android.hardware.tv.mediaquality.AmbientBacklightMetadata metadata;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightMetadata.aidl
similarity index 86%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightMetadata.aidl
index a5eda52..bbdfd62 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightMetadata.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable AmbientBacklightMetadata {
+  android.hardware.tv.mediaquality.AmbientBacklightSettings settings;
+  android.hardware.tv.mediaquality.AmbientBacklightCompressAlgorithm compressAlgorithm;
+  int[] zonesColors;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightSettings.aidl
similarity index 83%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightSettings.aidl
index a5eda52..ffbae26 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightSettings.aidl
@@ -31,9 +31,15 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable AmbientBacklightSettings {
+  String packageName;
+  android.hardware.tv.mediaquality.AmbientBacklightSource source;
+  int maxFramerate;
+  android.hardware.graphics.common.PixelFormat colorFormat;
+  int hZonesNumber;
+  int vZonesNumber;
+  boolean hasLetterbox;
+  int threshold;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightSource.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightSource.aidl
index a5eda52..22912f4 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/AmbientBacklightSource.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum AmbientBacklightSource {
+  NONE = 0,
+  AUDIO = 1,
+  VIDEO = 2,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorRange.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorRange.aidl
index a5eda52..c08c6cc 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorRange.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum ColorRange {
+  AUTO,
+  LIMITED,
+  FULL,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorSpace.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorSpace.aidl
index a5eda52..9bcddcb 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorSpace.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum ColorSpace {
+  AUTO,
+  S_RGB_BT_709,
+  DCI,
+  ADOBE_RGB,
+  BT2020,
+  ON,
+  OFF,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorTemperature.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorTemperature.aidl
index a5eda52..2d26aca 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ColorTemperature.aidl
@@ -31,9 +31,17 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum ColorTemperature {
+  USER,
+  COOL,
+  STANDARD,
+  WARM,
+  USER_HDR10PLUS,
+  COOL_HDR10PLUS,
+  STANDARD_HDR10PLUS,
+  WARM_HDR10PLUS,
+  FMMSDR,
+  FMMHDR,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DigitalOutput.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DigitalOutput.aidl
index a5eda52..a6e8b91 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DigitalOutput.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum DigitalOutput {
+  AUTO,
+  BYPASS,
+  PCM,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DolbyAudioProcessing.aidl
similarity index 84%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DolbyAudioProcessing.aidl
index a5eda52..c29ae18 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DolbyAudioProcessing.aidl
@@ -31,9 +31,17 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable DolbyAudioProcessing {
+  android.hardware.tv.mediaquality.DolbyAudioProcessing.SoundMode soundMode;
+  boolean volumeLeveler;
+  boolean surroundVirtualizer;
+  boolean doblyAtmos;
+  enum SoundMode {
+    GAME,
+    MOVIE,
+    MUSIC,
+    NEWS,
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DownmixMode.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DownmixMode.aidl
index a5eda52..ecb7db2 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DownmixMode.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum DownmixMode {
+  STEREO,
+  SURROUND,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DtsVirtualX.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DtsVirtualX.aidl
index a5eda52..d136dd9 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/DtsVirtualX.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable DtsVirtualX {
+  boolean tbHdx;
+  boolean limiter;
+  boolean truSurroundX;
+  boolean truVolumeHd;
+  boolean dialogClarity;
+  boolean definition;
+  boolean height;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/EqualizerDetail.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/EqualizerDetail.aidl
index a5eda52..99543e9 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/EqualizerDetail.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable EqualizerDetail {
+  int band120Hz;
+  int band500Hz;
+  int band1_5kHz;
+  int band5kHz;
+  int band10kHz;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/Gamma.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/Gamma.aidl
index a5eda52..89bb808 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/Gamma.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum Gamma {
+  DARK,
+  MIDDLE,
+  BRIGHT,
 }
diff --git a/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IMediaQuality.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IMediaQuality.aidl
new file mode 100644
index 0000000..b569baa
--- /dev/null
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IMediaQuality.aidl
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.mediaquality;
+@VintfStability
+interface IMediaQuality {
+  void setCallback(in android.hardware.tv.mediaquality.IMediaQualityCallback callback);
+  void setAmbientBacklightDetector(in android.hardware.tv.mediaquality.AmbientBacklightSettings settings);
+  void setAmbientBacklightDetectionEnabled(in boolean enabled);
+  boolean getAmbientBacklightDetectionEnabled();
+  boolean isAutoPqSupported();
+  boolean getAutoPqEnabled();
+  void setAutoPqEnabled(boolean enable);
+  boolean isAutoSrSupported();
+  boolean getAutoSrEnabled();
+  void setAutoSrEnabled(boolean enable);
+  boolean isAutoAqSupported();
+  boolean getAutoAqEnabled();
+  void setAutoAqEnabled(boolean enable);
+  android.hardware.tv.mediaquality.IPictureProfileChangedListener getPictureProfileListener();
+  void setPictureProfileAdjustmentListener(android.hardware.tv.mediaquality.IPictureProfileAdjustmentListener listener);
+  void sendDefaultPictureParameters(in android.hardware.tv.mediaquality.PictureParameters pictureParameters);
+  android.hardware.tv.mediaquality.ISoundProfileChangedListener getSoundProfileListener();
+  void setSoundProfileAdjustmentListener(android.hardware.tv.mediaquality.ISoundProfileAdjustmentListener listener);
+  void sendDefaultSoundParameters(in android.hardware.tv.mediaquality.SoundParameters soundParameters);
+  void getParamCaps(in android.hardware.tv.mediaquality.ParameterName[] paramNames, out android.hardware.tv.mediaquality.ParamCapability[] caps);
+  void getVendorParamCaps(in android.hardware.tv.mediaquality.VendorParameterIdentifier[] names, out android.hardware.tv.mediaquality.VendorParamCapability[] caps);
+  void sendPictureParameters(in android.hardware.tv.mediaquality.PictureParameters pictureParameters);
+  void sendSoundParameters(in android.hardware.tv.mediaquality.SoundParameters soundParameters);
+}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IMediaQualityCallback.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IMediaQualityCallback.aidl
index a5eda52..014bf58 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IMediaQualityCallback.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface IMediaQualityCallback {
+  oneway void notifyAmbientBacklightEvent(in android.hardware.tv.mediaquality.AmbientBacklightEvent event);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IPictureProfileAdjustmentListener.aidl
similarity index 76%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IPictureProfileAdjustmentListener.aidl
index a5eda52..e1a882e 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IPictureProfileAdjustmentListener.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface IPictureProfileAdjustmentListener {
+  oneway void onPictureProfileAdjusted(in android.hardware.tv.mediaquality.PictureProfile pictureProfile);
+  oneway void onParamCapabilityChanged(long pictureProfileId, in android.hardware.tv.mediaquality.ParamCapability[] caps);
+  oneway void onVendorParamCapabilityChanged(long pictureProfileId, in android.hardware.tv.mediaquality.VendorParamCapability[] caps);
+  oneway void onRequestPictureParameters(long pictureProfileId);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IPictureProfileChangedListener.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IPictureProfileChangedListener.aidl
index a5eda52..c1bfc36 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/IPictureProfileChangedListener.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface IPictureProfileChangedListener {
+  oneway void onPictureProfileChanged(in android.hardware.tv.mediaquality.PictureProfile pictureProfile);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ISoundProfileAdjustmentListener.aidl
similarity index 76%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ISoundProfileAdjustmentListener.aidl
index a5eda52..e162601 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ISoundProfileAdjustmentListener.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface ISoundProfileAdjustmentListener {
+  oneway void onSoundProfileAdjusted(in android.hardware.tv.mediaquality.SoundProfile soundProfile);
+  oneway void onParamCapabilityChanged(long soundProfileId, in android.hardware.tv.mediaquality.ParamCapability[] caps);
+  oneway void onVendorParamCapabilityChanged(long soundProfileId, in android.hardware.tv.mediaquality.VendorParamCapability[] caps);
+  oneway void onRequestSoundParameters(long SoundProfileId);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ISoundProfileChangedListener.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ISoundProfileChangedListener.aidl
index a5eda52..d07abe7 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ISoundProfileChangedListener.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface ISoundProfileChangedListener {
+  oneway void onSoundProfileChanged(in android.hardware.tv.mediaquality.SoundProfile soundProfile);
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/NumberRange.aidl
similarity index 85%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/NumberRange.aidl
index a5eda52..9fc9d0d 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/NumberRange.aidl
@@ -31,9 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+union NumberRange {
+  @nullable int[2] intMinMax;
+  @nullable long[2] longMinMax;
+  @nullable double[2] doubleMinMax;
+  @nullable int[] intValuesSupported;
+  @nullable long[] longValuesSupported;
+  @nullable double[] doubleValuesSupported;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParamCapability.aidl
similarity index 84%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParamCapability.aidl
index a5eda52..c60f1d1 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParamCapability.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable ParamCapability {
+  android.hardware.tv.mediaquality.ParameterName name;
+  boolean isSupported;
+  @nullable android.hardware.tv.mediaquality.ParameterDefaultValue defaultValue;
+  @nullable android.hardware.tv.mediaquality.ParameterRange range;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterDefaultValue.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterDefaultValue.aidl
index a5eda52..14e5ff4 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterDefaultValue.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+union ParameterDefaultValue {
+  int intDefault;
+  long longDefault;
+  double doubleDefault;
+  String stringDefault;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterName.aidl
similarity index 64%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterName.aidl
index a5eda52..711e270 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterName.aidl
@@ -31,9 +31,50 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum ParameterName {
+  BRIGHTNESS,
+  CONTRAST,
+  SHARPNESS,
+  SATURATION,
+  HUE,
+  COLOR_TUNER_BRIGHTNESS,
+  COLOR_TUNER_SATURATION,
+  COLOR_TUNER_HUE,
+  COLOR_TUNER_RED_OFFSET,
+  COLOR_TUNER_GREEN_OFFSET,
+  COLOR_TUNER_BLUE_OFFSET,
+  COLOR_TUNER_RED_GAIN,
+  COLOR_TUNER_GREEN_GAIN,
+  COLOR_TUNER_BLUE_GAIN,
+  NOISE_REDUCTION,
+  MPEG_NOISE_REDUCTION,
+  FLASH_TONE,
+  DE_CONTOUR,
+  DYNAMIC_LUMA_CONTROL,
+  FILM_MODE,
+  BLACK_STRETCH,
+  BLUE_STRETCH,
+  COLOR_TUNE,
+  COLOR_TEMPERATURE,
+  GLOBE_DIMMING,
+  AUTO_PICTUREQUALITY_ENABLED,
+  AUTO_SUPER_RESOLUTION_ENABLED,
+  BALANCE,
+  BASS,
+  TREBLE,
+  SURROUND_SOUND_ENABLED,
+  EQUALIZER_DETAIL,
+  SPEAKERS_ENABLED,
+  SPEAKERS_DELAY_MS,
+  ENHANCED_AUDIO_RETURN_CHANNEL_ENABLED,
+  AUTO_VOLUME_CONTROL,
+  DOWNMIX_MODE,
+  DTS_DRC,
+  DOLBY_AUDIO_PROCESSING,
+  DOLBY_DIALOGUE_ENHANCER,
+  DTS_VIRTUAL_X,
+  DIGITAL_OUTPUT,
+  DIGITAL_OUTPUT_DELAY_MS,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterRange.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterRange.aidl
index a5eda52..66bc405 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/ParameterRange.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable ParameterRange {
+  android.hardware.tv.mediaquality.NumberRange numRange;
+  ParcelableHolder vendorDefinedValues;
 }
diff --git a/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureParameter.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureParameter.aidl
new file mode 100644
index 0000000..c38e96f
--- /dev/null
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureParameter.aidl
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.mediaquality;
+@VintfStability
+union PictureParameter {
+  float brightness;
+  int contrast;
+  int sharpness;
+  int saturation;
+  int hue;
+  int colorTunerBrightness;
+  int colorTunerSaturation;
+  int colorTunerHue;
+  int colorTunerRedOffset;
+  int colorTunerGreenOffset;
+  int colorTunerBlueOffset;
+  int colorTunerRedGain;
+  int colorTunerGreenGain;
+  int colorTunerBlueGain;
+  android.hardware.tv.mediaquality.QualityLevel noiseReduction;
+  android.hardware.tv.mediaquality.QualityLevel mpegNoiseReduction;
+  android.hardware.tv.mediaquality.QualityLevel fleshTone;
+  android.hardware.tv.mediaquality.QualityLevel deContour;
+  android.hardware.tv.mediaquality.QualityLevel dynamicLumaControl;
+  boolean filmMode;
+  boolean blueStretch;
+  boolean colorTune;
+  android.hardware.tv.mediaquality.ColorTemperature colorTemperature;
+  boolean globeDimming;
+  boolean autoPictureQualityEnabled;
+  boolean autoSuperResolutionEnabled;
+  android.hardware.tv.mediaquality.ColorRange levelRange;
+  boolean gamutMapping;
+  boolean pcMode;
+  boolean lowLatency;
+  boolean vrr;
+  boolean cvrr;
+  android.hardware.tv.mediaquality.ColorRange hdmiRgbRange;
+  android.hardware.tv.mediaquality.ColorSpace colorSpace;
+  int panelInitMaxLuminceNits;
+  boolean panelInitMaxLuminceValid;
+  android.hardware.tv.mediaquality.Gamma gamma;
+}
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureParameters.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureParameters.aidl
index a5eda52..627369d 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureParameters.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable PictureParameters {
+  android.hardware.tv.mediaquality.PictureParameter[] pictureParameters;
+  ParcelableHolder vendorPictureParameters;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureProfile.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureProfile.aidl
index a5eda52..ec2f9ff 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/PictureProfile.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable PictureProfile {
+  long pictureProfileId;
+  android.hardware.tv.mediaquality.PictureParameters parameters;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/QualityLevel.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/QualityLevel.aidl
index a5eda52..a7f130f 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/QualityLevel.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+enum QualityLevel {
+  OFF,
+  LOW,
+  MEDIUM,
+  HIGH,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundParameter.aidl
similarity index 69%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundParameter.aidl
index a5eda52..63eb55f 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundParameter.aidl
@@ -31,9 +31,23 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+union SoundParameter {
+  int balance;
+  int bass;
+  int treble;
+  boolean surroundSoundEnabled;
+  android.hardware.tv.mediaquality.EqualizerDetail equalizerDetail;
+  boolean speakersEnabled;
+  int speakersDelayMs;
+  boolean enhancedAudioReturnChannelEnabled;
+  boolean autoVolumeControl;
+  android.hardware.tv.mediaquality.DownmixMode downmixMode;
+  boolean dtsDrc;
+  @nullable android.hardware.tv.mediaquality.DolbyAudioProcessing dolbyAudioProcessing;
+  android.hardware.tv.mediaquality.QualityLevel dolbyDialogueEnhancer;
+  @nullable android.hardware.tv.mediaquality.DtsVirtualX dtsVirtualX;
+  android.hardware.tv.mediaquality.DigitalOutput digitalOutput;
+  int digitalOutputDelayMs;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundParameters.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundParameters.aidl
index a5eda52..6492163 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundParameters.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable SoundParameters {
+  android.hardware.tv.mediaquality.SoundParameter[] soundParameters;
+  ParcelableHolder vendorSoundParameters;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundProfile.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundProfile.aidl
index a5eda52..05f936f 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/SoundProfile.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable SoundProfile {
+  long soundProfileId;
+  android.hardware.tv.mediaquality.SoundParameters parameters;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/VendorParamCapability.aidl
similarity index 83%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/VendorParamCapability.aidl
index a5eda52..5f16de9 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/VendorParamCapability.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable VendorParamCapability {
+  android.hardware.tv.mediaquality.VendorParameterIdentifier identifier;
+  boolean isSupported;
+  @nullable android.hardware.tv.mediaquality.ParameterDefaultValue defaultValue;
+  @nullable android.hardware.tv.mediaquality.ParameterRange range;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/VendorParameterIdentifier.aidl
similarity index 92%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/VendorParameterIdentifier.aidl
index a5eda52..016c22d 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/mediaquality/aidl/aidl_api/android.hardware.tv.mediaquality/current/android/hardware/tv/mediaquality/VendorParameterIdentifier.aidl
@@ -31,9 +31,8 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.mediaquality;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable VendorParameterIdentifier {
+  ParcelableHolder identifier;
 }
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightCompressAlgorithm.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightCompressAlgorithm.aidl
new file mode 100644
index 0000000..e1c68b3
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightCompressAlgorithm.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+enum AmbientBacklightCompressAlgorithm {
+    /**
+     * The compress algorithm is disabled.
+     */
+    NONE = 0,
+    /**
+     * The compress algorithm is enabled for RLE (Run-Length Encoding).
+     */
+    RLE = 1,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightEvent.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightEvent.aidl
new file mode 100644
index 0000000..237e531
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightEvent.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.AmbientBacklightMetadata;
+
+@VintfStability
+union AmbientBacklightEvent {
+    /**
+     * This field is relevant when the event signifies that ambient backlight is enabled.
+     */
+    boolean enabled;
+
+    /**
+     * This field is relevant when the event includes ambient backlight metadata.
+     */
+    AmbientBacklightMetadata metadata;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightMetadata.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightMetadata.aidl
new file mode 100644
index 0000000..49b3a28
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightMetadata.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.AmbientBacklightCompressAlgorithm;
+import android.hardware.tv.mediaquality.AmbientBacklightSettings;
+
+@VintfStability
+parcelable AmbientBacklightMetadata {
+    /**
+     * The settings which are used to generate the colors.
+     */
+    AmbientBacklightSettings settings;
+
+    /**
+     * The compress algorithm of the ambient backlight colors.
+     */
+    AmbientBacklightCompressAlgorithm compressAlgorithm;
+
+    /**
+     * The colors for the zones. Format of the color will be indicated in the
+     * AmbientBacklightSettings::colorFormat.
+     */
+    int[] zonesColors;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightSettings.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightSettings.aidl
new file mode 100644
index 0000000..b6a26ee
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightSettings.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.graphics.common.PixelFormat;
+import android.hardware.tv.mediaquality.AmbientBacklightSource;
+
+@VintfStability
+parcelable AmbientBacklightSettings {
+    /**
+     * The package name of the ambient backlight control application.
+     */
+    String packageName;
+
+    /**
+     * The source of the ambient backlight.
+     */
+    AmbientBacklightSource source;
+
+    /**
+     * The maximum framerate for the ambient backlight.
+     */
+    int maxFramerate;
+
+    /**
+     * The color format for the ambient backlight.
+     */
+    PixelFormat colorFormat;
+
+    /**
+     * The number of zones in horizontal direction.
+     */
+    int hZonesNumber;
+
+    /**
+     * The number of zones in vertical direction.
+     */
+    int vZonesNumber;
+
+    /**
+     * When a video has a different aspect ratio than the display people
+     * watching it on, they often get black bars at the top and bottom
+     * (or sometimes the sides). These black bars are called "letterboxing".
+     * It's a way to show the entire video without distortion, but it means
+     * some of the screen space is unused. This configuration determines
+     * whether to ignore the black bar used for padding.
+     */
+    boolean hasLetterbox;
+
+    /**
+     * The color threshold for the ambient backlight. The units of the color deopends on
+     * the colorFormat. For example, RGB888, where the values of R/G/B range from 0 to 255,
+     * and the threshold is a positive number within the same range.
+     */
+    int threshold;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightSource.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightSource.aidl
new file mode 100644
index 0000000..8051fb6
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/AmbientBacklightSource.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+enum AmbientBacklightSource {
+    /**
+     * The detection is disabled.
+     */
+    NONE = 0,
+    /**
+     * The detection is enabled for audio.
+     */
+    AUDIO = 1,
+    /**
+     * The detection is enabled for video.
+     */
+    VIDEO = 2,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorRange.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorRange.aidl
new file mode 100644
index 0000000..29f12ef
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorRange.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+/**
+ * The range of color the TV can display.
+ */
+@VintfStability
+enum ColorRange {
+    AUTO,
+    LIMITED,
+    FULL,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorSpace.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorSpace.aidl
new file mode 100644
index 0000000..bd4511d
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorSpace.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+/**
+ * Specific model used to define and represent colors numerically.
+ */
+@VintfStability
+enum ColorSpace {
+    AUTO,
+    S_RGB_BT_709,
+    DCI,
+    ADOBE_RGB,
+    BT2020,
+    ON,
+    OFF,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorTemperature.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorTemperature.aidl
new file mode 100644
index 0000000..4d4b01c
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ColorTemperature.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+enum ColorTemperature {
+    USER,
+    COOL,
+    STANDARD,
+    WARM,
+    USER_HDR10PLUS,
+    COOL_HDR10PLUS,
+    STANDARD_HDR10PLUS,
+    WARM_HDR10PLUS,
+    FMMSDR,
+    FMMHDR,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DigitalOutput.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DigitalOutput.aidl
new file mode 100644
index 0000000..1a46ae6
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DigitalOutput.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+enum DigitalOutput {
+    /**
+     * Automatically selects the best audio format to send to the connected audio device
+     * based on the incoming audio stream. This mode prioritizes high-quality formats
+     * like Dolby Digital or DTS if supported by the device, otherwise falls back to PCM.
+     */
+    AUTO,
+
+    /**
+     * Sends the raw, unprocessed audio stream directly to the connected audio device.
+     * This mode requires the audio device to handle decoding and processing of various
+     * audio formats like Dolby Digital or DTS.
+     */
+    BYPASS,
+
+    /**
+     * Converts all incoming audio to 2-channel PCM (Pulse Code Modulation) stereo
+     * before sending it to the audio device. This ensures compatibility with a wide
+     * range of devices but sacrifices surround sound capabilities.
+     */
+    PCM,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DolbyAudioProcessing.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DolbyAudioProcessing.aidl
new file mode 100644
index 0000000..d56848c
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DolbyAudioProcessing.aidl
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+parcelable DolbyAudioProcessing {
+    enum SoundMode {
+        GAME,
+        MOVIE,
+        MUSIC,
+        NEWS,
+    }
+
+    /**
+     * sound mode for dolby audio processing.
+     */
+    SoundMode soundMode;
+
+    /**
+     * Indicates whether Volume Leveler is enabled.
+     *
+     * <p>Volume Leveler helps to maintain a consistent volume level across different
+     * types of content and even within the same program. It minimizes the jarring jumps
+     * between loud commercials and quiet dialogue or action sequences.
+     */
+    boolean volumeLeveler;
+
+    /**
+     * Indicates whether Surround Virtualizer is enabled.
+     *
+     * <p>Surround Virtualizer creates a virtual surround sound experience from stereo
+     * content, making it seem like the sound is coming from multiple speakers, even if
+     * you only have your TV's built-in speakers. It expands the soundstage and adds
+     * depth to the audio.
+     */
+    boolean surroundVirtualizer;
+
+    /**
+     * Indicates whether Dolby Atmos is enabled.
+     *
+     * <p>Dolby Atmos creates a more immersive and realistic sound experience by adding
+     * a height dimension to surround sound. It allows sound to be placed and moved
+     * precisely around you, including overhead.
+     *
+     * <p>Note: To experience Dolby Atmos, you need content that has been specifically
+     * mixed in Dolby Atmos and a compatible sound system with upward-firing speakers
+     * or a Dolby Atmos soundbar.
+     */
+    boolean doblyAtmos;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DownmixMode.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DownmixMode.aidl
new file mode 100644
index 0000000..c30a0ba
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DownmixMode.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+enum DownmixMode {
+    STEREO,
+    SURROUND,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DtsVirtualX.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DtsVirtualX.aidl
new file mode 100644
index 0000000..b26a41d
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/DtsVirtualX.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+parcelable DtsVirtualX {
+    /*
+     * Total Bass Harmonic Distortion (X).
+     * Enables/disables TBHDX bass enhancement. Provides a richer low-frequency experience,
+     * simulating deeper bass.
+     */
+    boolean tbHdx;
+
+    /*
+     * Activates an audio limiter. Prevents excessive volume peaks that could cause distortion
+     * or speaker damage
+     */
+    boolean limiter;
+
+    /*
+     * Enables/disables the core DTS Virtual:X surround sound processing. Creates an immersive,
+     * multi-channel audio experience from the speaker configuration.
+     */
+    boolean truSurroundX;
+
+    /*
+     * Activates DTS TruVolume HD. Reduces the dynamic range of audio, minimizing loudness
+     * variations between content and channels.
+     */
+    boolean truVolumeHd;
+
+    /* Enhances the clarity and intelligibility of speech in audio content. */
+    boolean dialogClarity;
+
+    /* Applies audio processing to improve overall sound definition and clarity. */
+    boolean definition;
+
+    /*
+     * Enables/disables the processing of virtual height channels. Creates a more immersive
+     * audio experience by simulating sounds from above.
+     */
+    boolean height;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/EqualizerDetail.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/EqualizerDetail.aidl
new file mode 100644
index 0000000..6eebdc0
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/EqualizerDetail.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+parcelable EqualizerDetail {
+    int band120Hz; // Range: -50 to 50
+    int band500Hz; // Range: -50 to 50
+    int band1_5kHz; // Range: -50 to 50
+    int band5kHz; // Range: -50 to 50
+    int band10kHz; // Range: -50 to 50
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/Gamma.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/Gamma.aidl
new file mode 100644
index 0000000..c633557
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/Gamma.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+enum Gamma {
+    DARK,
+    MIDDLE,
+    BRIGHT,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IMediaQuality.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IMediaQuality.aidl
new file mode 100644
index 0000000..373a977
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IMediaQuality.aidl
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.AmbientBacklightSettings;
+import android.hardware.tv.mediaquality.IMediaQualityCallback;
+import android.hardware.tv.mediaquality.IPictureProfileAdjustmentListener;
+import android.hardware.tv.mediaquality.IPictureProfileChangedListener;
+import android.hardware.tv.mediaquality.ISoundProfileAdjustmentListener;
+import android.hardware.tv.mediaquality.ISoundProfileChangedListener;
+import android.hardware.tv.mediaquality.ParamCapability;
+import android.hardware.tv.mediaquality.ParameterName;
+import android.hardware.tv.mediaquality.PictureParameters;
+import android.hardware.tv.mediaquality.SoundParameters;
+import android.hardware.tv.mediaquality.VendorParamCapability;
+import android.hardware.tv.mediaquality.VendorParameterIdentifier;
+
+/**
+ * Interface for the media quality service
+ */
+@VintfStability
+interface IMediaQuality {
+    /**
+     * Sets a callback for events.
+     *
+     * @param callback Callback object to pass events.
+     */
+    void setCallback(in IMediaQualityCallback callback);
+
+    /**
+     * Sets the ambient backlight detector settings.
+     *
+     * @param settings Ambient backlight detector settings.
+     */
+    void setAmbientBacklightDetector(in AmbientBacklightSettings settings);
+
+    /**
+     * Sets the ambient backlight detection enabled or disabled. The ambient backlight is the
+     * projection of light against the wall driven by the current content playing. Enable will
+     * detects the Ambient backlight metadata and ambient control app can control the related
+     * device as configured before.
+     *
+     * @param enabled True to enable the ambient backlight detection, false to disable.
+     */
+    void setAmbientBacklightDetectionEnabled(in boolean enabled);
+
+    /**
+     * Gets the ambient backlight detection enabled status. The ambient backlight is enabled by
+     * calling setAmbientBacklightDetectionEnabled(in boolean enabled). True to enable the
+     * ambient light detection and False to disable the ambient backlight detection.
+     *
+     * @return True if the ambient backlight detection is enabled, false otherwise.
+     */
+    boolean getAmbientBacklightDetectionEnabled();
+
+    /**
+     * Check if auto picture quality feature is supported on the current TV device.
+     *
+     * @return true when the device supports the auto picture quality, false when the device does
+     * not supports the auto picture quality.
+     */
+    boolean isAutoPqSupported();
+
+    /**
+     * Get the current state of auto picture quality.
+     *
+     * @return true when auto picture quality is enabled, false when auto picture quality is
+     * disabled.
+     */
+    boolean getAutoPqEnabled();
+
+    /**
+     * Set the auto picture quality enable/disable. Auto picture quality is to adjust the Picture
+     * parameters depends on the current content playing.
+     *
+     * @param enable True to enable, false to disable.
+     */
+    void setAutoPqEnabled(boolean enable);
+
+    /**
+     * Check if auto super resolution feature is supported on the current TV device.
+     *
+     * @return true when the device supports the super resolution feature, false when the device
+     * does not support super resolution.
+     */
+    boolean isAutoSrSupported();
+
+    /**
+     * Get the current state of auto super resolution.
+     *
+     * @return true when auto super resolution is enabled, false when auto super resolution is
+     * disabled.
+     */
+    boolean getAutoSrEnabled();
+
+    /**
+     * Set the auto super resolution enable/disable. Auto super resolution is to analyze the
+     * lower resolution image and invent the missing pixel to make the image looks sharper.
+     *
+     * @param enable True to enable, false to disable.
+     */
+    void setAutoSrEnabled(boolean enable);
+
+    /**
+     * Check if auto sound/audio quality feature is supported on the current TV device.
+     *
+     * @return true when the device supports the auto sound/audio quality, false when
+     * the device does not supports the auto sound/audio quality.
+     */
+    boolean isAutoAqSupported();
+
+    /**
+     * Get the current state of auto sound/audio quality.
+     *
+     * @return true when auto sound/audio quality is enabled, false when auto sound/audio
+     * quality is disabled.
+     */
+    boolean getAutoAqEnabled();
+
+    /**
+     * Set the auto sound/audio quality enable/disable. Auto sound/audio quality is to
+     * adjust the sound parameters depends on the current content playing.
+     *
+     * @param enable True to enable, false to disable.
+     */
+    void setAutoAqEnabled(boolean enable);
+
+    /**
+     * Get picture profile changed listener.
+     *
+     * @return the IPictureProfileChangedListener.
+     */
+    IPictureProfileChangedListener getPictureProfileListener();
+
+    /**
+     * Sets the listener for picture adjustment from the HAL.
+     *
+     * When the same client registers this listener multiple times, only the most recent
+     * registration will be active. The previous listener will be overwritten.
+     *
+     * When different client registers this listener, it will overwrite the previous registered
+     * client. Only one listener can be active.
+     *
+     * @param IPictureProfileAdjustmentListener listener object to pass picture profile, profile
+     *        id and hardware capability.
+     */
+    void setPictureProfileAdjustmentListener(IPictureProfileAdjustmentListener listener);
+
+    /**
+     * Send the default picture parameters to the vendor code or HAL to apply the picture
+     * parameters.
+     *
+     * @param pictureParameters PictureParameters with pre-defined parameters and vendor defined
+     * parameters.
+     */
+    void sendDefaultPictureParameters(in PictureParameters pictureParameters);
+
+    /**
+     * Get sound profile changed listener.
+     *
+     * @return the ISoundProfileChangedListener.
+     */
+    ISoundProfileChangedListener getSoundProfileListener();
+
+    /**
+     * Sets the listener for sound adjustment from the HAL.
+     *
+     * When the same client registers this listener multiple times, only the most recent
+     * registration will be active. The previous listener will be overwritten.
+     *
+     * When different client registers this listener, it will overwrite the previous registered
+     * client. Only one listener can be active.
+     *
+     * @param ISoundProfileAdjustmentListener listener object to pass sound profile, profile id
+     *        and hardware capability.
+     */
+    void setSoundProfileAdjustmentListener(ISoundProfileAdjustmentListener listener);
+
+    /**
+     * Send the default sound parameters to the vendor code or HAL to apply the sound parameters.
+     *
+     * @param soundParameters SoundParameters with pre-defined parameters and vendor defined
+     * parameters.
+     */
+    void sendDefaultSoundParameters(in SoundParameters soundParameters);
+
+    /**
+     * Gets capability information of the given parameters.
+     */
+    void getParamCaps(in ParameterName[] paramNames, out ParamCapability[] caps);
+
+    /**
+     * Gets vendor capability information of the given parameters.
+     */
+    void getVendorParamCaps(in VendorParameterIdentifier[] names, out VendorParamCapability[] caps);
+
+    /**
+     * When HAL request picture parameters by picture profile id, the framework will use this to
+     * send the picture parameters associate with the profile id.
+     *
+     * @param pictureParameters pictureParameters that associate with the profile id HAL provided.
+     */
+    void sendPictureParameters(in PictureParameters pictureParameters);
+
+    /**
+     * When HAL request sound parameters by sound profile id, the framework will use this to
+     * send the sound parameters associate with the profile id.
+     *
+     * @param soundParameters soundParameters that associate with the profile id HAL provided.
+     */
+    void sendSoundParameters(in SoundParameters soundParameters);
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IMediaQualityCallback.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IMediaQualityCallback.aidl
new file mode 100644
index 0000000..31ab255
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IMediaQualityCallback.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.AmbientBacklightEvent;
+
+@VintfStability
+oneway interface IMediaQualityCallback {
+    /**
+     * Notifies the client that an ambient backlight event has occurred. For possible
+     * event types, check AmbientBacklightEventType.
+     *
+     * @param event Event passed to the client.
+     */
+    void notifyAmbientBacklightEvent(in AmbientBacklightEvent event);
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IPictureProfileAdjustmentListener.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IPictureProfileAdjustmentListener.aidl
new file mode 100644
index 0000000..06651e4
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IPictureProfileAdjustmentListener.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.ParamCapability;
+import android.hardware.tv.mediaquality.PictureProfile;
+import android.hardware.tv.mediaquality.VendorParamCapability;
+
+@VintfStability
+oneway interface IPictureProfileAdjustmentListener {
+    /**
+     * Notifies Media Quality Manager when the picture profile changed.
+     *
+     * @param pictureProfile Picture profile.
+     */
+    void onPictureProfileAdjusted(in PictureProfile pictureProfile);
+
+    /**
+     * Notifies Media Quality Manager when parameter capabilities changed.
+     *
+     * @param pictureProfileId the ID of the profile used by the media content. -1 if there
+     *                         is no associated profile.
+     * @param caps the updated capabilities.
+     */
+    void onParamCapabilityChanged(long pictureProfileId, in ParamCapability[] caps);
+
+    /**
+     * Notifies Media Quality Manager when vendor parameter capabilities changed.
+     *
+     * <p>This should be also called when the listener is registered to let the client know
+     * what vendor parameters are supported.
+     *
+     * @param pictureProfileId the ID of the profile used by the media content. -1 if there
+     *                         is no associated profile.
+     * @param caps the updated vendor capabilities.
+     */
+    void onVendorParamCapabilityChanged(long pictureProfileId, in VendorParamCapability[] caps);
+
+    /**
+     * Request the picture parameters by picture profile id. Check PictureParameters for its detail.
+     * This is called from the HAL to media quality framework.
+     *
+     * The requested picture parameters will get from IMediaQuality::sendPictureParameters called
+     * by the framework.
+     *
+     * @param pictureProfileId The PictureProfile id that associate with the PictureProfile.
+     */
+    void onRequestPictureParameters(long pictureProfileId);
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IPictureProfileChangedListener.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IPictureProfileChangedListener.aidl
new file mode 100644
index 0000000..35112e1
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/IPictureProfileChangedListener.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.PictureProfile;
+
+@VintfStability
+oneway interface IPictureProfileChangedListener {
+    /**
+     * Notifies the composer HAL that the picture profile has changed. For picture profile details,
+     * check PictureProfile.
+     *
+     * @param pictureProfile Picture profile passed to the composer HAL.
+     */
+    void onPictureProfileChanged(in PictureProfile pictureProfile);
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ISoundProfileAdjustmentListener.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ISoundProfileAdjustmentListener.aidl
new file mode 100644
index 0000000..2ab9c6c
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ISoundProfileAdjustmentListener.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.ParamCapability;
+import android.hardware.tv.mediaquality.SoundProfile;
+import android.hardware.tv.mediaquality.VendorParamCapability;
+
+@VintfStability
+oneway interface ISoundProfileAdjustmentListener {
+    /**
+     * Notifies Media Quality Manager when the sound profile changed.
+     *
+     * @param soundProfile Sound profile.
+     */
+    void onSoundProfileAdjusted(in SoundProfile soundProfile);
+
+    /**
+     * Notifies Media Quality Manager when parameter capabilities changed.
+     *
+     * @param soundProfileId the ID of the profile used by the media content. -1 if there
+     *                         is no associated profile.
+     * @param caps the updated capabilities.
+     */
+    void onParamCapabilityChanged(long soundProfileId, in ParamCapability[] caps);
+
+    /**
+     * Notifies Media Quality Manager when vendor parameter capabilities changed.
+     *
+     * <p>This should be also called when the listener is registered to let the client know
+     * what vendor parameters are supported.
+     *
+     * @param soundProfileId the ID of the profile used by the media content. -1 if there
+     *                         is no associated profile.
+     * @param caps the updated vendor capabilities.
+     */
+    void onVendorParamCapabilityChanged(long soundProfileId, in VendorParamCapability[] caps);
+
+    /**
+     * Request the sound parameters by sound profile id. Check SoundParameters for its detail.
+     * This is called from the HAL to media quality framework.
+     *
+     * The requested sound parameters will get from IMediaQuality::sendSoundParameters called
+     * by the framework.
+     *
+     * @param SoundProfileId The SoundProfile id that associate with the SoundProfile.
+     */
+    void onRequestSoundParameters(long SoundProfileId);
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ISoundProfileChangedListener.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ISoundProfileChangedListener.aidl
new file mode 100644
index 0000000..cb2d75e
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ISoundProfileChangedListener.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.SoundProfile;
+
+@VintfStability
+oneway interface ISoundProfileChangedListener {
+    /**
+     * Notifies the audio HAL that the sound profile has changed. For sound profile details,
+     * check SoundProfile.
+     *
+     * @param soundProfile Sound profile passed to the audio HAL.
+     */
+    void onSoundProfileChanged(in SoundProfile soundProfile);
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/NumberRange.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/NumberRange.aidl
new file mode 100644
index 0000000..94a041c
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/NumberRange.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+/** Parameter supported number range **/
+@VintfStability
+union NumberRange {
+    /** Min value and max value of an int parameter. Inclusive. */
+    @nullable int[2] intMinMax;
+    /** Min value and max value of a long parameter. Inclusive. */
+    @nullable long[2] longMinMax;
+    /** Min value and max value of a double parameter. Inclusive. */
+    @nullable double[2] doubleMinMax;
+
+    /** An array of supported int values. */
+    @nullable int[] intValuesSupported;
+    /** An array of supported long values. */
+    @nullable long[] longValuesSupported;
+    /** An array of supported double values. */
+    @nullable double[] doubleValuesSupported;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParamCapability.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParamCapability.aidl
new file mode 100644
index 0000000..933a1a3
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParamCapability.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.ParameterDefaultValue;
+import android.hardware.tv.mediaquality.ParameterName;
+import android.hardware.tv.mediaquality.ParameterRange;
+/**
+ * Capability of parameters.
+ */
+@VintfStability
+parcelable ParamCapability {
+    /** Name of the parameter **/
+    ParameterName name;
+
+    /** true if this parameter is supported **/
+    boolean isSupported;
+
+    /**
+     * Default value of this parameter. null if there is no default value.
+     */
+    @nullable ParameterDefaultValue defaultValue;
+
+    /**
+     * The supported range of this parameter. null if there is no specific range.
+     */
+    @nullable ParameterRange range;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterDefaultValue.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterDefaultValue.aidl
new file mode 100644
index 0000000..3827134
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterDefaultValue.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+/** Parameter default value **/
+@VintfStability
+union ParameterDefaultValue {
+    int intDefault;
+    long longDefault;
+    double doubleDefault;
+    String stringDefault;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterName.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterName.aidl
new file mode 100644
index 0000000..0a3c97b
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterName.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+/**
+ * Parameter names.
+ * <p>Details of the parameters can be found at
+ * android.hardware.tv.mediaquality.PictureParameter and
+ * android.hardware.tv.mediaquality.SoundParameter.
+ */
+@VintfStability
+enum ParameterName {
+    BRIGHTNESS,
+    CONTRAST,
+    SHARPNESS,
+    SATURATION,
+    HUE,
+    COLOR_TUNER_BRIGHTNESS,
+    COLOR_TUNER_SATURATION,
+    COLOR_TUNER_HUE,
+    COLOR_TUNER_RED_OFFSET,
+    COLOR_TUNER_GREEN_OFFSET,
+    COLOR_TUNER_BLUE_OFFSET,
+    COLOR_TUNER_RED_GAIN,
+    COLOR_TUNER_GREEN_GAIN,
+    COLOR_TUNER_BLUE_GAIN,
+    NOISE_REDUCTION,
+    MPEG_NOISE_REDUCTION,
+    FLASH_TONE,
+    DE_CONTOUR,
+    DYNAMIC_LUMA_CONTROL,
+    FILM_MODE,
+    BLACK_STRETCH,
+    BLUE_STRETCH,
+    COLOR_TUNE,
+    COLOR_TEMPERATURE,
+    GLOBE_DIMMING,
+    AUTO_PICTUREQUALITY_ENABLED,
+    AUTO_SUPER_RESOLUTION_ENABLED,
+
+    BALANCE,
+    BASS,
+    TREBLE,
+    SURROUND_SOUND_ENABLED,
+    EQUALIZER_DETAIL,
+    SPEAKERS_ENABLED,
+    SPEAKERS_DELAY_MS,
+    ENHANCED_AUDIO_RETURN_CHANNEL_ENABLED,
+    AUTO_VOLUME_CONTROL,
+    DOWNMIX_MODE,
+    DTS_DRC,
+    DOLBY_AUDIO_PROCESSING,
+    DOLBY_DIALOGUE_ENHANCER,
+    DTS_VIRTUAL_X,
+    DIGITAL_OUTPUT,
+    DIGITAL_OUTPUT_DELAY_MS,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterRange.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterRange.aidl
new file mode 100644
index 0000000..836b5b8
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/ParameterRange.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.NumberRange;
+
+/** Parameter supported range **/
+@VintfStability
+parcelable ParameterRange {
+    /** Supported number range */
+    NumberRange numRange;
+
+    /** Supported vendor-defined values **/
+    ParcelableHolder vendorDefinedValues;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureParameter.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureParameter.aidl
new file mode 100644
index 0000000..b7f2a11
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureParameter.aidl
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.ColorRange;
+import android.hardware.tv.mediaquality.ColorSpace;
+import android.hardware.tv.mediaquality.ColorTemperature;
+import android.hardware.tv.mediaquality.Gamma;
+import android.hardware.tv.mediaquality.QualityLevel;
+
+/**
+ * The parameters for Picture Profile.
+ */
+@VintfStability
+union PictureParameter {
+    /*
+     * Brightness field represents the brightness level of the TV.
+     * Brightness value range are from 0.0 to 1.0, where 0.0 represents the minimum brightness and
+     * 1.0 represents the maximum brightness. The content-unmodified value is 0.5.
+     *
+     * note: when a picture profile is applied to the entire display, the media quality framework
+     * will synchronize the brightness field.
+     */
+    float brightness;
+
+    /*
+     * This value represents the image contrast on an arbitrary scale from 0 to 100,
+     * where 0 represents the darkest black (black screen) and 100 represents the brightest
+     * white (brighter).
+     * The default/unmodified value for contrast is 50.
+     */
+    int contrast;
+
+    /*
+     * Control that increases edge contrast so that objects become more distinct.
+     * Sharpness value range are from 0 to 100, where 0 represents the minimum sharpness that
+     * makes the image appear softer with less defined edges, 100 represents the maximum
+     * sharpness that makes the image appear halos around objects due to excessive edges.
+     * The default/unmodified value for sharpness is 50.
+     */
+    int sharpness;
+
+    /*
+     * Saturation value controls the intensity or purity of colors.
+     * Saturation values are from 0 to 100, where 0 represents grayscale (no color) and 100
+     * represents the most vivid colors.
+     * The default/unmodified value for saturation is 50.
+     */
+    int saturation;
+
+    /*
+     * Hue affects the balance between red, green and blue primary colors on the screen.
+     * Hue values are from -50 to 50, where -50 represents cooler and 50 represents warmer.
+     * The default/unmodified value for hue is 0.
+     */
+    int hue;
+
+    /*
+     * Adjust brightness in advance color engine. Similar to a "brightness" control on a TV
+     * but acts at a lower level.
+     *
+     * The range is from 0 to 100, where 0 represents the minimum brightness and 100 represents
+     * the maximum brightness. The default/unmodified value is 50.
+     */
+    int colorTunerBrightness;
+
+    /*
+     * Adjust saturation in advance color engine. Similar to a "saturation" control on a TV
+     * but acts at a lower level.
+     *
+     * The range is from 0 to 100, where 0 being completely desaturated/grayscale and 100 being
+     * the most saturated. The default/unmodified value is 50.
+     */
+    int colorTunerSaturation;
+
+    /*
+     * Adjust hue in advance color engine. Similar to a "hue" control on a TV but acts at a lower
+     * level.
+     *
+     * The range is from -50 to 50, where -50 represents cooler setting for a specific color and 50
+     * represents warmer setting for a specific color. The default/unmodified value is 0.
+     */
+    int colorTunerHue;
+
+    /*
+     * Advance setting for red offset. Adjust the black level of red color channels, it control
+     * the minimum intensity of each color, affecting the shadows and dark areas of the image.
+     *
+     * The range is from 0 to 100, where 0 makes shadows darker and 100 makes shadows brighter.
+     * The default/unmodified value is 50.
+     */
+    int colorTunerRedOffset;
+
+    /*
+     * Advance setting for green offset. Adjust the black level of green color channels, it control
+     * the minimum intensity of each color, affecting the shadows and dark areas of the image.
+     *
+     * The range is from 0 to 100, where 0 makes shadows darker and 100 makes shadows brighter.
+     * The default/unmodified value is 50.
+     */
+    int colorTunerGreenOffset;
+
+    /*
+     * Advance setting for blue offset. Adjust the black level of blue color channels, it control
+     * the minimum intensity of each color, affecting the shadows and dark areas of the image.
+     *
+     * The range is from 0 to 100, where 0 makes shadows darker and 100 makes shadows brighter.
+     * The default/unmodified value is 50.
+     */
+    int colorTunerBlueOffset;
+
+    /*
+     * Advance setting for red gain. Adjust the gain or amplification of the red color channels.
+     * They control the overall intensity and white balance of red.
+     *
+     * The range is from 0 to 100, where 0 makes the red dimmer and 100 makes the red brighter.
+     * The default/unmodified value is 50.
+     */
+    int colorTunerRedGain;
+
+    /*
+     * Advance setting for green gain. Adjust the gain or amplification of the green color channels.
+     * They control the overall intensity and white balance of green.
+     *
+     * The range is from 0 to 100, where 0 makes the green dimmer and 100 makes the green brighter.
+     * The default/unmodified value is 50.
+     */
+    int colorTunerGreenGain;
+
+    /*
+     * Advance setting for blue gain. Adjust the gain or amplification of the blue color channels.
+     * They control the overall intensity and white balance of blue.
+     *
+     * The range is from 0 to 100, where 0 makes the blue dimmer and 100 makes the blue brighter.
+     * The default/unmodified value is 50.
+     */
+    int colorTunerBlueGain;
+
+    /* Noise reduction. (Off, Low, Medium, High) */
+    QualityLevel noiseReduction;
+
+    /* MPEG (moving picture experts group) noise reduction (Off, Low, Medium, High) */
+    QualityLevel mpegNoiseReduction;
+
+    /*
+     * Refine the flesh colors in the pictures without affecting the other colors on the screen.
+     * (Off, Low, Medium, High)
+     */
+    QualityLevel fleshTone;
+
+    /* Contour noise reduction. (Off, Low, Medium, High) */
+    QualityLevel deContour;
+
+    /* Dynamically change picture luma to enhance contrast. (Off, Low, Medium, High) */
+    QualityLevel dynamicLumaControl;
+
+    /* Enable/disable film mode */
+    boolean filmMode;
+
+    /* Enable/disable blue color auto stretch */
+    boolean blueStretch;
+
+    /* Enable/disable the overall color tuning feature. */
+    boolean colorTune;
+
+    /* Adjust color temperature type */
+    ColorTemperature colorTemperature;
+
+    /* Enable/disable globe dimming. */
+    boolean globeDimming;
+
+    /* Enable/disable auto adjust picture parameter based on the TV content. */
+    boolean autoPictureQualityEnabled;
+
+    /*
+     * Enable/disable auto upscaling the picture quality. It analyzes the lower-resolution
+     * image and uses its knowledge to invent the missing pixel, make the image look sharper.
+     */
+    boolean autoSuperResolutionEnabled;
+
+    /**
+     * The color range of the content. This indicates the range of luminance values
+     * used in the video signal.
+     */
+    ColorRange levelRange;
+
+    /**
+     * Enable/disable gamut mapping. Gamut mapping is a process that adjusts
+     * the colors in the video signal to match the color gamut of the display.
+     */
+    boolean gamutMapping;
+
+    /**
+     * Enable/disable PC mode. PC mode is a display mode that is optimized for
+     * use with computers.
+     */
+    boolean pcMode;
+
+    /**
+     * Enable/disable low latency mode. Low latency mode reduces the delay
+     * between the video source and the display.
+     */
+    boolean lowLatency;
+
+    /**
+     * Enable/disable variable refresh rate (VRR) mode. VRR allows the display to
+     * dynamically adjust its refresh rate to match the frame rate of the video
+     * source, reducing screen tearing.
+     */
+    boolean vrr;
+
+    /**
+     * Enable/disable continuous variable refresh rate (CVRR) mode. CVRR is a type
+     * of VRR that allows for a wider range of refresh rates.
+     */
+    boolean cvrr;
+
+    /**
+     * The color range of the HDMI input. This indicates the range of luminance
+     * values used in the HDMI signal.
+     */
+    ColorRange hdmiRgbRange;
+
+    /**
+     * The color space of the content. This indicates the color gamut and
+     * transfer function used in the video signal.
+     */
+    ColorSpace colorSpace;
+
+    /**
+     * The initial maximum luminance of the panel, in nits.
+     */
+    int panelInitMaxLuminceNits;
+
+    /**
+     * Whether the initial maximum luminance value is valid.
+     */
+    boolean panelInitMaxLuminceValid;
+
+    /* The gamma curve used for the display. */
+    Gamma gamma;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureParameters.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureParameters.aidl
new file mode 100644
index 0000000..e5f6b83
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureParameters.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.PictureParameter;
+
+/**
+ * The pre-defined parameters and vendor parameters for Picture Profile.
+ */
+@VintfStability
+parcelable PictureParameters {
+    /* Pre-defined picture parameters. */
+    PictureParameter[] pictureParameters;
+
+    /* Vendor defined picture parameters. */
+    ParcelableHolder vendorPictureParameters;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureProfile.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureProfile.aidl
new file mode 100644
index 0000000..7e02350
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/PictureProfile.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.PictureParameters;
+
+/**
+ * Picture profile that includes all the parameters.
+ */
+@VintfStability
+parcelable PictureProfile {
+    long pictureProfileId;
+
+    /* Picture parameters that associate with the id. */
+    PictureParameters parameters;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/QualityLevel.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/QualityLevel.aidl
new file mode 100644
index 0000000..e0171ca
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/QualityLevel.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+@VintfStability
+enum QualityLevel {
+    OFF,
+    LOW,
+    MEDIUM,
+    HIGH,
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundParameter.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundParameter.aidl
new file mode 100644
index 0000000..4714ad2
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundParameter.aidl
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.DigitalOutput;
+import android.hardware.tv.mediaquality.DolbyAudioProcessing;
+import android.hardware.tv.mediaquality.DownmixMode;
+import android.hardware.tv.mediaquality.DtsVirtualX;
+import android.hardware.tv.mediaquality.EqualizerDetail;
+import android.hardware.tv.mediaquality.QualityLevel;
+
+/**
+ * The parameters for Sound Profile.
+ */
+@VintfStability
+union SoundParameter {
+    /*
+     * This parameter controls the balance between the left and tight speakers.
+     * The valid range is -50 to 50, where:
+     *   - Negative values shift the balance towards the left speaker.
+     *   - Positive values shift the balance towards the right speaker.
+     *   - 0 represents a balanced output.
+     */
+    int balance;
+
+    /*
+     * Bass controls the intensity of low-frequency sounds.
+     * The valid range is 0 - 100.
+     */
+    int bass;
+
+    /*
+     * Treble controls the intensity of high-frequency sounds.
+     * The valid range is 0 - 100.
+     */
+    int treble;
+
+    /* Enable surround sound. */
+    boolean surroundSoundEnabled;
+
+    /*
+     * Equalizer can fine-tune the audio output by adjusting the loudness of different
+     * frequency bands;
+     * The frequency bands are 120Hz, 500Hz, 1.5kHz, 5kHz, 10kHz.
+     * Each band have a value of -50 to 50.
+     */
+    EqualizerDetail equalizerDetail;
+
+    /* Enable speaker output. */
+    boolean speakersEnabled;
+
+    /* Speaker delay in ms. */
+    int speakersDelayMs;
+
+    /* eARC allows for higher bandwidth audio transmission over HDMI */
+    boolean enhancedAudioReturnChannelEnabled;
+
+    /* Enable auto volume control sound effect. */
+    boolean autoVolumeControl;
+
+    /* Enable downmix mode. */
+    DownmixMode downmixMode;
+
+    /* Enable dynamic range compression */
+    boolean dtsDrc;
+
+    /* Sound effects from Dobly */
+    @nullable DolbyAudioProcessing dolbyAudioProcessing;
+
+    /* Sound effect from Dolby. */
+    QualityLevel dolbyDialogueEnhancer;
+
+    /* Sound effect from DTS. */
+    @nullable DtsVirtualX dtsVirtualX;
+
+    /* Digital output mode. */
+    DigitalOutput digitalOutput;
+
+    /* Digital output delay in ms. */
+    int digitalOutputDelayMs;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundParameters.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundParameters.aidl
new file mode 100644
index 0000000..2fe0ce7
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundParameters.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.SoundParameter;
+
+/**
+ * The pre-defined parameters and vendor parameters for Sound Profile.
+ */
+@VintfStability
+parcelable SoundParameters {
+    /* Pre-defined sound parameters. */
+    SoundParameter[] soundParameters;
+
+    /* Vendor defined sound parameters. */
+    ParcelableHolder vendorSoundParameters;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundProfile.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundProfile.aidl
new file mode 100644
index 0000000..27628eb
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/SoundProfile.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.SoundParameters;
+
+/**
+ * Sound profile that includes all the parameters.
+ */
+@VintfStability
+parcelable SoundProfile {
+    long soundProfileId;
+
+    /* Sound parameters that associate with the id. */
+    SoundParameters parameters;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/VendorParamCapability.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/VendorParamCapability.aidl
new file mode 100644
index 0000000..bdc0188
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/VendorParamCapability.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+import android.hardware.tv.mediaquality.ParameterDefaultValue;
+import android.hardware.tv.mediaquality.ParameterRange;
+import android.hardware.tv.mediaquality.VendorParameterIdentifier;
+
+/**
+ * Capability of vendor parameters.
+ */
+@VintfStability
+parcelable VendorParamCapability {
+    /** Identifier of the parameter **/
+    VendorParameterIdentifier identifier;
+
+    /** true if this parameter is supported **/
+    boolean isSupported;
+
+    /**
+     * Default value of this parameter. null if there is no default value.
+     */
+    @nullable ParameterDefaultValue defaultValue;
+
+    /**
+     * The supported range of this parameter. null if there is no specific range.
+     */
+    @nullable ParameterRange range;
+}
diff --git a/tv/mediaquality/aidl/android/hardware/tv/mediaquality/VendorParameterIdentifier.aidl b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/VendorParameterIdentifier.aidl
new file mode 100644
index 0000000..f974b16
--- /dev/null
+++ b/tv/mediaquality/aidl/android/hardware/tv/mediaquality/VendorParameterIdentifier.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.mediaquality;
+
+/**
+ * Identifier of vendor parameters.
+ */
+@VintfStability
+parcelable VendorParameterIdentifier {
+    /** Identifier of the parameter **/
+    ParcelableHolder identifier;
+}
diff --git a/tv/mediaquality/aidl/default/Android.bp b/tv/mediaquality/aidl/default/Android.bp
new file mode 100644
index 0000000..e25b01f
--- /dev/null
+++ b/tv/mediaquality/aidl/default/Android.bp
@@ -0,0 +1,24 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+rust_binary {
+    name: "android.hardware.tv.mediaquality-service.example",
+    relative_install_path: "hw",
+    init_rc: ["mediaquality-default.rc"],
+    vintf_fragments: ["mediaquality-default.xml"],
+    vendor: true,
+    rustlibs: [
+        "libandroid_logger",
+        "liblogger",
+        "liblog_rust",
+        "libbinder_rs",
+        "android.hardware.tv.mediaquality-V1-rust",
+    ],
+    srcs: ["main.rs"],
+}
diff --git a/tv/mediaquality/aidl/default/hal/media_quality_hal_impl.rs b/tv/mediaquality/aidl/default/hal/media_quality_hal_impl.rs
new file mode 100644
index 0000000..1946cec
--- /dev/null
+++ b/tv/mediaquality/aidl/default/hal/media_quality_hal_impl.rs
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+//! This module implements the IMediaQuality AIDL interface.
+
+use android_hardware_tv_mediaquality::aidl::android::hardware::tv::mediaquality::{
+    IMediaQuality::IMediaQuality,
+    IMediaQualityCallback::IMediaQualityCallback,
+    AmbientBacklightEvent::AmbientBacklightEvent,
+    AmbientBacklightSettings::AmbientBacklightSettings,
+    IPictureProfileAdjustmentListener::IPictureProfileAdjustmentListener,
+    IPictureProfileChangedListener::IPictureProfileChangedListener,
+    ParamCapability::ParamCapability,
+    ParameterName::ParameterName,
+    PictureParameters::PictureParameters,
+    ISoundProfileAdjustmentListener::ISoundProfileAdjustmentListener,
+    ISoundProfileChangedListener::ISoundProfileChangedListener,
+    SoundParameters::SoundParameters,
+    VendorParamCapability::VendorParamCapability,
+    VendorParameterIdentifier::VendorParameterIdentifier,
+};
+use binder::{Interface, Strong};
+use std::sync::{Arc, Mutex};
+use std::thread;
+
+/// Defined so we can implement the IMediaQuality AIDL interface.
+pub struct MediaQualityService {
+    callback: Arc<Mutex<Option<Strong<dyn IMediaQualityCallback>>>>,
+    ambient_backlight_enabled: Arc<Mutex<bool>>,
+    ambient_backlight_detector_settings: Arc<Mutex<AmbientBacklightSettings>>,
+    auto_pq_supported: Arc<Mutex<bool>>,
+    auto_pq_enabled: Arc<Mutex<bool>>,
+    auto_sr_supported: Arc<Mutex<bool>>,
+    auto_sr_enabled: Arc<Mutex<bool>>,
+    auto_aq_supported: Arc<Mutex<bool>>,
+    auto_aq_enabled: Arc<Mutex<bool>>,
+    picture_profile_adjustment_listener:
+            Arc<Mutex<Option<Strong<dyn IPictureProfileAdjustmentListener>>>>,
+    sound_profile_adjustment_listener:
+            Arc<Mutex<Option<Strong<dyn ISoundProfileAdjustmentListener>>>>,
+    picture_profile_changed_listener: Arc<Mutex<Option<Strong<dyn IPictureProfileChangedListener>>>>,
+    sound_profile_changed_listener: Arc<Mutex<Option<Strong<dyn ISoundProfileChangedListener>>>>,
+}
+
+impl MediaQualityService {
+
+    /// Create a new instance of the MediaQualityService.
+    pub fn new() -> Self {
+        Self {
+            callback: Arc::new(Mutex::new(None)),
+            ambient_backlight_enabled: Arc::new(Mutex::new(true)),
+            ambient_backlight_detector_settings:
+                    Arc::new(Mutex::new(AmbientBacklightSettings::default())),
+            auto_pq_supported: Arc::new(Mutex::new(false)),
+            auto_pq_enabled: Arc::new(Mutex::new(false)),
+            auto_sr_supported: Arc::new(Mutex::new(false)),
+            auto_sr_enabled: Arc::new(Mutex::new(false)),
+            auto_aq_supported: Arc::new(Mutex::new(false)),
+            auto_aq_enabled: Arc::new(Mutex::new(false)),
+            picture_profile_adjustment_listener: Arc::new(Mutex::new(None)),
+            sound_profile_adjustment_listener: Arc::new(Mutex::new(None)),
+            picture_profile_changed_listener: Arc::new(Mutex::new(None)),
+            sound_profile_changed_listener: Arc::new(Mutex::new(None)),
+        }
+    }
+}
+
+impl Interface for MediaQualityService {}
+
+impl IMediaQuality for MediaQualityService {
+
+    fn setCallback(
+        &self,
+        callback: &Strong<dyn IMediaQualityCallback>
+    ) -> binder::Result<()> {
+        println!("Received callback: {:?}", callback);
+        let mut cb = self.callback.lock().unwrap();
+        *cb = Some(callback.clone());
+        Ok(())
+    }
+
+    fn setAmbientBacklightDetector(
+        &self,
+        settings: &AmbientBacklightSettings
+    ) -> binder::Result<()> {
+        println!("Received settings: {:?}", settings);
+        let mut ambient_backlight_detector_settings = self.ambient_backlight_detector_settings.lock().unwrap();
+        ambient_backlight_detector_settings.packageName = settings.packageName.clone();
+        ambient_backlight_detector_settings.source = settings.source;
+        ambient_backlight_detector_settings.maxFramerate = settings.maxFramerate;
+        ambient_backlight_detector_settings.colorFormat = settings.colorFormat;
+        ambient_backlight_detector_settings.hZonesNumber = settings.hZonesNumber;
+        ambient_backlight_detector_settings.vZonesNumber = settings.vZonesNumber;
+        ambient_backlight_detector_settings.hasLetterbox = settings.hasLetterbox;
+        ambient_backlight_detector_settings.threshold = settings.threshold;
+        Ok(())
+    }
+
+    fn setAmbientBacklightDetectionEnabled(&self, enabled: bool) -> binder::Result<()> {
+        println!("Received enabled: {}", enabled);
+        let mut ambient_backlight_enabled = self.ambient_backlight_enabled.lock().unwrap();
+        *ambient_backlight_enabled = enabled;
+        if enabled {
+            println!("Enable Ambient Backlight detection");
+            thread::scope(|s| {
+                s.spawn(|| {
+                    let cb = self.callback.lock().unwrap();
+                    if let Some(cb) = &*cb {
+                        let enabled_event = AmbientBacklightEvent::Enabled(true);
+                        cb.notifyAmbientBacklightEvent(&enabled_event).unwrap();
+                    }
+                });
+            });
+        } else {
+            println!("Disable Ambient Backlight detection");
+            thread::scope(|s| {
+                s.spawn(|| {
+                    let cb = self.callback.lock().unwrap();
+                    if let Some(cb) = &*cb {
+                        let disabled_event = AmbientBacklightEvent::Enabled(false);
+                        cb.notifyAmbientBacklightEvent(&disabled_event).unwrap();
+                    }
+                });
+            });
+        }
+        Ok(())
+    }
+
+    fn getAmbientBacklightDetectionEnabled(&self) -> binder::Result<bool> {
+        let ambient_backlight_enabled = self.ambient_backlight_enabled.lock().unwrap();
+        Ok(*ambient_backlight_enabled)
+    }
+
+    fn isAutoPqSupported(&self) -> binder::Result<bool> {
+        let auto_pq_supported = self.auto_pq_supported.lock().unwrap();
+        Ok(*auto_pq_supported)
+    }
+
+    fn getAutoPqEnabled(&self) -> binder::Result<bool> {
+        let auto_pq_enabled = self.auto_pq_enabled.lock().unwrap();
+        Ok(*auto_pq_enabled)
+    }
+
+    fn setAutoPqEnabled(&self, enabled: bool) -> binder::Result<()> {
+        let mut auto_pq_enabled = self.auto_pq_enabled.lock().unwrap();
+        *auto_pq_enabled = enabled;
+        if enabled {
+            println!("Enable auto picture quality");
+        } else {
+            println!("Disable auto picture quality");
+        }
+        Ok(())
+    }
+
+    fn isAutoSrSupported(&self) -> binder::Result<bool> {
+        let auto_sr_supported = self.auto_sr_supported.lock().unwrap();
+        Ok(*auto_sr_supported)
+    }
+
+    fn getAutoSrEnabled(&self) -> binder::Result<bool> {
+        let auto_sr_enabled = self.auto_sr_enabled.lock().unwrap();
+        Ok(*auto_sr_enabled)
+    }
+
+    fn setAutoSrEnabled(&self, enabled: bool) -> binder::Result<()> {
+        let mut auto_sr_enabled = self.auto_sr_enabled.lock().unwrap();
+        *auto_sr_enabled = enabled;
+        if enabled {
+            println!("Enable auto super resolution");
+        } else {
+            println!("Disable auto super resolution");
+        }
+        Ok(())
+    }
+
+    fn isAutoAqSupported(&self) -> binder::Result<bool> {
+        let auto_aq_supported = self.auto_aq_supported.lock().unwrap();
+        Ok(*auto_aq_supported)
+    }
+
+    fn getAutoAqEnabled(&self) -> binder::Result<bool> {
+        let auto_aq_enabled = self.auto_aq_enabled.lock().unwrap();
+        Ok(*auto_aq_enabled)
+    }
+
+    fn setAutoAqEnabled(&self, enabled: bool) -> binder::Result<()> {
+        let mut auto_aq_enabled = self.auto_aq_enabled.lock().unwrap();
+        *auto_aq_enabled = enabled;
+        if enabled {
+            println!("Enable auto audio quality");
+        } else {
+            println!("Disable auto audio quality");
+        }
+        Ok(())
+    }
+
+    fn getPictureProfileListener(&self) -> binder::Result<binder::Strong<dyn IPictureProfileChangedListener>> {
+        println!("getPictureProfileListener");
+        let listener = self.picture_profile_changed_listener.lock().unwrap();
+        listener.clone().ok_or(binder::StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setPictureProfileAdjustmentListener(
+        &self,
+        picture_profile_adjustment_listener: &Strong<dyn IPictureProfileAdjustmentListener>
+    ) -> binder::Result<()> {
+        println!("Received picture profile adjustment");
+        let mut listener = self.picture_profile_adjustment_listener.lock().unwrap();
+        *listener = Some(picture_profile_adjustment_listener.clone());
+        Ok(())
+    }
+
+    fn sendDefaultPictureParameters(&self, _picture_parameters: &PictureParameters) -> binder::Result<()>{
+        println!("Received picture parameters");
+        Ok(())
+    }
+
+    fn getSoundProfileListener(&self) -> binder::Result<binder::Strong<dyn ISoundProfileChangedListener>> {
+        println!("getSoundProfileListener");
+        let listener = self.sound_profile_changed_listener.lock().unwrap();
+        listener.clone().ok_or(binder::StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setSoundProfileAdjustmentListener(
+        &self,
+        sound_profile_adjustment_listener: &Strong<dyn ISoundProfileAdjustmentListener>
+    ) -> binder::Result<()> {
+        println!("Received sound profile adjustment");
+        let mut listener = self.sound_profile_adjustment_listener.lock().unwrap();
+        *listener = Some(sound_profile_adjustment_listener.clone());
+        Ok(())
+    }
+
+    fn sendDefaultSoundParameters(&self, _sound_parameters: &SoundParameters) -> binder::Result<()>{
+        println!("Received sound parameters");
+        Ok(())
+    }
+
+    fn getParamCaps(
+            &self,
+            param_names: &[ParameterName],
+            _caps: &mut Vec<ParamCapability>
+    ) -> binder::Result<()> {
+        println!("getParamCaps. len= {}", param_names.len());
+        Ok(())
+    }
+
+    fn getVendorParamCaps(
+            &self,
+            param_names: &[VendorParameterIdentifier],
+            _caps: &mut Vec<VendorParamCapability>
+    ) -> binder::Result<()> {
+        println!("getVendorParamCaps. len= {}", param_names.len());
+        Ok(())
+    }
+
+    fn sendPictureParameters(&self, _picture_parameters: &PictureParameters) -> binder::Result<()>{
+        println!("Received picture parameters");
+        Ok(())
+    }
+
+    fn sendSoundParameters(&self, _sound_parameters: &SoundParameters) -> binder::Result<()>{
+        println!("Received sound parameters");
+        Ok(())
+    }
+}
diff --git a/tv/mediaquality/aidl/default/hal/mod.rs b/tv/mediaquality/aidl/default/hal/mod.rs
new file mode 100644
index 0000000..5b5d4ac
--- /dev/null
+++ b/tv/mediaquality/aidl/default/hal/mod.rs
@@ -0,0 +1,17 @@
+/*
+ * 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.
+ */
+
+pub mod media_quality_hal_impl;
\ No newline at end of file
diff --git a/tv/mediaquality/aidl/default/main.rs b/tv/mediaquality/aidl/default/main.rs
new file mode 100644
index 0000000..f0cccb4
--- /dev/null
+++ b/tv/mediaquality/aidl/default/main.rs
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+//! This implements the MediaQuality Example Service.
+use android_hardware_tv_mediaquality::aidl::android::hardware::tv::mediaquality::IMediaQuality::{BnMediaQuality, IMediaQuality};
+use binder::BinderFeatures;
+
+mod hal;
+use hal::media_quality_hal_impl::MediaQualityService;
+
+const LOG_TAG: &str = "mediaquality_service_example_rust";
+
+use log::LevelFilter;
+
+fn main() {
+
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag(LOG_TAG)
+            .with_max_level(LevelFilter::Info),
+    );
+
+    let media_quality_service = MediaQualityService::new();
+    let media_quality_service_binder = BnMediaQuality::new_binder(media_quality_service, BinderFeatures::default());
+
+    let service_name = format!("{}/default", MediaQualityService::get_descriptor());
+    binder::add_service(&service_name, media_quality_service_binder.as_binder())
+        .expect("Failed to register service");
+
+    log::info!("MediaQualityHal service is running...");
+
+    binder::ProcessState::join_thread_pool();
+}
diff --git a/tv/mediaquality/aidl/default/mediaquality-default.rc b/tv/mediaquality/aidl/default/mediaquality-default.rc
new file mode 100644
index 0000000..5a103a9
--- /dev/null
+++ b/tv/mediaquality/aidl/default/mediaquality-default.rc
@@ -0,0 +1,4 @@
+service vendor.mediaquality-default /vendor/bin/hw/android.hardware.tv.mediaquality-service.example
+    class hal
+    user nobody
+    group nobody
diff --git a/tv/mediaquality/aidl/default/mediaquality-default.xml b/tv/mediaquality/aidl/default/mediaquality-default.xml
new file mode 100644
index 0000000..865f663
--- /dev/null
+++ b/tv/mediaquality/aidl/default/mediaquality-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.tv.mediaquality</name>
+        <fqname>IMediaQuality/default</fqname>
+    </hal>
+</manifest>
\ No newline at end of file
diff --git a/tv/mediaquality/aidl/vts/functional/Android.bp b/tv/mediaquality/aidl/vts/functional/Android.bp
new file mode 100644
index 0000000..226569e
--- /dev/null
+++ b/tv/mediaquality/aidl/vts/functional/Android.bp
@@ -0,0 +1,42 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_team: "trendy_team_tv_os",
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+    name: "VtsHalMediaQualityTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalMediaQualityTest.cpp"],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "android.hardware.tv.mediaquality-V1-ndk",
+    ],
+    test_suites: [
+        "vts",
+    ],
+}
diff --git a/tv/mediaquality/aidl/vts/functional/VtsHalMediaQualityTest.cpp b/tv/mediaquality/aidl/vts/functional/VtsHalMediaQualityTest.cpp
new file mode 100644
index 0000000..84f798b
--- /dev/null
+++ b/tv/mediaquality/aidl/vts/functional/VtsHalMediaQualityTest.cpp
@@ -0,0 +1,280 @@
+/*
+ * 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.
+ */
+#define LOG_TAG "ambient_backlight_aidl_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/tv/mediaquality/AmbientBacklightEvent.h>
+#include <aidl/android/hardware/tv/mediaquality/AmbientBacklightSettings.h>
+#include <aidl/android/hardware/tv/mediaquality/BnMediaQualityCallback.h>
+#include <aidl/android/hardware/tv/mediaquality/BnPictureProfileAdjustmentListener.h>
+#include <aidl/android/hardware/tv/mediaquality/BnSoundProfileAdjustmentListener.h>
+#include <aidl/android/hardware/tv/mediaquality/IMediaQuality.h>
+#include <aidl/android/hardware/tv/mediaquality/PictureParameter.h>
+#include <aidl/android/hardware/tv/mediaquality/PictureParameters.h>
+#include <aidl/android/hardware/tv/mediaquality/PictureProfile.h>
+#include <aidl/android/hardware/tv/mediaquality/SoundParameter.h>
+#include <aidl/android/hardware/tv/mediaquality/SoundParameters.h>
+#include <aidl/android/hardware/tv/mediaquality/SoundProfile.h>
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <future>
+
+using aidl::android::hardware::graphics::common::PixelFormat;
+using aidl::android::hardware::tv::mediaquality::AmbientBacklightEvent;
+using aidl::android::hardware::tv::mediaquality::AmbientBacklightSettings;
+using aidl::android::hardware::tv::mediaquality::AmbientBacklightSource;
+using aidl::android::hardware::tv::mediaquality::BnMediaQualityCallback;
+using aidl::android::hardware::tv::mediaquality::BnPictureProfileAdjustmentListener;
+using aidl::android::hardware::tv::mediaquality::BnSoundProfileAdjustmentListener;
+using aidl::android::hardware::tv::mediaquality::IMediaQuality;
+using aidl::android::hardware::tv::mediaquality::ParamCapability;
+using aidl::android::hardware::tv::mediaquality::PictureParameter;
+using aidl::android::hardware::tv::mediaquality::PictureParameters;
+using aidl::android::hardware::tv::mediaquality::PictureProfile;
+using aidl::android::hardware::tv::mediaquality::SoundParameter;
+using aidl::android::hardware::tv::mediaquality::SoundParameters;
+using aidl::android::hardware::tv::mediaquality::SoundProfile;
+using aidl::android::hardware::tv::mediaquality::VendorParamCapability;
+using aidl::android::hardware::tv::mediaquality::VendorParameterIdentifier;
+using android::ProcessState;
+using android::String16;
+using ndk::ScopedAStatus;
+using ndk::SpAIBinder;
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
+
+class MediaQualityCallback : public BnMediaQualityCallback {
+  public:
+    explicit MediaQualityCallback(
+            const std::function<void(const AmbientBacklightEvent& event)>& on_hal_event_cb)
+        : on_hal_event_cb_(on_hal_event_cb) {}
+    ScopedAStatus notifyAmbientBacklightEvent(const AmbientBacklightEvent& event) override {
+        on_hal_event_cb_(event);
+        return ScopedAStatus::ok();
+    }
+
+  private:
+    std::function<void(const AmbientBacklightEvent& event)> on_hal_event_cb_;
+};
+
+class PictureProfileAdjustmentListener : public BnPictureProfileAdjustmentListener {
+  public:
+    explicit PictureProfileAdjustmentListener(
+            const std::function<void(const PictureProfile& pictureProfile)>&
+                    on_hal_picture_profile_adjust)
+        : on_hal_picture_profile_adjust_(on_hal_picture_profile_adjust) {}
+    ScopedAStatus onPictureProfileAdjusted(const PictureProfile& pictureProfile) override {
+        on_hal_picture_profile_adjust_(pictureProfile);
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onParamCapabilityChanged(int64_t, const std::vector<ParamCapability>&) override {
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onVendorParamCapabilityChanged(int64_t,
+                                                 const std::vector<VendorParamCapability>&) {
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onRequestPictureParameters(int64_t) { return ScopedAStatus::ok(); }
+
+  private:
+    std::function<void(const PictureProfile& pictureProfile)> on_hal_picture_profile_adjust_;
+};
+
+class SoundProfileAdjustmentListener : public BnSoundProfileAdjustmentListener {
+  public:
+    explicit SoundProfileAdjustmentListener(
+            const std::function<void(const SoundProfile& soundProfile)>&
+                    on_hal_sound_profile_adjust)
+        : on_hal_sound_profile_adjust_(on_hal_sound_profile_adjust) {}
+    ScopedAStatus onSoundProfileAdjusted(const SoundProfile& soundProfile) override {
+        on_hal_sound_profile_adjust_(soundProfile);
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onParamCapabilityChanged(int64_t, const std::vector<ParamCapability>&) override {
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onVendorParamCapabilityChanged(int64_t,
+                                                 const std::vector<VendorParamCapability>&) {
+        return ScopedAStatus::ok();
+    }
+
+    ScopedAStatus onRequestSoundParameters(int64_t) { return ScopedAStatus::ok(); }
+
+  private:
+    std::function<void(const SoundProfile& soundProfile)> on_hal_sound_profile_adjust_;
+};
+
+class MediaQualityAidl : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        mediaquality = IMediaQuality::fromBinder(
+                SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(mediaquality, nullptr);
+    }
+    std::shared_ptr<IMediaQuality> mediaquality;
+};
+
+TEST_P(MediaQualityAidl, TestSetAmbientBacklightDetectionEnabled) {
+    std::promise<void> open_cb_promise;
+    std::future<void> open_cb_future{open_cb_promise.get_future()};
+    std::shared_ptr<MediaQualityCallback> callback =
+            ndk::SharedRefBase::make<MediaQualityCallback>([&open_cb_promise](auto event) {
+                EXPECT_EQ(event.getTag(), AmbientBacklightEvent::Tag::enabled);
+                EXPECT_EQ(event.template get<AmbientBacklightEvent::Tag::enabled>(), true);
+                open_cb_promise.set_value();
+                return ScopedAStatus::ok();
+            });
+    ASSERT_OK(mediaquality->setCallback(callback));
+    ASSERT_OK(mediaquality->setAmbientBacklightDetectionEnabled(true));
+    std::chrono::milliseconds timeout{10000};
+    EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+}
+
+TEST_P(MediaQualityAidl, TestGetAmbientBacklightDetectionEnabled) {
+    bool enabled;
+    ASSERT_OK(mediaquality->getAmbientBacklightDetectionEnabled(&enabled));
+}
+
+TEST_P(MediaQualityAidl, TestSetMediaQualityCallback) {
+    std::shared_ptr<MediaQualityCallback> callback = ndk::SharedRefBase::make<MediaQualityCallback>(
+            [](auto /* event */) { return ScopedAStatus::ok(); });
+    ASSERT_OK(mediaquality->setCallback(callback));
+}
+
+TEST_P(MediaQualityAidl, TestSetPictureProfileAdjustmentListener) {
+    std::shared_ptr<PictureProfileAdjustmentListener> listener =
+            ndk::SharedRefBase::make<PictureProfileAdjustmentListener>(
+                    [](auto /*picture profile*/) { return ScopedAStatus::ok(); });
+    ASSERT_OK(mediaquality->setPictureProfileAdjustmentListener(listener));
+}
+
+TEST_P(MediaQualityAidl, TestSendDefaultPictureParameters) {
+    PictureParameters pictureParameters;
+    std::vector<PictureParameter> picParams;
+
+    PictureParameter brightnessParam;
+    brightnessParam.set<PictureParameter::Tag::brightness>(0.5f);
+    picParams.push_back(brightnessParam);
+
+    PictureParameter contrastParam;
+    contrastParam.set<PictureParameter::Tag::contrast>(50);
+    picParams.push_back(contrastParam);
+
+    pictureParameters.pictureParameters = picParams;
+    ASSERT_OK(mediaquality->sendDefaultPictureParameters(pictureParameters));
+}
+
+TEST_P(MediaQualityAidl, TestSetSoundProfileAdjustmentListener) {
+    std::shared_ptr<SoundProfileAdjustmentListener> listener =
+            ndk::SharedRefBase::make<SoundProfileAdjustmentListener>(
+                    [](auto /*sound profile*/) { return ScopedAStatus::ok(); });
+    ASSERT_OK(mediaquality->setSoundProfileAdjustmentListener(listener));
+}
+
+TEST_P(MediaQualityAidl, TestSendDefaultSoundParameters) {
+    SoundParameters soundParameters;
+    std::vector<SoundParameter> soundParams;
+
+    SoundParameter balanceParam;
+    balanceParam.set<SoundParameter::Tag::balance>(50);
+    soundParams.push_back(balanceParam);
+
+    SoundParameter bassParam;
+    bassParam.set<SoundParameter::Tag::bass>(50);
+    soundParams.push_back(bassParam);
+
+    soundParameters.soundParameters = soundParams;
+    ASSERT_OK(mediaquality->sendDefaultSoundParameters(soundParameters));
+}
+
+TEST_P(MediaQualityAidl, TestSetAmbientBacklightDetector) {
+    AmbientBacklightSettings in_settings = {
+            .packageName = "com.android.mediaquality",
+            .source = AmbientBacklightSource::VIDEO,
+            .colorFormat = PixelFormat::RGB_888,
+            .hZonesNumber = 32,
+            .vZonesNumber = 20,
+            .hasLetterbox = true,
+            .threshold = 0,
+    };
+    ASSERT_OK(mediaquality->setAmbientBacklightDetector(in_settings));
+}
+
+TEST_P(MediaQualityAidl, TestIsAutoPqSupported) {
+    bool supported;
+    ASSERT_OK(mediaquality->isAutoPqSupported(&supported));
+}
+
+TEST_P(MediaQualityAidl, TestGetAutoPqEnabled) {
+    bool enabled;
+    ASSERT_OK(mediaquality->getAutoPqEnabled(&enabled));
+}
+
+TEST_P(MediaQualityAidl, TestSetAutoPqEnabled) {
+    ASSERT_OK(mediaquality->setAutoPqEnabled(true));
+}
+
+TEST_P(MediaQualityAidl, TestIsAutoSrSupported) {
+    bool supported;
+    ASSERT_OK(mediaquality->isAutoSrSupported(&supported));
+}
+
+TEST_P(MediaQualityAidl, TestGetAutoSrEnabled) {
+    bool enabled;
+    ASSERT_OK(mediaquality->getAutoSrEnabled(&enabled));
+}
+
+TEST_P(MediaQualityAidl, TestSetAutoSrEnabled) {
+    ASSERT_OK(mediaquality->setAutoSrEnabled(true));
+}
+
+TEST_P(MediaQualityAidl, TestIsAutoAqSupported) {
+    bool supported;
+    ASSERT_OK(mediaquality->isAutoAqSupported(&supported));
+}
+
+TEST_P(MediaQualityAidl, TestGetAutoAqEnabled) {
+    bool enabled;
+    ASSERT_OK(mediaquality->getAutoAqEnabled(&enabled));
+}
+
+TEST_P(MediaQualityAidl, TestSetAutoAqEnabled) {
+    ASSERT_OK(mediaquality->setAutoAqEnabled(true));
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaQualityAidl);
+
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, MediaQualityAidl,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IMediaQuality::descriptor)),
+        android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    ProcessState::self()->startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/tv/tuner/aidl/Android.bp b/tv/tuner/aidl/Android.bp
index efcc327..e53e84d 100644
--- a/tv/tuner/aidl/Android.bp
+++ b/tv/tuner/aidl/Android.bp
@@ -39,7 +39,7 @@
                 "android.hardware.common.fmq-V1",
             ],
         },
-
     ],
+    frozen: false,
 
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
index 783511f..2977ff6 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPreselectionRenderingIndicationType.aidl
@@ -35,9 +35,9 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum AudioPreselectionRenderingIndicationType {
-  NOT_INDICATED = 0,
-  STEREO = 1,
-  TWO_DIMENSIONAL = 2,
-  THREE_DIMENSIONAL = 3,
-  HEADPHONE = 4,
+  NOT_INDICATED,
+  STEREO,
+  TWO_DIMENSIONAL,
+  THREE_DIMENSIONAL,
+  HEADPHONE,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl
index 96a6d98..eba820c 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioPresentation.aidl
@@ -36,5 +36,5 @@
 @VintfStability
 parcelable AudioPresentation {
   android.hardware.tv.tuner.AudioPreselection preselection;
-  int ac4ShortProgramId = -1;
+  int ac4ShortProgramId = (-1) /* -1 */;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl
index 6c538ea..4754bb1 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/AudioStreamType.aidl
@@ -35,24 +35,24 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum AudioStreamType {
-  UNDEFINED = 0,
-  PCM = 1,
-  MP3 = 2,
-  MPEG1 = 3,
-  MPEG2 = 4,
-  MPEGH = 5,
-  AAC = 6,
-  AC3 = 7,
-  EAC3 = 8,
-  AC4 = 9,
-  DTS = 10,
-  DTS_HD = 11,
-  WMA = 12,
-  OPUS = 13,
-  VORBIS = 14,
-  DRA = 15,
-  AAC_ADTS = 16,
-  AAC_LATM = 17,
-  AAC_HE_ADTS = 18,
-  AAC_HE_LATM = 19,
+  UNDEFINED,
+  PCM,
+  MP3,
+  MPEG1,
+  MPEG2,
+  MPEGH,
+  AAC,
+  AC3,
+  EAC3,
+  AC4,
+  DTS,
+  DTS_HD,
+  WMA,
+  OPUS,
+  VORBIS,
+  DRA,
+  AAC_ADTS,
+  AAC_LATM,
+  AAC_HE_ADTS,
+  AAC_HE_LATM,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
index 95ecc51..1f7153b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant.aidl
@@ -35,17 +35,17 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum Constant {
-  INVALID_TS_PID = 65535,
-  INVALID_STREAM_ID = 65535,
-  INVALID_FILTER_ID = -1,
-  INVALID_AV_SYNC_ID = -1,
-  INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = -1,
-  INVALID_FIRST_MACROBLOCK_IN_SLICE = -1,
-  INVALID_FRONTEND_SETTING_FREQUENCY = -1,
-  INVALID_IP_FILTER_CONTEXT_ID = -1,
-  INVALID_LTS_ID = -1,
-  INVALID_FRONTEND_ID = -1,
-  INVALID_LNB_ID = -1,
-  INVALID_KEYTOKEN = 0,
-  INVALID_TABINFO_VERSION = -1,
+  INVALID_TS_PID = 0xFFFF,
+  INVALID_STREAM_ID = 0xFFFF,
+  INVALID_FILTER_ID = 0xFFFFFFFF,
+  INVALID_AV_SYNC_ID = 0xFFFFFFFF,
+  INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM = 0xFFFFFFFF,
+  INVALID_FIRST_MACROBLOCK_IN_SLICE = 0xFFFFFFFF,
+  INVALID_FRONTEND_SETTING_FREQUENCY = 0xFFFFFFFF,
+  INVALID_IP_FILTER_CONTEXT_ID = 0xFFFFFFFF,
+  INVALID_LTS_ID = 0xFFFFFFFF,
+  INVALID_FRONTEND_ID = 0xFFFFFFFF,
+  INVALID_LNB_ID = 0xFFFFFFFF,
+  INVALID_KEYTOKEN = 0x00,
+  INVALID_TABINFO_VERSION = 0xFFFFFFFF,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant64Bit.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant64Bit.aidl
index a56a0cf..ccbfd1a 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant64Bit.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Constant64Bit.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="long") @VintfStability
 enum Constant64Bit {
-  INVALID_FILTER_ID_64BIT = -1,
-  INVALID_AV_SYNC_ID_64BIT = -1,
-  INVALID_PRESENTATION_TIME_STAMP = -1,
+  INVALID_FILTER_ID_64BIT = 0xFFFFFFFFFFFFFFFF,
+  INVALID_AV_SYNC_ID_64BIT = 0xFFFFFFFFFFFFFFFF,
+  INVALID_PRESENTATION_TIME_STAMP = 0xFFFFFFFFFFFFFFFF,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DataFormat.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DataFormat.aidl
index 3b8fee4..5fb34ba 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DataFormat.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DataFormat.aidl
@@ -35,9 +35,9 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DataFormat {
-  TS = 0,
-  PES = 1,
-  ES = 2,
-  SHV_TLV = 3,
-  UNDEFINED = 4,
+  TS,
+  PES,
+  ES,
+  SHV_TLV,
+  UNDEFINED,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
index f0df497..c164f19 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpFilterType.aidl
@@ -35,8 +35,8 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxAlpFilterType {
-  UNDEFINED = 0,
-  SECTION = 1,
-  PTP = 2,
-  PAYLOAD_THROUGH = 3,
+  UNDEFINED,
+  SECTION,
+  PTP,
+  PAYLOAD_THROUGH,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpLengthType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
index ccca6de..59edc34 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxAlpLengthType.aidl
@@ -36,6 +36,6 @@
 @Backing(type="byte") @VintfStability
 enum DemuxAlpLengthType {
   UNDEFINED = 0,
-  WITHOUT_ADDITIONAL_HEADER = 1,
-  WITH_ADDITIONAL_HEADER = 2,
+  WITHOUT_ADDITIONAL_HEADER,
+  WITH_ADDITIONAL_HEADER,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMainType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMainType.aidl
index 6abd87b..b78965d 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMainType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMainType.aidl
@@ -36,9 +36,9 @@
 @Backing(type="int") @VintfStability
 enum DemuxFilterMainType {
   UNDEFINED = 0,
-  TS = 1,
-  MMTP = 2,
-  IP = 4,
-  TLV = 8,
-  ALP = 16,
+  TS = (1 << 0) /* 1 */,
+  MMTP = (1 << 1) /* 2 */,
+  IP = (1 << 2) /* 4 */,
+  TLV = (1 << 3) /* 8 */,
+  ALP = (1 << 4) /* 16 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
index 61a9555..126c740 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
@@ -49,4 +49,7 @@
   boolean isPesPrivateData;
   android.hardware.tv.tuner.DemuxFilterMediaEventExtraMetaData extraMetaData;
   android.hardware.tv.tuner.DemuxFilterScIndexMask scIndexMask;
+  int numDataPieces;
+  int indexInDataGroup;
+  int dataGroupId;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
index 5d27f76..062650b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterMonitorEventType.aidl
@@ -35,6 +35,6 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxFilterMonitorEventType {
-  SCRAMBLING_STATUS = 1,
-  IP_CID_CHANGE = 2,
+  SCRAMBLING_STATUS = (1 << 0) /* 1 */,
+  IP_CID_CHANGE = (1 << 1) /* 2 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
index 1dc593a..cfc5838 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxFilterStatus.aidl
@@ -35,9 +35,9 @@
 /* @hide */
 @Backing(type="byte") @VintfStability
 enum DemuxFilterStatus {
-  DATA_READY = 1,
-  LOW_WATER = 2,
-  HIGH_WATER = 4,
-  OVERFLOW = 8,
-  NO_DATA = 16,
+  DATA_READY = (1 << 0) /* 1 */,
+  LOW_WATER = (1 << 1) /* 2 */,
+  HIGH_WATER = (1 << 2) /* 4 */,
+  OVERFLOW = (1 << 3) /* 8 */,
+  NO_DATA = (1 << 4) /* 16 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl
index 872d963..12f9dc8 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxInfo.aidl
@@ -35,5 +35,5 @@
 /* @hide */
 @VintfStability
 parcelable DemuxInfo {
-  int filterTypes = 0;
+  int filterTypes = android.hardware.tv.tuner.DemuxFilterMainType.UNDEFINED /* 0 */;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterType.aidl
index b78ac9a..7320aec 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxIpFilterType.aidl
@@ -35,10 +35,10 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxIpFilterType {
-  UNDEFINED = 0,
-  SECTION = 1,
-  NTP = 2,
-  IP_PAYLOAD = 3,
-  IP = 4,
-  PAYLOAD_THROUGH = 5,
+  UNDEFINED,
+  SECTION,
+  NTP,
+  IP_PAYLOAD,
+  IP,
+  PAYLOAD_THROUGH,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
index 7e9e3a6..a89c5b1 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxMmtpFilterType.aidl
@@ -35,12 +35,12 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxMmtpFilterType {
-  UNDEFINED = 0,
-  SECTION = 1,
-  PES = 2,
-  MMTP = 3,
-  AUDIO = 4,
-  VIDEO = 5,
-  RECORD = 6,
-  DOWNLOAD = 7,
+  UNDEFINED,
+  SECTION,
+  PES,
+  MMTP,
+  AUDIO,
+  VIDEO,
+  RECORD,
+  DOWNLOAD,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
index bcd0aeb..ecb4e8b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxQueueNotifyBits.aidl
@@ -35,6 +35,6 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxQueueNotifyBits {
-  DATA_READY = 1,
-  DATA_CONSUMED = 2,
+  DATA_READY = (1 << 0) /* 1 */,
+  DATA_CONSUMED = (1 << 1) /* 2 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
index fb4430b..5556bb2 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxRecordScIndexType.aidl
@@ -35,9 +35,9 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxRecordScIndexType {
-  NONE = 0,
-  SC = 1,
-  SC_HEVC = 2,
-  SC_AVC = 3,
-  SC_VVC = 4,
+  NONE,
+  SC,
+  SC_HEVC,
+  SC_AVC,
+  SC_VVC,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
index 651b66c..5c51793 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScAvcIndex.aidl
@@ -36,9 +36,9 @@
 @Backing(type="int") @VintfStability
 enum DemuxScAvcIndex {
   UNDEFINED = 0,
-  I_SLICE = 1,
-  P_SLICE = 2,
-  B_SLICE = 4,
-  SI_SLICE = 8,
-  SP_SLICE = 16,
+  I_SLICE = (1 << 0) /* 1 */,
+  P_SLICE = (1 << 1) /* 2 */,
+  B_SLICE = (1 << 2) /* 4 */,
+  SI_SLICE = (1 << 3) /* 8 */,
+  SP_SLICE = (1 << 4) /* 16 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
index 670b34e..d07bcb7 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScHevcIndex.aidl
@@ -36,12 +36,12 @@
 @Backing(type="int") @VintfStability
 enum DemuxScHevcIndex {
   UNDEFINED = 0,
-  SPS = 1,
-  AUD = 2,
-  SLICE_CE_BLA_W_LP = 4,
-  SLICE_BLA_W_RADL = 8,
-  SLICE_BLA_N_LP = 16,
-  SLICE_IDR_W_RADL = 32,
-  SLICE_IDR_N_LP = 64,
-  SLICE_TRAIL_CRA = 128,
+  SPS = (1 << 0) /* 1 */,
+  AUD = (1 << 1) /* 2 */,
+  SLICE_CE_BLA_W_LP = (1 << 2) /* 4 */,
+  SLICE_BLA_W_RADL = (1 << 3) /* 8 */,
+  SLICE_BLA_N_LP = (1 << 4) /* 16 */,
+  SLICE_IDR_W_RADL = (1 << 5) /* 32 */,
+  SLICE_IDR_N_LP = (1 << 6) /* 64 */,
+  SLICE_TRAIL_CRA = (1 << 7) /* 128 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
index 25f0585..509c1ab 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScIndex.aidl
@@ -36,8 +36,8 @@
 @Backing(type="int") @VintfStability
 enum DemuxScIndex {
   UNDEFINED = 0,
-  I_FRAME = 1,
-  P_FRAME = 2,
-  B_FRAME = 4,
-  SEQUENCE = 8,
+  I_FRAME = (1 << 0) /* 1 */,
+  P_FRAME = (1 << 1) /* 2 */,
+  B_FRAME = (1 << 2) /* 4 */,
+  SEQUENCE = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
index 3e08d26..ac3a5e6 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxScVvcIndex.aidl
@@ -36,11 +36,11 @@
 @Backing(type="int") @VintfStability
 enum DemuxScVvcIndex {
   UNDEFINED = 0,
-  SLICE_IDR_W_RADL = 1,
-  SLICE_IDR_N_LP = 2,
-  SLICE_CRA = 4,
-  SLICE_GDR = 8,
-  VPS = 16,
-  SPS = 32,
-  AUD = 64,
+  SLICE_IDR_W_RADL = (1 << 0) /* 1 */,
+  SLICE_IDR_N_LP = (1 << 1) /* 2 */,
+  SLICE_CRA = (1 << 2) /* 4 */,
+  SLICE_GDR = (1 << 3) /* 8 */,
+  VPS = (1 << 4) /* 16 */,
+  SPS = (1 << 5) /* 32 */,
+  AUD = (1 << 6) /* 64 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
index a4e1ff1..bd9e583 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTlvFilterType.aidl
@@ -35,8 +35,8 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxTlvFilterType {
-  UNDEFINED = 0,
-  SECTION = 1,
-  TLV = 2,
-  PAYLOAD_THROUGH = 3,
+  UNDEFINED,
+  SECTION,
+  TLV,
+  PAYLOAD_THROUGH,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterType.aidl
index 8b806bf..8be0e95 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsFilterType.aidl
@@ -35,13 +35,13 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxTsFilterType {
-  UNDEFINED = 0,
-  SECTION = 1,
-  PES = 2,
-  TS = 3,
-  AUDIO = 4,
-  VIDEO = 5,
-  PCR = 6,
-  RECORD = 7,
-  TEMI = 8,
+  UNDEFINED,
+  SECTION,
+  PES,
+  TS,
+  AUDIO,
+  VIDEO,
+  PCR,
+  RECORD,
+  TEMI,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsIndex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsIndex.aidl
index ed03477..9ca684f 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsIndex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DemuxTsIndex.aidl
@@ -35,22 +35,22 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum DemuxTsIndex {
-  FIRST_PACKET = 1,
-  PAYLOAD_UNIT_START_INDICATOR = 2,
-  CHANGE_TO_NOT_SCRAMBLED = 4,
-  CHANGE_TO_EVEN_SCRAMBLED = 8,
-  CHANGE_TO_ODD_SCRAMBLED = 16,
-  DISCONTINUITY_INDICATOR = 32,
-  RANDOM_ACCESS_INDICATOR = 64,
-  PRIORITY_INDICATOR = 128,
-  PCR_FLAG = 256,
-  OPCR_FLAG = 512,
-  SPLICING_POINT_FLAG = 1024,
-  PRIVATE_DATA = 2048,
-  ADAPTATION_EXTENSION_FLAG = 4096,
-  MPT_INDEX_MPT = 65536,
-  MPT_INDEX_VIDEO = 131072,
-  MPT_INDEX_AUDIO = 262144,
-  MPT_INDEX_TIMESTAMP_TARGET_VIDEO = 524288,
-  MPT_INDEX_TIMESTAMP_TARGET_AUDIO = 1048576,
+  FIRST_PACKET = (1 << 0) /* 1 */,
+  PAYLOAD_UNIT_START_INDICATOR = (1 << 1) /* 2 */,
+  CHANGE_TO_NOT_SCRAMBLED = (1 << 2) /* 4 */,
+  CHANGE_TO_EVEN_SCRAMBLED = (1 << 3) /* 8 */,
+  CHANGE_TO_ODD_SCRAMBLED = (1 << 4) /* 16 */,
+  DISCONTINUITY_INDICATOR = (1 << 5) /* 32 */,
+  RANDOM_ACCESS_INDICATOR = (1 << 6) /* 64 */,
+  PRIORITY_INDICATOR = (1 << 7) /* 128 */,
+  PCR_FLAG = (1 << 8) /* 256 */,
+  OPCR_FLAG = (1 << 9) /* 512 */,
+  SPLICING_POINT_FLAG = (1 << 10) /* 1024 */,
+  PRIVATE_DATA = (1 << 11) /* 2048 */,
+  ADAPTATION_EXTENSION_FLAG = (1 << 12) /* 4096 */,
+  MPT_INDEX_MPT = (1 << 16) /* 65536 */,
+  MPT_INDEX_VIDEO = (1 << 17) /* 131072 */,
+  MPT_INDEX_AUDIO = (1 << 18) /* 262144 */,
+  MPT_INDEX_TIMESTAMP_TARGET_VIDEO = (1 << 19) /* 524288 */,
+  MPT_INDEX_TIMESTAMP_TARGET_AUDIO = (1 << 20) /* 1048576 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrType.aidl
index 3a0c1e4..6dab74b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/DvrType.aidl
@@ -35,6 +35,6 @@
 /* @hide */
 @Backing(type="byte") @VintfStability
 enum DvrType {
-  RECORD = 0,
-  PLAYBACK = 1,
+  RECORD,
+  PLAYBACK,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FilterDelayHintType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FilterDelayHintType.aidl
index 8c5a3f5..af35c70 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FilterDelayHintType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FilterDelayHintType.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FilterDelayHintType {
-  INVALID = 0,
-  TIME_DELAY_IN_MS = 1,
-  DATA_SIZE_DELAY_IN_BYTES = 2,
+  INVALID,
+  TIME_DELAY_IN_MS,
+  DATA_SIZE_DELAY_IN_BYTES,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
index 6b32110..45aa2af 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogAftFlag.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendAnalogAftFlag {
-  UNDEFINED = 0,
-  AFT_TRUE = 1,
-  AFT_FALSE = 2,
+  UNDEFINED,
+  AFT_TRUE,
+  AFT_FALSE,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
index 3502522..8d19461 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogSifStandard.aidl
@@ -36,22 +36,22 @@
 @Backing(type="int") @VintfStability
 enum FrontendAnalogSifStandard {
   UNDEFINED = 0,
-  AUTO = 1,
-  BG = 2,
-  BG_A2 = 4,
-  BG_NICAM = 8,
-  I = 16,
-  DK = 32,
-  DK1_A2 = 64,
-  DK2_A2 = 128,
-  DK3_A2 = 256,
-  DK_NICAM = 512,
-  L = 1024,
-  M = 2048,
-  M_BTSC = 4096,
-  M_A2 = 8192,
-  M_EIAJ = 16384,
-  I_NICAM = 32768,
-  L_NICAM = 65536,
-  L_PRIME = 131072,
+  AUTO = (1 << 0) /* 1 */,
+  BG = (1 << 1) /* 2 */,
+  BG_A2 = (1 << 2) /* 4 */,
+  BG_NICAM = (1 << 3) /* 8 */,
+  I = (1 << 4) /* 16 */,
+  DK = (1 << 5) /* 32 */,
+  DK1_A2 = (1 << 6) /* 64 */,
+  DK2_A2 = (1 << 7) /* 128 */,
+  DK3_A2 = (1 << 8) /* 256 */,
+  DK_NICAM = (1 << 9) /* 512 */,
+  L = (1 << 10) /* 1024 */,
+  M = (1 << 11) /* 2048 */,
+  M_BTSC = (1 << 12) /* 4096 */,
+  M_A2 = (1 << 13) /* 8192 */,
+  M_EIAJ = (1 << 14) /* 16384 */,
+  I_NICAM = (1 << 15) /* 32768 */,
+  L_NICAM = (1 << 16) /* 65536 */,
+  L_PRIME = (1 << 17) /* 131072 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogType.aidl
index 33fd93d..bf8b000 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAnalogType.aidl
@@ -36,12 +36,12 @@
 @Backing(type="int") @VintfStability
 enum FrontendAnalogType {
   UNDEFINED = 0,
-  AUTO = 1,
-  PAL = 2,
-  PAL_M = 4,
-  PAL_N = 8,
-  PAL_60 = 16,
-  NTSC = 32,
-  NTSC_443 = 64,
-  SECAM = 128,
+  AUTO = (1 << 0) /* 1 */,
+  PAL = (1 << 1) /* 2 */,
+  PAL_M = (1 << 2) /* 4 */,
+  PAL_N = (1 << 3) /* 8 */,
+  PAL_60 = (1 << 4) /* 16 */,
+  NTSC = (1 << 5) /* 32 */,
+  NTSC_443 = (1 << 6) /* 64 */,
+  SECAM = (1 << 7) /* 128 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
index 51a3fc5..9704f40 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Bandwidth.aidl
@@ -36,8 +36,8 @@
 @Backing(type="int") @VintfStability
 enum FrontendAtsc3Bandwidth {
   UNDEFINED = 0,
-  AUTO = 1,
-  BANDWIDTH_6MHZ = 2,
-  BANDWIDTH_7MHZ = 4,
-  BANDWIDTH_8MHZ = 8,
+  AUTO = (1 << 0) /* 1 */,
+  BANDWIDTH_6MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_7MHZ = (1 << 2) /* 4 */,
+  BANDWIDTH_8MHZ = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
index aec0718..2d09271 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3CodeRate.aidl
@@ -36,17 +36,17 @@
 @Backing(type="int") @VintfStability
 enum FrontendAtsc3CodeRate {
   UNDEFINED = 0,
-  AUTO = 1,
-  CODERATE_2_15 = 2,
-  CODERATE_3_15 = 4,
-  CODERATE_4_15 = 8,
-  CODERATE_5_15 = 16,
-  CODERATE_6_15 = 32,
-  CODERATE_7_15 = 64,
-  CODERATE_8_15 = 128,
-  CODERATE_9_15 = 256,
-  CODERATE_10_15 = 512,
-  CODERATE_11_15 = 1024,
-  CODERATE_12_15 = 2048,
-  CODERATE_13_15 = 4096,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_2_15 = (1 << 1) /* 2 */,
+  CODERATE_3_15 = (1 << 2) /* 4 */,
+  CODERATE_4_15 = (1 << 3) /* 8 */,
+  CODERATE_5_15 = (1 << 4) /* 16 */,
+  CODERATE_6_15 = (1 << 5) /* 32 */,
+  CODERATE_7_15 = (1 << 6) /* 64 */,
+  CODERATE_8_15 = (1 << 7) /* 128 */,
+  CODERATE_9_15 = (1 << 8) /* 256 */,
+  CODERATE_10_15 = (1 << 9) /* 512 */,
+  CODERATE_11_15 = (1 << 10) /* 1024 */,
+  CODERATE_12_15 = (1 << 11) /* 2048 */,
+  CODERATE_13_15 = (1 << 12) /* 4096 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
index 8702a49..22267e7 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3DemodOutputFormat.aidl
@@ -36,6 +36,6 @@
 @Backing(type="byte") @VintfStability
 enum FrontendAtsc3DemodOutputFormat {
   UNDEFINED = 0,
-  ATSC3_LINKLAYER_PACKET = 1,
-  BASEBAND_PACKET = 2,
+  ATSC3_LINKLAYER_PACKET = (1 << 0) /* 1 */,
+  BASEBAND_PACKET = (1 << 1) /* 2 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
index a2c140a..2e229c0 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Fec.aidl
@@ -36,11 +36,11 @@
 @Backing(type="int") @VintfStability
 enum FrontendAtsc3Fec {
   UNDEFINED = 0,
-  AUTO = 1,
-  BCH_LDPC_16K = 2,
-  BCH_LDPC_64K = 4,
-  CRC_LDPC_16K = 8,
-  CRC_LDPC_64K = 16,
-  LDPC_16K = 32,
-  LDPC_64K = 64,
+  AUTO = (1 << 0) /* 1 */,
+  BCH_LDPC_16K = (1 << 1) /* 2 */,
+  BCH_LDPC_64K = (1 << 2) /* 4 */,
+  CRC_LDPC_16K = (1 << 3) /* 8 */,
+  CRC_LDPC_64K = (1 << 4) /* 16 */,
+  LDPC_16K = (1 << 5) /* 32 */,
+  LDPC_64K = (1 << 6) /* 64 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
index 09e513d..cbe8c1f 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3Modulation.aidl
@@ -36,11 +36,11 @@
 @Backing(type="int") @VintfStability
 enum FrontendAtsc3Modulation {
   UNDEFINED = 0,
-  AUTO = 1,
-  MOD_QPSK = 2,
-  MOD_16QAM = 4,
-  MOD_64QAM = 8,
-  MOD_256QAM = 16,
-  MOD_1024QAM = 32,
-  MOD_4096QAM = 64,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_QPSK = (1 << 1) /* 2 */,
+  MOD_16QAM = (1 << 2) /* 4 */,
+  MOD_64QAM = (1 << 3) /* 8 */,
+  MOD_256QAM = (1 << 4) /* 16 */,
+  MOD_1024QAM = (1 << 5) /* 32 */,
+  MOD_4096QAM = (1 << 6) /* 64 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
index a9747f0..4e70641 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtsc3TimeInterleaveMode.aidl
@@ -36,7 +36,7 @@
 @Backing(type="int") @VintfStability
 enum FrontendAtsc3TimeInterleaveMode {
   UNDEFINED = 0,
-  AUTO = 1,
-  CTI = 2,
-  HTI = 4,
+  AUTO = (1 << 0) /* 1 */,
+  CTI = (1 << 1) /* 2 */,
+  HTI = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscModulation.aidl
index 426fe20..7da48f1 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscModulation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendAtscModulation.aidl
@@ -36,7 +36,7 @@
 @Backing(type="int") @VintfStability
 enum FrontendAtscModulation {
   UNDEFINED = 0,
-  AUTO = 1,
-  MOD_8VSB = 4,
-  MOD_16VSB = 8,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_8VSB = (1 << 2) /* 4 */,
+  MOD_16VSB = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
index ff71df3..61cbf12 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendCableTimeInterleaveMode.aidl
@@ -36,14 +36,14 @@
 @Backing(type="int") @VintfStability
 enum FrontendCableTimeInterleaveMode {
   UNDEFINED = 0,
-  AUTO = 1,
-  INTERLEAVING_128_1_0 = 2,
-  INTERLEAVING_128_1_1 = 4,
-  INTERLEAVING_64_2 = 8,
-  INTERLEAVING_32_4 = 16,
-  INTERLEAVING_16_8 = 32,
-  INTERLEAVING_8_16 = 64,
-  INTERLEAVING_128_2 = 128,
-  INTERLEAVING_128_3 = 256,
-  INTERLEAVING_128_4 = 512,
+  AUTO = (1 << 0) /* 1 */,
+  INTERLEAVING_128_1_0 = (1 << 1) /* 2 */,
+  INTERLEAVING_128_1_1 = (1 << 2) /* 4 */,
+  INTERLEAVING_64_2 = (1 << 3) /* 8 */,
+  INTERLEAVING_32_4 = (1 << 4) /* 16 */,
+  INTERLEAVING_16_8 = (1 << 5) /* 32 */,
+  INTERLEAVING_8_16 = (1 << 6) /* 64 */,
+  INTERLEAVING_128_2 = (1 << 7) /* 128 */,
+  INTERLEAVING_128_3 = (1 << 8) /* 256 */,
+  INTERLEAVING_128_4 = (1 << 9) /* 512 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
index 18d71d2..6f62d91 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbBandwidth.aidl
@@ -36,7 +36,7 @@
 @Backing(type="int") @VintfStability
 enum FrontendDtmbBandwidth {
   UNDEFINED = 0,
-  AUTO = 1,
-  BANDWIDTH_8MHZ = 2,
-  BANDWIDTH_6MHZ = 4,
+  AUTO = (1 << 0) /* 1 */,
+  BANDWIDTH_8MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_6MHZ = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
index c9454e7..d6be639 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbCodeRate.aidl
@@ -36,8 +36,8 @@
 @Backing(type="int") @VintfStability
 enum FrontendDtmbCodeRate {
   UNDEFINED = 0,
-  AUTO = 1,
-  CODERATE_2_5 = 2,
-  CODERATE_3_5 = 4,
-  CODERATE_4_5 = 8,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_2_5 = (1 << 1) /* 2 */,
+  CODERATE_3_5 = (1 << 2) /* 4 */,
+  CODERATE_4_5 = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
index 872eb6a..5626064 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbGuardInterval.aidl
@@ -36,11 +36,11 @@
 @Backing(type="int") @VintfStability
 enum FrontendDtmbGuardInterval {
   UNDEFINED = 0,
-  AUTO = 1,
-  PN_420_VARIOUS = 2,
-  PN_595_CONST = 4,
-  PN_945_VARIOUS = 8,
-  PN_420_CONST = 16,
-  PN_945_CONST = 32,
-  PN_RESERVED = 64,
+  AUTO = (1 << 0) /* 1 */,
+  PN_420_VARIOUS = (1 << 1) /* 2 */,
+  PN_595_CONST = (1 << 2) /* 4 */,
+  PN_945_VARIOUS = (1 << 3) /* 8 */,
+  PN_420_CONST = (1 << 4) /* 16 */,
+  PN_945_CONST = (1 << 5) /* 32 */,
+  PN_RESERVED = (1 << 6) /* 64 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
index 088aac5..036e64b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbModulation.aidl
@@ -36,10 +36,10 @@
 @Backing(type="int") @VintfStability
 enum FrontendDtmbModulation {
   UNDEFINED = 0,
-  AUTO = 1,
-  CONSTELLATION_4QAM = 2,
-  CONSTELLATION_4QAM_NR = 4,
-  CONSTELLATION_16QAM = 8,
-  CONSTELLATION_32QAM = 16,
-  CONSTELLATION_64QAM = 32,
+  AUTO = (1 << 0) /* 1 */,
+  CONSTELLATION_4QAM = (1 << 1) /* 2 */,
+  CONSTELLATION_4QAM_NR = (1 << 2) /* 4 */,
+  CONSTELLATION_16QAM = (1 << 3) /* 8 */,
+  CONSTELLATION_32QAM = (1 << 4) /* 16 */,
+  CONSTELLATION_64QAM = (1 << 5) /* 32 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
index 8321ad0..1223887 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTimeInterleaveMode.aidl
@@ -36,7 +36,7 @@
 @Backing(type="int") @VintfStability
 enum FrontendDtmbTimeInterleaveMode {
   UNDEFINED = 0,
-  AUTO = 1,
-  TIMER_INT_240 = 2,
-  TIMER_INT_720 = 4,
+  AUTO = (1 << 0) /* 1 */,
+  TIMER_INT_240 = (1 << 1) /* 2 */,
+  TIMER_INT_720 = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
index 5298291..0498825 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDtmbTransmissionMode.aidl
@@ -36,7 +36,7 @@
 @Backing(type="int") @VintfStability
 enum FrontendDtmbTransmissionMode {
   UNDEFINED = 0,
-  AUTO = 1,
-  C1 = 2,
-  C3780 = 4,
+  AUTO = (1 << 0) /* 1 */,
+  C1 = (1 << 1) /* 2 */,
+  C3780 = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
index cdfedb6..985add1 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcAnnex.aidl
@@ -36,7 +36,7 @@
 @Backing(type="byte") @VintfStability
 enum FrontendDvbcAnnex {
   UNDEFINED = 0,
-  A = 1,
-  B = 2,
-  C = 4,
+  A = (1 << 0) /* 1 */,
+  B = (1 << 1) /* 2 */,
+  C = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
index f0fe460..c253cfe 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcBandwidth.aidl
@@ -36,8 +36,8 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbcBandwidth {
   UNDEFINED = 0,
-  BANDWIDTH_5MHZ = 1,
-  BANDWIDTH_6MHZ = 2,
-  BANDWIDTH_7MHZ = 4,
-  BANDWIDTH_8MHZ = 8,
+  BANDWIDTH_5MHZ = (1 << 0) /* 1 */,
+  BANDWIDTH_6MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_7MHZ = (1 << 2) /* 4 */,
+  BANDWIDTH_8MHZ = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
index 0871777..c18e83e 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcModulation.aidl
@@ -36,10 +36,10 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbcModulation {
   UNDEFINED = 0,
-  AUTO = 1,
-  MOD_16QAM = 2,
-  MOD_32QAM = 4,
-  MOD_64QAM = 8,
-  MOD_128QAM = 16,
-  MOD_256QAM = 32,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_16QAM = (1 << 1) /* 2 */,
+  MOD_32QAM = (1 << 2) /* 4 */,
+  MOD_64QAM = (1 << 3) /* 8 */,
+  MOD_128QAM = (1 << 4) /* 16 */,
+  MOD_256QAM = (1 << 5) /* 32 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
index f1e92c9..a6fbc6d 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbcOuterFec.aidl
@@ -36,6 +36,6 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbcOuterFec {
   UNDEFINED = 0,
-  OUTER_FEC_NONE = 1,
-  OUTER_FEC_RS = 2,
+  OUTER_FEC_NONE,
+  OUTER_FEC_RS,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
index 25951cc..71957d5 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsModulation.aidl
@@ -36,18 +36,18 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbsModulation {
   UNDEFINED = 0,
-  AUTO = 1,
-  MOD_QPSK = 2,
-  MOD_8PSK = 4,
-  MOD_16QAM = 8,
-  MOD_16PSK = 16,
-  MOD_32PSK = 32,
-  MOD_ACM = 64,
-  MOD_8APSK = 128,
-  MOD_16APSK = 256,
-  MOD_32APSK = 512,
-  MOD_64APSK = 1024,
-  MOD_128APSK = 2048,
-  MOD_256APSK = 4096,
-  MOD_RESERVED = 8192,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_QPSK = (1 << 1) /* 2 */,
+  MOD_8PSK = (1 << 2) /* 4 */,
+  MOD_16QAM = (1 << 3) /* 8 */,
+  MOD_16PSK = (1 << 4) /* 16 */,
+  MOD_32PSK = (1 << 5) /* 32 */,
+  MOD_ACM = (1 << 6) /* 64 */,
+  MOD_8APSK = (1 << 7) /* 128 */,
+  MOD_16APSK = (1 << 8) /* 256 */,
+  MOD_32APSK = (1 << 9) /* 512 */,
+  MOD_64APSK = (1 << 10) /* 1024 */,
+  MOD_128APSK = (1 << 11) /* 2048 */,
+  MOD_256APSK = (1 << 12) /* 4096 */,
+  MOD_RESERVED = (1 << 13) /* 8192 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsPilot.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
index 4f2c6eb..e3543b3 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsPilot.aidl
@@ -35,8 +35,8 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendDvbsPilot {
-  UNDEFINED = 0,
-  ON = 1,
-  OFF = 2,
-  AUTO = 3,
+  UNDEFINED,
+  ON,
+  OFF,
+  AUTO,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
index 56ee37b..2181abf 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsRolloff.aidl
@@ -35,11 +35,11 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendDvbsRolloff {
-  UNDEFINED = 0,
-  ROLLOFF_0_35 = 1,
-  ROLLOFF_0_25 = 2,
-  ROLLOFF_0_20 = 3,
-  ROLLOFF_0_15 = 4,
-  ROLLOFF_0_10 = 5,
-  ROLLOFF_0_5 = 6,
+  UNDEFINED,
+  ROLLOFF_0_35,
+  ROLLOFF_0_25,
+  ROLLOFF_0_20,
+  ROLLOFF_0_15,
+  ROLLOFF_0_10,
+  ROLLOFF_0_5,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsScanType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
index 110b1d8..46edb56 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsScanType.aidl
@@ -36,8 +36,8 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbsScanType {
   UNDEFINED = 0,
-  DIRECT = 1,
-  DISEQC = 2,
-  UNICABLE = 3,
-  JESS = 4,
+  DIRECT,
+  DISEQC,
+  UNICABLE,
+  JESS,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
index b9cb657..bcb1c6d 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsStandard.aidl
@@ -36,8 +36,8 @@
 @Backing(type="byte") @VintfStability
 enum FrontendDvbsStandard {
   UNDEFINED = 0,
-  AUTO = 1,
-  S = 2,
-  S2 = 4,
-  S2X = 8,
+  AUTO = (1 << 0) /* 1 */,
+  S = (1 << 1) /* 2 */,
+  S2 = (1 << 2) /* 4 */,
+  S2X = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
index 2cbff7c..af87423 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbsVcmMode.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendDvbsVcmMode {
-  UNDEFINED = 0,
-  AUTO = 1,
-  MANUAL = 2,
+  UNDEFINED,
+  AUTO,
+  MANUAL,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
index f5d14e8..ff2d9e4 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtBandwidth.aidl
@@ -36,11 +36,11 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbtBandwidth {
   UNDEFINED = 0,
-  AUTO = 1,
-  BANDWIDTH_8MHZ = 2,
-  BANDWIDTH_7MHZ = 4,
-  BANDWIDTH_6MHZ = 8,
-  BANDWIDTH_5MHZ = 16,
-  BANDWIDTH_1_7MHZ = 32,
-  BANDWIDTH_10MHZ = 64,
+  AUTO = (1 << 0) /* 1 */,
+  BANDWIDTH_8MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_7MHZ = (1 << 2) /* 4 */,
+  BANDWIDTH_6MHZ = (1 << 3) /* 8 */,
+  BANDWIDTH_5MHZ = (1 << 4) /* 16 */,
+  BANDWIDTH_1_7MHZ = (1 << 5) /* 32 */,
+  BANDWIDTH_10MHZ = (1 << 6) /* 64 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
index 8bd0489..8d2df06 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtCoderate.aidl
@@ -36,14 +36,14 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbtCoderate {
   UNDEFINED = 0,
-  AUTO = 1,
-  CODERATE_1_2 = 2,
-  CODERATE_2_3 = 4,
-  CODERATE_3_4 = 8,
-  CODERATE_5_6 = 16,
-  CODERATE_7_8 = 32,
-  CODERATE_3_5 = 64,
-  CODERATE_4_5 = 128,
-  CODERATE_6_7 = 256,
-  CODERATE_8_9 = 512,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_1_2 = (1 << 1) /* 2 */,
+  CODERATE_2_3 = (1 << 2) /* 4 */,
+  CODERATE_3_4 = (1 << 3) /* 8 */,
+  CODERATE_5_6 = (1 << 4) /* 16 */,
+  CODERATE_7_8 = (1 << 5) /* 32 */,
+  CODERATE_3_5 = (1 << 6) /* 64 */,
+  CODERATE_4_5 = (1 << 7) /* 128 */,
+  CODERATE_6_7 = (1 << 8) /* 256 */,
+  CODERATE_8_9 = (1 << 9) /* 512 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
index bc40901..4bd5691 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtConstellation.aidl
@@ -36,13 +36,13 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbtConstellation {
   UNDEFINED = 0,
-  AUTO = 1,
-  CONSTELLATION_QPSK = 2,
-  CONSTELLATION_16QAM = 4,
-  CONSTELLATION_64QAM = 8,
-  CONSTELLATION_256QAM = 16,
-  CONSTELLATION_QPSK_R = 32,
-  CONSTELLATION_16QAM_R = 64,
-  CONSTELLATION_64QAM_R = 128,
-  CONSTELLATION_256QAM_R = 256,
+  AUTO = (1 << 0) /* 1 */,
+  CONSTELLATION_QPSK = (1 << 1) /* 2 */,
+  CONSTELLATION_16QAM = (1 << 2) /* 4 */,
+  CONSTELLATION_64QAM = (1 << 3) /* 8 */,
+  CONSTELLATION_256QAM = (1 << 4) /* 16 */,
+  CONSTELLATION_QPSK_R = (1 << 5) /* 32 */,
+  CONSTELLATION_16QAM_R = (1 << 6) /* 64 */,
+  CONSTELLATION_64QAM_R = (1 << 7) /* 128 */,
+  CONSTELLATION_256QAM_R = (1 << 8) /* 256 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
index 073a77e..01c2b66 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtGuardInterval.aidl
@@ -36,12 +36,12 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbtGuardInterval {
   UNDEFINED = 0,
-  AUTO = 1,
-  INTERVAL_1_32 = 2,
-  INTERVAL_1_16 = 4,
-  INTERVAL_1_8 = 8,
-  INTERVAL_1_4 = 16,
-  INTERVAL_1_128 = 32,
-  INTERVAL_19_128 = 64,
-  INTERVAL_19_256 = 128,
+  AUTO = (1 << 0) /* 1 */,
+  INTERVAL_1_32 = (1 << 1) /* 2 */,
+  INTERVAL_1_16 = (1 << 2) /* 4 */,
+  INTERVAL_1_8 = (1 << 3) /* 8 */,
+  INTERVAL_1_4 = (1 << 4) /* 16 */,
+  INTERVAL_1_128 = (1 << 5) /* 32 */,
+  INTERVAL_19_128 = (1 << 6) /* 64 */,
+  INTERVAL_19_256 = (1 << 7) /* 128 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
index 9ed5c8c..bd86479 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtHierarchy.aidl
@@ -36,13 +36,13 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbtHierarchy {
   UNDEFINED = 0,
-  AUTO = 1,
-  HIERARCHY_NON_NATIVE = 2,
-  HIERARCHY_1_NATIVE = 4,
-  HIERARCHY_2_NATIVE = 8,
-  HIERARCHY_4_NATIVE = 16,
-  HIERARCHY_NON_INDEPTH = 32,
-  HIERARCHY_1_INDEPTH = 64,
-  HIERARCHY_2_INDEPTH = 128,
-  HIERARCHY_4_INDEPTH = 256,
+  AUTO = (1 << 0) /* 1 */,
+  HIERARCHY_NON_NATIVE = (1 << 1) /* 2 */,
+  HIERARCHY_1_NATIVE = (1 << 2) /* 4 */,
+  HIERARCHY_2_NATIVE = (1 << 3) /* 8 */,
+  HIERARCHY_4_NATIVE = (1 << 4) /* 16 */,
+  HIERARCHY_NON_INDEPTH = (1 << 5) /* 32 */,
+  HIERARCHY_1_INDEPTH = (1 << 6) /* 64 */,
+  HIERARCHY_2_INDEPTH = (1 << 7) /* 128 */,
+  HIERARCHY_4_INDEPTH = (1 << 8) /* 256 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
index c80bc2a..dc8e12c 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtPlpMode.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendDvbtPlpMode {
-  UNDEFINED = 0,
-  AUTO = 1,
-  MANUAL = 2,
+  UNDEFINED,
+  AUTO,
+  MANUAL,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtStandard.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
index c7ba68a..080cc5c 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtStandard.aidl
@@ -36,7 +36,7 @@
 @Backing(type="byte") @VintfStability
 enum FrontendDvbtStandard {
   UNDEFINED = 0,
-  AUTO = 1,
-  T = 2,
-  T2 = 4,
+  AUTO = (1 << 0) /* 1 */,
+  T = (1 << 1) /* 2 */,
+  T2 = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
index e3ca2e3..3731f86 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendDvbtTransmissionMode.aidl
@@ -36,14 +36,14 @@
 @Backing(type="int") @VintfStability
 enum FrontendDvbtTransmissionMode {
   UNDEFINED = 0,
-  AUTO = 1,
-  MODE_2K = 2,
-  MODE_8K = 4,
-  MODE_4K = 8,
-  MODE_1K = 16,
-  MODE_16K = 32,
-  MODE_32K = 64,
-  MODE_8K_E = 128,
-  MODE_16K_E = 256,
-  MODE_32K_E = 512,
+  AUTO = (1 << 0) /* 1 */,
+  MODE_2K = (1 << 1) /* 2 */,
+  MODE_8K = (1 << 2) /* 4 */,
+  MODE_4K = (1 << 3) /* 8 */,
+  MODE_1K = (1 << 4) /* 16 */,
+  MODE_16K = (1 << 5) /* 32 */,
+  MODE_32K = (1 << 6) /* 64 */,
+  MODE_8K_E = (1 << 7) /* 128 */,
+  MODE_16K_E = (1 << 8) /* 256 */,
+  MODE_32K_E = (1 << 9) /* 512 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendEventType.aidl
index 443313f..101e347 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendEventType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendEventType.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendEventType {
-  LOCKED = 0,
-  NO_SIGNAL = 1,
-  LOST_LOCK = 2,
+  LOCKED,
+  NO_SIGNAL,
+  LOST_LOCK,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInnerFec.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInnerFec.aidl
index 19599a3..da91888 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInnerFec.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInnerFec.aidl
@@ -36,57 +36,57 @@
 @Backing(type="long") @VintfStability
 enum FrontendInnerFec {
   FEC_UNDEFINED = 0,
-  AUTO = 1,
-  FEC_1_2 = 2,
-  FEC_1_3 = 4,
-  FEC_1_4 = 8,
-  FEC_1_5 = 16,
-  FEC_2_3 = 32,
-  FEC_2_5 = 64,
-  FEC_2_9 = 128,
-  FEC_3_4 = 256,
-  FEC_3_5 = 512,
-  FEC_4_5 = 1024,
-  FEC_4_15 = 2048,
-  FEC_5_6 = 4096,
-  FEC_5_9 = 8192,
-  FEC_6_7 = 16384,
-  FEC_7_8 = 32768,
-  FEC_7_9 = 65536,
-  FEC_7_15 = 131072,
-  FEC_8_9 = 262144,
-  FEC_8_15 = 524288,
-  FEC_9_10 = 1048576,
-  FEC_9_20 = 2097152,
-  FEC_11_15 = 4194304,
-  FEC_11_20 = 8388608,
-  FEC_11_45 = 16777216,
-  FEC_13_18 = 33554432,
-  FEC_13_45 = 67108864,
-  FEC_14_45 = 134217728,
-  FEC_23_36 = 268435456,
-  FEC_25_36 = 536870912,
-  FEC_26_45 = 1073741824,
-  FEC_28_45 = 2147483648,
-  FEC_29_45 = 4294967296,
-  FEC_31_45 = 8589934592,
-  FEC_32_45 = 17179869184,
-  FEC_77_90 = 34359738368,
-  FEC_2_15 = 68719476736,
-  FEC_3_15 = 137438953472,
-  FEC_5_15 = 274877906944,
-  FEC_6_15 = 549755813888,
-  FEC_9_15 = 1099511627776,
-  FEC_10_15 = 2199023255552,
-  FEC_12_15 = 4398046511104,
-  FEC_13_15 = 8796093022208,
-  FEC_18_30 = 17592186044416,
-  FEC_20_30 = 35184372088832,
-  FEC_90_180 = 70368744177664,
-  FEC_96_180 = 140737488355328,
-  FEC_104_180 = 281474976710656,
-  FEC_128_180 = 562949953421312,
-  FEC_132_180 = 1125899906842624,
-  FEC_135_180 = 2251799813685248,
-  FEC_140_180 = 4503599627370496,
+  AUTO = (1L << 0) /* 1 */,
+  FEC_1_2 = (1L << 1) /* 2 */,
+  FEC_1_3 = (1L << 2) /* 4 */,
+  FEC_1_4 = (1L << 3) /* 8 */,
+  FEC_1_5 = (1L << 4) /* 16 */,
+  FEC_2_3 = (1L << 5) /* 32 */,
+  FEC_2_5 = (1L << 6) /* 64 */,
+  FEC_2_9 = (1L << 7) /* 128 */,
+  FEC_3_4 = (1L << 8) /* 256 */,
+  FEC_3_5 = (1L << 9) /* 512 */,
+  FEC_4_5 = (1L << 10) /* 1024 */,
+  FEC_4_15 = (1L << 11) /* 2048 */,
+  FEC_5_6 = (1L << 12) /* 4096 */,
+  FEC_5_9 = (1L << 13) /* 8192 */,
+  FEC_6_7 = (1L << 14) /* 16384 */,
+  FEC_7_8 = (1L << 15) /* 32768 */,
+  FEC_7_9 = (1L << 16) /* 65536 */,
+  FEC_7_15 = (1L << 17) /* 131072 */,
+  FEC_8_9 = (1L << 18) /* 262144 */,
+  FEC_8_15 = (1L << 19) /* 524288 */,
+  FEC_9_10 = (1L << 20) /* 1048576 */,
+  FEC_9_20 = (1L << 21) /* 2097152 */,
+  FEC_11_15 = (1L << 22) /* 4194304 */,
+  FEC_11_20 = (1L << 23) /* 8388608 */,
+  FEC_11_45 = (1L << 24) /* 16777216 */,
+  FEC_13_18 = (1L << 25) /* 33554432 */,
+  FEC_13_45 = (1L << 26) /* 67108864 */,
+  FEC_14_45 = (1L << 27) /* 134217728 */,
+  FEC_23_36 = (1L << 28) /* 268435456 */,
+  FEC_25_36 = (1L << 29) /* 536870912 */,
+  FEC_26_45 = (1L << 30) /* 1073741824 */,
+  FEC_28_45 = (1L << 31) /* 2147483648 */,
+  FEC_29_45 = (1L << 32) /* 4294967296 */,
+  FEC_31_45 = (1L << 33) /* 8589934592 */,
+  FEC_32_45 = (1L << 34) /* 17179869184 */,
+  FEC_77_90 = (1L << 35) /* 34359738368 */,
+  FEC_2_15 = (1L << 36) /* 68719476736 */,
+  FEC_3_15 = (1L << 37) /* 137438953472 */,
+  FEC_5_15 = (1L << 38) /* 274877906944 */,
+  FEC_6_15 = (1L << 39) /* 549755813888 */,
+  FEC_9_15 = (1L << 40) /* 1099511627776 */,
+  FEC_10_15 = (1L << 41) /* 2199023255552 */,
+  FEC_12_15 = (1L << 42) /* 4398046511104 */,
+  FEC_13_15 = (1L << 43) /* 8796093022208 */,
+  FEC_18_30 = (1L << 44) /* 17592186044416 */,
+  FEC_20_30 = (1L << 45) /* 35184372088832 */,
+  FEC_90_180 = (1L << 46) /* 70368744177664 */,
+  FEC_96_180 = (1L << 47) /* 140737488355328 */,
+  FEC_104_180 = (1L << 48) /* 281474976710656 */,
+  FEC_128_180 = (1L << 49) /* 562949953421312 */,
+  FEC_132_180 = (1L << 50) /* 1125899906842624 */,
+  FEC_135_180 = (1L << 51) /* 2251799813685248 */,
+  FEC_140_180 = (1L << 52) /* 4503599627370496 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
index 50a1208..5806cc5 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsFecType.aidl
@@ -36,7 +36,7 @@
 @Backing(type="int") @VintfStability
 enum FrontendIptvSettingsFecType {
   UNDEFINED = 0,
-  COLUMN = 1,
-  ROW = 2,
-  COLUMN_ROW = 4,
+  COLUMN = (1 << 0) /* 1 */,
+  ROW = (1 << 1) /* 2 */,
+  COLUMN_ROW = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
index aa08496..43ae523 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsIgmp.aidl
@@ -36,7 +36,7 @@
 @Backing(type="int") @VintfStability
 enum FrontendIptvSettingsIgmp {
   UNDEFINED = 0,
-  V1 = 1,
-  V2 = 2,
-  V3 = 4,
+  V1 = (1 << 0) /* 1 */,
+  V2 = (1 << 1) /* 2 */,
+  V3 = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
index 08a01f1..2e4c478 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIptvSettingsProtocol.aidl
@@ -36,6 +36,6 @@
 @Backing(type="int") @VintfStability
 enum FrontendIptvSettingsProtocol {
   UNDEFINED = 0,
-  UDP = 1,
-  RTP = 2,
+  UDP = (1 << 0) /* 1 */,
+  RTP = (1 << 1) /* 2 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
index 1ee7f07..de865ca 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Coderate.aidl
@@ -36,16 +36,16 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbs3Coderate {
   UNDEFINED = 0,
-  AUTO = 1,
-  CODERATE_1_3 = 2,
-  CODERATE_2_5 = 4,
-  CODERATE_1_2 = 8,
-  CODERATE_3_5 = 16,
-  CODERATE_2_3 = 32,
-  CODERATE_3_4 = 64,
-  CODERATE_7_9 = 128,
-  CODERATE_4_5 = 256,
-  CODERATE_5_6 = 512,
-  CODERATE_7_8 = 1024,
-  CODERATE_9_10 = 2048,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_1_3 = (1 << 1) /* 2 */,
+  CODERATE_2_5 = (1 << 2) /* 4 */,
+  CODERATE_1_2 = (1 << 3) /* 8 */,
+  CODERATE_3_5 = (1 << 4) /* 16 */,
+  CODERATE_2_3 = (1 << 5) /* 32 */,
+  CODERATE_3_4 = (1 << 6) /* 64 */,
+  CODERATE_7_9 = (1 << 7) /* 128 */,
+  CODERATE_4_5 = (1 << 8) /* 256 */,
+  CODERATE_5_6 = (1 << 9) /* 512 */,
+  CODERATE_7_8 = (1 << 10) /* 1024 */,
+  CODERATE_9_10 = (1 << 11) /* 2048 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
index 3603292..adc902d 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Modulation.aidl
@@ -36,10 +36,10 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbs3Modulation {
   UNDEFINED = 0,
-  AUTO = 1,
-  MOD_BPSK = 2,
-  MOD_QPSK = 4,
-  MOD_8PSK = 8,
-  MOD_16APSK = 16,
-  MOD_32APSK = 32,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_BPSK = (1 << 1) /* 2 */,
+  MOD_QPSK = (1 << 2) /* 4 */,
+  MOD_8PSK = (1 << 3) /* 8 */,
+  MOD_16APSK = (1 << 4) /* 16 */,
+  MOD_32APSK = (1 << 5) /* 32 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
index 733760c..c93cf20 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbs3Rolloff.aidl
@@ -35,6 +35,6 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendIsdbs3Rolloff {
-  UNDEFINED = 0,
-  ROLLOFF_0_03 = 1,
+  UNDEFINED,
+  ROLLOFF_0_03,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
index 09e9c59..a0e436f 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsCoderate.aidl
@@ -36,10 +36,10 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbsCoderate {
   UNDEFINED = 0,
-  AUTO = 1,
-  CODERATE_1_2 = 2,
-  CODERATE_2_3 = 4,
-  CODERATE_3_4 = 8,
-  CODERATE_5_6 = 16,
-  CODERATE_7_8 = 32,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_1_2 = (1 << 1) /* 2 */,
+  CODERATE_2_3 = (1 << 2) /* 4 */,
+  CODERATE_3_4 = (1 << 3) /* 8 */,
+  CODERATE_5_6 = (1 << 4) /* 16 */,
+  CODERATE_7_8 = (1 << 5) /* 32 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
index 7b9bde6..61a21c3 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsModulation.aidl
@@ -36,8 +36,8 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbsModulation {
   UNDEFINED = 0,
-  AUTO = 1,
-  MOD_BPSK = 2,
-  MOD_QPSK = 4,
-  MOD_TC8PSK = 8,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_BPSK = (1 << 1) /* 2 */,
+  MOD_QPSK = (1 << 2) /* 4 */,
+  MOD_TC8PSK = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
index a2ab154..b769231 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsRolloff.aidl
@@ -35,6 +35,6 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendIsdbsRolloff {
-  UNDEFINED = 0,
-  ROLLOFF_0_35 = 1,
+  UNDEFINED,
+  ROLLOFF_0_35,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
index 089f611..77956b6 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbsStreamIdType.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendIsdbsStreamIdType {
-  STREAM_ID = 0,
-  RELATIVE_STREAM_NUMBER = 1,
-  UNDEFINED = 2,
+  STREAM_ID,
+  RELATIVE_STREAM_NUMBER,
+  UNDEFINED,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
index cd49214..209620f 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtBandwidth.aidl
@@ -36,8 +36,8 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbtBandwidth {
   UNDEFINED = 0,
-  AUTO = 1,
-  BANDWIDTH_8MHZ = 2,
-  BANDWIDTH_7MHZ = 4,
-  BANDWIDTH_6MHZ = 8,
+  AUTO = (1 << 0) /* 1 */,
+  BANDWIDTH_8MHZ = (1 << 1) /* 2 */,
+  BANDWIDTH_7MHZ = (1 << 2) /* 4 */,
+  BANDWIDTH_6MHZ = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
index 2b747ed..4236b7c 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCoderate.aidl
@@ -36,14 +36,14 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbtCoderate {
   UNDEFINED = 0,
-  AUTO = 1,
-  CODERATE_1_2 = 2,
-  CODERATE_2_3 = 4,
-  CODERATE_3_4 = 8,
-  CODERATE_5_6 = 16,
-  CODERATE_7_8 = 32,
-  CODERATE_3_5 = 64,
-  CODERATE_4_5 = 128,
-  CODERATE_6_7 = 256,
-  CODERATE_8_9 = 512,
+  AUTO = (1 << 0) /* 1 */,
+  CODERATE_1_2 = (1 << 1) /* 2 */,
+  CODERATE_2_3 = (1 << 2) /* 4 */,
+  CODERATE_3_4 = (1 << 3) /* 8 */,
+  CODERATE_5_6 = (1 << 4) /* 16 */,
+  CODERATE_7_8 = (1 << 5) /* 32 */,
+  CODERATE_3_5 = (1 << 6) /* 64 */,
+  CODERATE_4_5 = (1 << 7) /* 128 */,
+  CODERATE_6_7 = (1 << 8) /* 256 */,
+  CODERATE_8_9 = (1 << 9) /* 512 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
index 42a023a..86225e2 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtGuardInterval.aidl
@@ -36,12 +36,12 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbtGuardInterval {
   UNDEFINED = 0,
-  AUTO = 1,
-  INTERVAL_1_32 = 2,
-  INTERVAL_1_16 = 4,
-  INTERVAL_1_8 = 8,
-  INTERVAL_1_4 = 16,
-  INTERVAL_1_128 = 32,
-  INTERVAL_19_128 = 64,
-  INTERVAL_19_256 = 128,
+  AUTO = (1 << 0) /* 1 */,
+  INTERVAL_1_32 = (1 << 1) /* 2 */,
+  INTERVAL_1_16 = (1 << 2) /* 4 */,
+  INTERVAL_1_8 = (1 << 3) /* 8 */,
+  INTERVAL_1_4 = (1 << 4) /* 16 */,
+  INTERVAL_1_128 = (1 << 5) /* 32 */,
+  INTERVAL_19_128 = (1 << 6) /* 64 */,
+  INTERVAL_19_256 = (1 << 7) /* 128 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
index 54698ab..0e38c26 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtMode.aidl
@@ -36,8 +36,8 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbtMode {
   UNDEFINED = 0,
-  AUTO = 1,
-  MODE_1 = 2,
-  MODE_2 = 4,
-  MODE_3 = 8,
+  AUTO = (1 << 0) /* 1 */,
+  MODE_1 = (1 << 1) /* 2 */,
+  MODE_2 = (1 << 2) /* 4 */,
+  MODE_3 = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
index a31e0cf..4474c83 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtModulation.aidl
@@ -36,9 +36,9 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbtModulation {
   UNDEFINED = 0,
-  AUTO = 1,
-  MOD_DQPSK = 2,
-  MOD_QPSK = 4,
-  MOD_16QAM = 8,
-  MOD_64QAM = 16,
+  AUTO = (1 << 0) /* 1 */,
+  MOD_DQPSK = (1 << 1) /* 2 */,
+  MOD_QPSK = (1 << 2) /* 4 */,
+  MOD_16QAM = (1 << 3) /* 8 */,
+  MOD_64QAM = (1 << 4) /* 16 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
index 133887f..1387e66 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
@@ -36,7 +36,7 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbtPartialReceptionFlag {
   UNDEFINED = 0,
-  AUTO = 1,
-  FALSE = 2,
-  TRUE = 4,
+  AUTO = (1 << 0) /* 1 */,
+  FALSE = (1 << 1) /* 2 */,
+  TRUE = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
index 50adde9..b9d76ee 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
@@ -36,17 +36,17 @@
 @Backing(type="int") @VintfStability
 enum FrontendIsdbtTimeInterleaveMode {
   UNDEFINED = 0,
-  AUTO = 1,
-  INTERLEAVE_1_0 = 2,
-  INTERLEAVE_1_4 = 4,
-  INTERLEAVE_1_8 = 8,
-  INTERLEAVE_1_16 = 16,
-  INTERLEAVE_2_0 = 32,
-  INTERLEAVE_2_2 = 64,
-  INTERLEAVE_2_4 = 128,
-  INTERLEAVE_2_8 = 256,
-  INTERLEAVE_3_0 = 512,
-  INTERLEAVE_3_1 = 1024,
-  INTERLEAVE_3_2 = 2048,
-  INTERLEAVE_3_4 = 4096,
+  AUTO = (1 << 0) /* 1 */,
+  INTERLEAVE_1_0 = (1 << 1) /* 2 */,
+  INTERLEAVE_1_4 = (1 << 2) /* 4 */,
+  INTERLEAVE_1_8 = (1 << 3) /* 8 */,
+  INTERLEAVE_1_16 = (1 << 4) /* 16 */,
+  INTERLEAVE_2_0 = (1 << 5) /* 32 */,
+  INTERLEAVE_2_2 = (1 << 6) /* 64 */,
+  INTERLEAVE_2_4 = (1 << 7) /* 128 */,
+  INTERLEAVE_2_8 = (1 << 8) /* 256 */,
+  INTERLEAVE_3_0 = (1 << 9) /* 512 */,
+  INTERLEAVE_3_1 = (1 << 10) /* 1024 */,
+  INTERLEAVE_3_2 = (1 << 11) /* 2048 */,
+  INTERLEAVE_3_4 = (1 << 12) /* 4096 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl
index 6976ecd..186dbd7 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanMessageType.aidl
@@ -35,20 +35,20 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendScanMessageType {
-  LOCKED = 0,
-  END = 1,
-  PROGRESS_PERCENT = 2,
-  FREQUENCY = 3,
-  SYMBOL_RATE = 4,
-  HIERARCHY = 5,
-  ANALOG_TYPE = 6,
-  PLP_IDS = 7,
-  GROUP_IDS = 8,
-  INPUT_STREAM_IDS = 9,
-  STANDARD = 10,
-  ATSC3_PLP_INFO = 11,
-  MODULATION = 12,
-  DVBC_ANNEX = 13,
-  HIGH_PRIORITY = 14,
-  DVBT_CELL_IDS = 15,
+  LOCKED,
+  END,
+  PROGRESS_PERCENT,
+  FREQUENCY,
+  SYMBOL_RATE,
+  HIERARCHY,
+  ANALOG_TYPE,
+  PLP_IDS,
+  GROUP_IDS,
+  INPUT_STREAM_IDS,
+  STANDARD,
+  ATSC3_PLP_INFO,
+  MODULATION,
+  DVBC_ANNEX,
+  HIGH_PRIORITY,
+  DVBT_CELL_IDS,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanType.aidl
index ed42d0a..cef02cc 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendScanType.aidl
@@ -36,6 +36,6 @@
 @Backing(type="int") @VintfStability
 enum FrontendScanType {
   SCAN_UNDEFINED = 0,
-  SCAN_AUTO = 1,
-  SCAN_BLIND = 2,
+  SCAN_AUTO = (1 << 0) /* 1 */,
+  SCAN_BLIND = (1 << 1) /* 2 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSpectralInversion.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
index ff11bb8..14ec2fd 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendSpectralInversion.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendSpectralInversion {
-  UNDEFINED = 0,
-  NORMAL = 1,
-  INVERTED = 2,
+  UNDEFINED,
+  NORMAL,
+  INVERTED,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStandardExt.aidl
similarity index 80%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStandardExt.aidl
index a5eda52..88637db 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStandardExt.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.tv.tuner;
+/* @hide */
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+union FrontendStandardExt {
+  android.hardware.tv.tuner.FrontendDvbsStandard dvbsStandardExt = android.hardware.tv.tuner.FrontendDvbsStandard.UNDEFINED;
+  android.hardware.tv.tuner.FrontendDvbtStandard dvbtStandardExt = android.hardware.tv.tuner.FrontendDvbtStandard.UNDEFINED;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
index b991ab6..e79eba6 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -82,4 +82,5 @@
   long iptvPacketsLost;
   int iptvWorstJitterMs;
   int iptvAverageJitterMs;
+  android.hardware.tv.tuner.FrontendStandardExt standardExt;
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusReadiness.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusReadiness.aidl
index 41944ce..13735fa 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusReadiness.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusReadiness.aidl
@@ -35,9 +35,9 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendStatusReadiness {
-  UNDEFINED = 0,
-  UNAVAILABLE = 1,
-  UNSTABLE = 2,
-  STABLE = 3,
-  UNSUPPORTED = 4,
+  UNDEFINED,
+  UNAVAILABLE,
+  UNSTABLE,
+  STABLE,
+  UNSUPPORTED,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
index 3791299..bfd2145 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -35,51 +35,52 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum FrontendStatusType {
-  DEMOD_LOCK = 0,
-  SNR = 1,
-  BER = 2,
-  PER = 3,
-  PRE_BER = 4,
-  SIGNAL_QUALITY = 5,
-  SIGNAL_STRENGTH = 6,
-  SYMBOL_RATE = 7,
-  FEC = 8,
-  MODULATION = 9,
-  SPECTRAL = 10,
-  LNB_VOLTAGE = 11,
-  PLP_ID = 12,
-  EWBS = 13,
-  AGC = 14,
-  LNA = 15,
-  LAYER_ERROR = 16,
-  MER = 17,
-  FREQ_OFFSET = 18,
-  HIERARCHY = 19,
-  RF_LOCK = 20,
-  ATSC3_PLP_INFO = 21,
-  MODULATIONS = 22,
-  BERS = 23,
-  CODERATES = 24,
-  BANDWIDTH = 25,
-  GUARD_INTERVAL = 26,
-  TRANSMISSION_MODE = 27,
-  UEC = 28,
-  T2_SYSTEM_ID = 29,
-  INTERLEAVINGS = 30,
-  ISDBT_SEGMENTS = 31,
-  TS_DATA_RATES = 32,
-  ROLL_OFF = 33,
-  IS_MISO = 34,
-  IS_LINEAR = 35,
-  IS_SHORT_FRAMES = 36,
-  ISDBT_MODE = 37,
-  ISDBT_PARTIAL_RECEPTION_FLAG = 38,
-  STREAM_ID_LIST = 39,
-  DVBT_CELL_IDS = 40,
-  ATSC3_ALL_PLP_INFO = 41,
-  IPTV_CONTENT_URL = 42,
-  IPTV_PACKETS_LOST = 43,
-  IPTV_PACKETS_RECEIVED = 44,
-  IPTV_WORST_JITTER_MS = 45,
-  IPTV_AVERAGE_JITTER_MS = 46,
+  DEMOD_LOCK,
+  SNR,
+  BER,
+  PER,
+  PRE_BER,
+  SIGNAL_QUALITY,
+  SIGNAL_STRENGTH,
+  SYMBOL_RATE,
+  FEC,
+  MODULATION,
+  SPECTRAL,
+  LNB_VOLTAGE,
+  PLP_ID,
+  EWBS,
+  AGC,
+  LNA,
+  LAYER_ERROR,
+  MER,
+  FREQ_OFFSET,
+  HIERARCHY,
+  RF_LOCK,
+  ATSC3_PLP_INFO,
+  MODULATIONS,
+  BERS,
+  CODERATES,
+  BANDWIDTH,
+  GUARD_INTERVAL,
+  TRANSMISSION_MODE,
+  UEC,
+  T2_SYSTEM_ID,
+  INTERLEAVINGS,
+  ISDBT_SEGMENTS,
+  TS_DATA_RATES,
+  ROLL_OFF,
+  IS_MISO,
+  IS_LINEAR,
+  IS_SHORT_FRAMES,
+  ISDBT_MODE,
+  ISDBT_PARTIAL_RECEPTION_FLAG,
+  STREAM_ID_LIST,
+  DVBT_CELL_IDS,
+  ATSC3_ALL_PLP_INFO,
+  IPTV_CONTENT_URL,
+  IPTV_PACKETS_LOST,
+  IPTV_PACKETS_RECEIVED,
+  IPTV_WORST_JITTER_MS,
+  IPTV_AVERAGE_JITTER_MS,
+  STANDARD_EXT,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
index cbf5b47..455bbc0 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendType.aidl
@@ -36,15 +36,15 @@
 @Backing(type="int") @VintfStability
 enum FrontendType {
   UNDEFINED = 0,
-  ANALOG = 1,
-  ATSC = 2,
-  ATSC3 = 3,
-  DVBC = 4,
-  DVBS = 5,
-  DVBT = 6,
-  ISDBS = 7,
-  ISDBS3 = 8,
-  ISDBT = 9,
-  DTMB = 10,
-  IPTV = 11,
+  ANALOG,
+  ATSC,
+  ATSC3,
+  DVBC,
+  DVBS,
+  DVBT,
+  ISDBS,
+  ISDBS3,
+  ISDBT,
+  DTMB,
+  IPTV,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbEventType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbEventType.aidl
index e6e2b05..7bec809 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbEventType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbEventType.aidl
@@ -35,8 +35,8 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum LnbEventType {
-  DISEQC_RX_OVERFLOW = 0,
-  DISEQC_RX_TIMEOUT = 1,
-  DISEQC_RX_PARITY_ERROR = 2,
-  LNB_OVERLOAD = 3,
+  DISEQC_RX_OVERFLOW,
+  DISEQC_RX_TIMEOUT,
+  DISEQC_RX_PARITY_ERROR,
+  LNB_OVERLOAD,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbPosition.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbPosition.aidl
index 5fc4d15..a4a5740 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbPosition.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbPosition.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum LnbPosition {
-  UNDEFINED = 0,
-  POSITION_A = 1,
-  POSITION_B = 2,
+  UNDEFINED,
+  POSITION_A,
+  POSITION_B,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbTone.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbTone.aidl
index 3217de9..0628354 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbTone.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbTone.aidl
@@ -35,6 +35,6 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum LnbTone {
-  NONE = 0,
-  CONTINUOUS = 1,
+  NONE,
+  CONTINUOUS,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbVoltage.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbVoltage.aidl
index 034c7e6..b18ff0e 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbVoltage.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/LnbVoltage.aidl
@@ -35,13 +35,13 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum LnbVoltage {
-  NONE = 0,
-  VOLTAGE_5V = 1,
-  VOLTAGE_11V = 2,
-  VOLTAGE_12V = 3,
-  VOLTAGE_13V = 4,
-  VOLTAGE_14V = 5,
-  VOLTAGE_15V = 6,
-  VOLTAGE_18V = 7,
-  VOLTAGE_19V = 8,
+  NONE,
+  VOLTAGE_5V,
+  VOLTAGE_11V,
+  VOLTAGE_12V,
+  VOLTAGE_13V,
+  VOLTAGE_14V,
+  VOLTAGE_15V,
+  VOLTAGE_18V,
+  VOLTAGE_19V,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackStatus.aidl
index 850b737..a8b6378 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/PlaybackStatus.aidl
@@ -35,8 +35,8 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum PlaybackStatus {
-  SPACE_EMPTY = 1,
-  SPACE_ALMOST_EMPTY = 2,
-  SPACE_ALMOST_FULL = 4,
-  SPACE_FULL = 8,
+  SPACE_EMPTY = (1 << 0) /* 1 */,
+  SPACE_ALMOST_EMPTY = (1 << 1) /* 2 */,
+  SPACE_ALMOST_FULL = (1 << 2) /* 4 */,
+  SPACE_FULL = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordStatus.aidl
index 48bf9ec..e06b616 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/RecordStatus.aidl
@@ -35,8 +35,8 @@
 /* @hide */
 @Backing(type="byte") @VintfStability
 enum RecordStatus {
-  DATA_READY = 1,
-  LOW_WATER = 2,
-  HIGH_WATER = 4,
-  OVERFLOW = 8,
+  DATA_READY = (1 << 0) /* 1 */,
+  LOW_WATER = (1 << 1) /* 2 */,
+  HIGH_WATER = (1 << 2) /* 4 */,
+  OVERFLOW = (1 << 3) /* 8 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Result.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Result.aidl
index 4e22f67..ae43350 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Result.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/Result.aidl
@@ -35,11 +35,11 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum Result {
-  SUCCESS = 0,
-  UNAVAILABLE = 1,
-  NOT_INITIALIZED = 2,
-  INVALID_STATE = 3,
-  INVALID_ARGUMENT = 4,
-  OUT_OF_MEMORY = 5,
-  UNKNOWN_ERROR = 6,
+  SUCCESS,
+  UNAVAILABLE,
+  NOT_INITIALIZED,
+  INVALID_STATE,
+  INVALID_ARGUMENT,
+  OUT_OF_MEMORY,
+  UNKNOWN_ERROR,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ScramblingStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ScramblingStatus.aidl
index 656fe20..4d52de1 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ScramblingStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/ScramblingStatus.aidl
@@ -35,7 +35,7 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum ScramblingStatus {
-  UNKNOWN = 1,
-  NOT_SCRAMBLED = 2,
-  SCRAMBLED = 4,
+  UNKNOWN = (1 << 0) /* 1 */,
+  NOT_SCRAMBLED = (1 << 1) /* 2 */,
+  SCRAMBLED = (1 << 2) /* 4 */,
 }
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
index dbb6033..530f454 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/VideoStreamType.aidl
@@ -35,18 +35,18 @@
 /* @hide */
 @Backing(type="int") @VintfStability
 enum VideoStreamType {
-  UNDEFINED = 0,
-  RESERVED = 1,
-  MPEG1 = 2,
-  MPEG2 = 3,
-  MPEG4P2 = 4,
-  AVC = 5,
-  HEVC = 6,
-  VC1 = 7,
-  VP8 = 8,
-  VP9 = 9,
-  AV1 = 10,
-  AVS = 11,
-  AVS2 = 12,
-  VVC = 13,
+  UNDEFINED,
+  RESERVED,
+  MPEG1,
+  MPEG2,
+  MPEG4P2,
+  AVC,
+  HEVC,
+  VC1,
+  VP8,
+  VP9,
+  AV1,
+  AVS,
+  AVS2,
+  VVC,
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
index 32f0cb2..06f087b 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/DemuxFilterMediaEvent.aidl
@@ -17,7 +17,6 @@
 package android.hardware.tv.tuner;
 
 import android.hardware.common.NativeHandle;
-
 import android.hardware.tv.tuner.DemuxFilterMediaEventExtraMetaData;
 import android.hardware.tv.tuner.DemuxFilterScIndexMask;
 
@@ -91,4 +90,32 @@
      * access unit framing at decode stage.
      */
     DemuxFilterScIndexMask scIndexMask;
+
+    /**
+     * This attribute is used together with dataGroupId and indexInDataGroup to
+     * associate fragmented data.
+     *
+     * 1 if the media event contains the complete data. dataGroupId can be
+     * ignored.
+     * Greater than 1 if the media event contains incomplete data. Data can be
+     * reassembled by gathering all media events with the same dataGroupId.
+     */
+    int numDataPieces;
+
+    /**
+     * This attribute is used together with numDataPieces and dataGroupId to
+     * associate fragmented data.
+     *
+     * The value should be in the range of [0, numDataPieces - 1], indicating
+     * this piece is the Nth piece.
+     */
+    int indexInDataGroup;
+
+    /**
+     * This attribute is used together with numDataPieces and indexInDataGroup to
+     * associate fragmented data.
+     *
+     * The value is the id of the data group.
+     */
+    int dataGroupId;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStandardExt.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStandardExt.aidl
new file mode 100644
index 0000000..0b68e89
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStandardExt.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.FrontendDvbsStandard;
+import android.hardware.tv.tuner.FrontendDvbtStandard;
+
+/**
+ * @hide
+ */
+@VintfStability
+union FrontendStandardExt {
+    /**
+     * The DVB-S standard extension after standard transition.
+     */
+    FrontendDvbsStandard dvbsStandardExt = FrontendDvbsStandard.UNDEFINED;
+
+    /**
+     * The DVB-T standard extension after standard transition.
+     */
+    FrontendDvbtStandard dvbtStandardExt = FrontendDvbtStandard.UNDEFINED;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
index 391f29b..a3902df 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -28,6 +28,7 @@
 import android.hardware.tv.tuner.FrontendRollOff;
 import android.hardware.tv.tuner.FrontendScanAtsc3PlpInfo;
 import android.hardware.tv.tuner.FrontendSpectralInversion;
+import android.hardware.tv.tuner.FrontendStandardExt;
 import android.hardware.tv.tuner.FrontendStatusAtsc3PlpInfo;
 import android.hardware.tv.tuner.FrontendTransmissionMode;
 import android.hardware.tv.tuner.LnbVoltage;
@@ -272,4 +273,13 @@
      * Average jitter (milliseconds).
      */
     int iptvAverageJitterMs;
+
+    /**
+     * Standard extension.
+     *
+     * DVB-T and DVB-S can transition to another standard within the same standard series. For
+     * example, DVB-T can transition to DVB-T2 and back. This attribute represents the standard
+     * extension. Valid values include FrontendDvbtStandard.T or FrontendDvbsStandard.S2 etc.
+     */
+    FrontendStandardExt standardExt;
 }
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
index 6804b2d..3225c42 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -259,4 +259,9 @@
      * Average jitter (milliseconds).
      */
     IPTV_AVERAGE_JITTER_MS,
+
+    /**
+     * Standard extension.
+     */
+    STANDARD_EXT,
 }
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index 5f7a4cd..946ec3a 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -333,8 +333,8 @@
     // All the filter event callbacks in start are for testing purpose.
     switch (mType.mainType) {
         case DemuxFilterMainType::TS:
-            createMediaEvent(events, false);
-            createMediaEvent(events, true);
+            createMediaEvent(events, false, 0);
+            createMediaEvent(events, true, 1);
             createTsRecordEvent(events);
             createTemiEvent(events);
             break;
@@ -1235,7 +1235,8 @@
     return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
 }
 
-void Filter::createMediaEvent(vector<DemuxFilterEvent>& events, bool isAudioPresentation) {
+void Filter::createMediaEvent(vector<DemuxFilterEvent>& events, bool isAudioPresentation,
+                              int indexInDataGroup) {
     DemuxFilterMediaEvent mediaEvent;
     mediaEvent.streamId = 1;
     mediaEvent.isPtsPresent = true;
@@ -1302,6 +1303,10 @@
     mediaEvent.avDataId = static_cast<int64_t>(dataId);
     mediaEvent.avMemory = ::android::dupToAidl(nativeHandle);
 
+    mediaEvent.numDataPieces = 2;
+    mediaEvent.indexInDataGroup = indexInDataGroup;
+    mediaEvent.dataGroupId = 321;
+
     events.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>(std::move(mediaEvent)));
 
     native_handle_close(nativeHandle);
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index e2a0c7a..4be15e2 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -231,7 +231,8 @@
     ::ndk::ScopedAStatus createShareMemMediaEvents(vector<int8_t>& output);
     bool sameFile(int fd1, int fd2);
 
-    void createMediaEvent(vector<DemuxFilterEvent>&, bool isAudioPresentation);
+    void createMediaEvent(vector<DemuxFilterEvent>&, bool isAudioPresentation,
+                          int indexInDataGroup);
     void createTsRecordEvent(vector<DemuxFilterEvent>&);
     void createMmtpRecordEvent(vector<DemuxFilterEvent>&);
     void createSectionEvent(vector<DemuxFilterEvent>&);
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index 1031604..bba004a 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -81,6 +81,7 @@
                     FrontendStatusType::SIGNAL_STRENGTH, FrontendStatusType::SYMBOL_RATE,
                     FrontendStatusType::MODULATION,      FrontendStatusType::MODULATIONS,
                     FrontendStatusType::ROLL_OFF,        FrontendStatusType::IS_MISO,
+                    FrontendStatusType::STANDARD_EXT,
             };
             break;
         }
@@ -96,6 +97,7 @@
                     FrontendStatusType::TRANSMISSION_MODE,
                     FrontendStatusType::T2_SYSTEM_ID,
                     FrontendStatusType::DVBT_CELL_IDS,
+                    FrontendStatusType::STANDARD_EXT,
             };
             break;
         }
@@ -985,6 +987,17 @@
                 status.set<FrontendStatus::iptvAverageJitterMs>(5);
                 break;
             }
+            case FrontendStatusType::STANDARD_EXT: {
+                FrontendStandardExt standardExt;
+                if (mType == FrontendType::DVBS) {
+                    standardExt.set<FrontendStandardExt::dvbsStandardExt>(
+                            FrontendDvbsStandard::S2X);
+                } else if (mType == FrontendType::DVBT) {
+                    standardExt.set<FrontendStandardExt::dvbtStandardExt>(FrontendDvbtStandard::T2);
+                }
+                status.set<FrontendStatus::standardExt>(standardExt);
+                break;
+            }
             default: {
                 continue;
             }
diff --git a/tv/tuner/aidl/default/tuner-default.xml b/tv/tuner/aidl/default/tuner-default.xml
index bff8ff0..261fcbf 100644
--- a/tv/tuner/aidl/default/tuner-default.xml
+++ b/tv/tuner/aidl/default/tuner-default.xml
@@ -2,6 +2,6 @@
     <hal format="aidl">
         <name>android.hardware.tv.tuner</name>
         <fqname>ITuner/default</fqname>
-        <version>2</version>
+        <version>3</version>
     </hal>
 </manifest>
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.cpp b/tv/tuner/aidl/vts/functional/FilterTests.cpp
index 533d0e6..788ebbd 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FilterTests.cpp
@@ -105,17 +105,30 @@
     // todo separate filter handlers
     for (int i = 0; i < events.size(); i++) {
         switch (events[i].getTag()) {
-            case DemuxFilterEvent::Tag::media:
-                ALOGD("[vts] Media filter event, avMemHandle numFds=%zu.",
-                      events[i].get<DemuxFilterEvent::Tag::media>().avMemory.fds.size());
+            case DemuxFilterEvent::Tag::media: {
+                int numDataPieces = events[i].get<DemuxFilterEvent::Tag::media>().numDataPieces;
+                int indexInDataGroup
+                    = events[i].get<DemuxFilterEvent::Tag::media>().indexInDataGroup;
+                ALOGD("[vts] Media filter event, avMemHandle numFds=%zu, numDataPieces=%d,"
+                      " indexInDataGroup=%d, dataGroupId=%d.",
+                      events[i].get<DemuxFilterEvent::Tag::media>().avMemory.fds.size(),
+                      numDataPieces,
+                      indexInDataGroup,
+                      events[i].get<DemuxFilterEvent::Tag::media>().dataGroupId);
+                if (numDataPieces > 1) {
+                    EXPECT_TRUE(indexInDataGroup >= 0);
+                    EXPECT_TRUE(indexInDataGroup < numDataPieces);
+                }
                 dumpAvData(events[i].get<DemuxFilterEvent::Tag::media>());
                 break;
-            case DemuxFilterEvent::Tag::tsRecord:
+            }
+            case DemuxFilterEvent::Tag::tsRecord: {
                 ALOGD("[vts] TS record filter event, pts=%" PRIu64 ", firstMbInSlice=%d",
                       events[i].get<DemuxFilterEvent::Tag::tsRecord>().pts,
                       events[i].get<DemuxFilterEvent::Tag::tsRecord>().firstMbInSlice);
                 break;
-            case DemuxFilterEvent::Tag::mmtpRecord:
+            }
+            case DemuxFilterEvent::Tag::mmtpRecord: {
                 ALOGD("[vts] MMTP record filter event, pts=%" PRIu64
                       ", firstMbInSlice=%d, mpuSequenceNumber=%d, tsIndexMask=%d",
                       events[i].get<DemuxFilterEvent::Tag::mmtpRecord>().pts,
@@ -123,7 +136,8 @@
                       events[i].get<DemuxFilterEvent::Tag::mmtpRecord>().mpuSequenceNumber,
                       events[i].get<DemuxFilterEvent::Tag::mmtpRecord>().tsIndexMask);
                 break;
-            case DemuxFilterEvent::Tag::monitorEvent:
+            }
+            case DemuxFilterEvent::Tag::monitorEvent: {
                 switch (events[i].get<DemuxFilterEvent::Tag::monitorEvent>().getTag()) {
                     case DemuxFilterMonitorEvent::Tag::scramblingStatus:
                         mScramblingStatusEvent++;
@@ -135,13 +149,16 @@
                         break;
                 }
                 break;
-            case DemuxFilterEvent::Tag::startId:
+            }
+            case DemuxFilterEvent::Tag::startId: {
                 ALOGD("[vts] Restart filter event, startId=%d",
                       events[i].get<DemuxFilterEvent::Tag::startId>());
                 mStartIdReceived = true;
                 break;
-            default:
+            }
+            default: {
                 break;
+            }
         }
     }
 }
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index 85d0496..99c0283 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -636,7 +636,7 @@
     ASSERT_TRUE(tuneFrontend(frontendConf, false /*testWithDemux*/));
 
     // TODO: find a better way to push all frontend status types
-    for (int32_t i = 0; i <= static_cast<int32_t>(FrontendStatusType::ATSC3_ALL_PLP_INFO); i++) {
+    for (int32_t i = 0; i <= static_cast<int32_t>(FrontendStatusType::STANDARD_EXT); i++) {
         allTypes.push_back(static_cast<FrontendStatusType>(i));
     }
 
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePwleV2.aidl
similarity index 94%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePwleV2.aidl
index a5eda52..de0bdb5 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/CompositePwleV2.aidl
@@ -33,7 +33,6 @@
 
 package android.hardware.vibrator;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable CompositePwleV2 {
+  android.hardware.vibrator.PwleV2Primitive[] pwlePrimitives;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/FrequencyAccelerationMapEntry.aidl
similarity index 97%
rename from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
rename to vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/FrequencyAccelerationMapEntry.aidl
index a5eda52..e6743f9 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/FrequencyAccelerationMapEntry.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.vibrator;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
+parcelable FrequencyAccelerationMapEntry {
   float frequencyHz;
   float maxOutputAccelerationGs;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrationSession.aidl
similarity index 94%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrationSession.aidl
index a5eda52..ec301b2 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrationSession.aidl
@@ -33,7 +33,7 @@
 
 package android.hardware.vibrator;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+interface IVibrationSession {
+  void close();
+  void abort();
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl
index 0dcc657..9fad952 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibrator.aidl
@@ -51,19 +51,40 @@
   void alwaysOnDisable(in int id);
   float getResonantFrequency();
   float getQFactor();
+  /**
+   * @deprecated This method is deprecated from AIDL v3 and is no longer required to be implemented even if CAP_FREQUENCY_CONTROL capability is reported.
+   */
   float getFrequencyResolution();
+  /**
+   * @deprecated This method is deprecated from AIDL v3 and is no longer required to be implemented even if CAP_FREQUENCY_CONTROL capability is reported.
+   */
   float getFrequencyMinimum();
+  /**
+   * @deprecated This method is deprecated from AIDL v3 and is no longer required to be implemented even if CAP_FREQUENCY_CONTROL capability is reported.
+   */
   float[] getBandwidthAmplitudeMap();
+  /**
+   * @deprecated This method is deprecated from AIDL v3 and is no longer required to be implemented. Use `IVibrator.getPwleV2PrimitiveDurationMaxMillis` instead.
+   */
   int getPwlePrimitiveDurationMax();
+  /**
+   * @deprecated This method is deprecated from AIDL v3 and is no longer required to be implemented. Use `IVibrator.getPwleV2CompositionSizeMax` instead.
+   */
   int getPwleCompositionSizeMax();
+  /**
+   * @deprecated This method is deprecated from AIDL v3 and is no longer required to be implemented.
+   */
   android.hardware.vibrator.Braking[] getSupportedBraking();
+  /**
+   * @deprecated This method is deprecated from AIDL v3 and is no longer required to be implemented. Use `IVibrator.composePwleV2` instead.
+   */
   void composePwle(in android.hardware.vibrator.PrimitivePwle[] composite, in android.hardware.vibrator.IVibratorCallback callback);
   void performVendorEffect(in android.hardware.vibrator.VendorEffect vendorEffect, in android.hardware.vibrator.IVibratorCallback callback);
-  List<android.hardware.vibrator.PwleV2OutputMapEntry> getPwleV2FrequencyToOutputAccelerationMap();
+  List<android.hardware.vibrator.FrequencyAccelerationMapEntry> getFrequencyToOutputAccelerationMap();
   int getPwleV2PrimitiveDurationMaxMillis();
   int getPwleV2CompositionSizeMax();
   int getPwleV2PrimitiveDurationMinMillis();
-  void composePwleV2(in android.hardware.vibrator.PwleV2Primitive[] composite, in android.hardware.vibrator.IVibratorCallback callback);
+  void composePwleV2(in android.hardware.vibrator.CompositePwleV2 composite, in android.hardware.vibrator.IVibratorCallback callback);
   const int CAP_ON_CALLBACK = (1 << 0) /* 1 */;
   const int CAP_PERFORM_CALLBACK = (1 << 1) /* 2 */;
   const int CAP_AMPLITUDE_CONTROL = (1 << 2) /* 4 */;
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
index ef5794c..081d9dc 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/IVibratorManager.aidl
@@ -40,6 +40,8 @@
   void prepareSynced(in int[] vibratorIds);
   void triggerSynced(in android.hardware.vibrator.IVibratorCallback callback);
   void cancelSynced();
+  android.hardware.vibrator.IVibrationSession startSession(in int[] vibratorIds, in android.hardware.vibrator.VibrationSessionConfig config, in android.hardware.vibrator.IVibratorCallback callback);
+  void clearSessions();
   const int CAP_SYNC = (1 << 0) /* 1 */;
   const int CAP_PREPARE_ON = (1 << 1) /* 2 */;
   const int CAP_PREPARE_PERFORM = (1 << 2) /* 4 */;
@@ -48,4 +50,5 @@
   const int CAP_MIXED_TRIGGER_PERFORM = (1 << 5) /* 32 */;
   const int CAP_MIXED_TRIGGER_COMPOSE = (1 << 6) /* 64 */;
   const int CAP_TRIGGER_CALLBACK = (1 << 7) /* 128 */;
+  const int CAP_START_SESSIONS = (1 << 8) /* 256 */;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VibrationSessionConfig.aidl
similarity index 94%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VibrationSessionConfig.aidl
index a5eda52..01136aa 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VibrationSessionConfig.aidl
@@ -33,7 +33,6 @@
 
 package android.hardware.vibrator;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable VibrationSessionConfig {
+  ParcelableHolder vendorExtension;
 }
diff --git a/vibrator/aidl/android/hardware/vibrator/CompositePwleV2.aidl b/vibrator/aidl/android/hardware/vibrator/CompositePwleV2.aidl
new file mode 100644
index 0000000..f0d0970
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/CompositePwleV2.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.vibrator;
+
+import android.hardware.vibrator.PwleV2Primitive;
+
+@VintfStability
+parcelable CompositePwleV2 {
+    /**
+     * Represents a PWLE (Piecewise-Linear Envelope) effect as an array of primitives.
+     *
+     * A PWLE effect defines a vibration waveform using amplitude and frequency points.
+     * The envelope linearly interpolates both amplitude and frequency between consecutive points,
+     * creating smooth transitions in the vibration pattern.
+     */
+    PwleV2Primitive[] pwlePrimitives;
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/vibrator/aidl/android/hardware/vibrator/FrequencyAccelerationMapEntry.aidl
similarity index 89%
rename from vibrator/aidl/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
rename to vibrator/aidl/android/hardware/vibrator/FrequencyAccelerationMapEntry.aidl
index a8db87c..013ae84 100644
--- a/vibrator/aidl/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/FrequencyAccelerationMapEntry.aidl
@@ -17,7 +17,7 @@
 package android.hardware.vibrator;
 
 @VintfStability
-parcelable PwleV2OutputMapEntry {
+parcelable FrequencyAccelerationMapEntry {
     /**
      * Absolute frequency point in the units of hertz
      *
@@ -29,7 +29,7 @@
      *
      * This value represents the maximum safe output acceleration (in Gs) achievable at the
      * specified frequency, typically determined during calibration. The actual output acceleration
-     * is assumed to scale linearly with the input amplitude within the range of [0, 1].
+     * should scale linearly based on the 'amplitude' input value.
      */
     float maxOutputAccelerationGs;
 }
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrationSession.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrationSession.aidl
new file mode 100644
index 0000000..88382e5
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrationSession.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.vibrator;
+
+@VintfStability
+interface IVibrationSession {
+    /**
+     * Request the end of this session.
+     *
+     * This will cause this session to end once the ongoing vibration commands are completed in each
+     * individual vibrator. The immediate end of this session can stll be trigged via abort().
+     *
+     * This should not block on the end of this session. The callback provided during the creation
+     * of this session should be used to indicate the vibrations are done and the session has
+     * ended. The session object can be safely destroyed after this is called, and the session
+     * should end as expected.
+     */
+    void close();
+
+    /**
+     * Immediately end this session.
+     *
+     * This will cause this session to end immediately and stop any ongoing vibration. The vibrator
+     * manager and each individual vibrator in this session will be reset and available when this
+     * returns.
+     */
+    void abort();
+}
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
index 11f36ba..81d7948 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibrator.aidl
@@ -19,12 +19,12 @@
 import android.hardware.vibrator.Braking;
 import android.hardware.vibrator.CompositeEffect;
 import android.hardware.vibrator.CompositePrimitive;
+import android.hardware.vibrator.CompositePwleV2;
 import android.hardware.vibrator.Effect;
 import android.hardware.vibrator.EffectStrength;
+import android.hardware.vibrator.FrequencyAccelerationMapEntry;
 import android.hardware.vibrator.IVibratorCallback;
 import android.hardware.vibrator.PrimitivePwle;
-import android.hardware.vibrator.PwleV2OutputMapEntry;
-import android.hardware.vibrator.PwleV2Primitive;
 import android.hardware.vibrator.VendorEffect;
 
 @VintfStability
@@ -290,6 +290,8 @@
      *
      * @return The frequency resolution of the bandwidth amplitude map.
      *         Non-zero value if supported, or value should be ignored if not supported.
+     * @deprecated This method is deprecated from AIDL v3 and is no longer required to be
+     * implemented even if CAP_FREQUENCY_CONTROL capability is reported.
      */
     float getFrequencyResolution();
 
@@ -301,6 +303,8 @@
      *
      * @return The minimum frequency allowed. Non-zero value if supported,
      *         or value should be ignored if not supported.
+     * @deprecated This method is deprecated from AIDL v3 and is no longer required to be
+     * implemented even if CAP_FREQUENCY_CONTROL capability is reported.
      */
     float getFrequencyMinimum();
 
@@ -322,6 +326,8 @@
      *
      * @return The maximum output acceleration amplitude for each supported frequency,
      *         starting at getMinimumFrequency()
+     * @deprecated This method is deprecated from AIDL v3 and is no longer required to be
+     * implemented even if CAP_FREQUENCY_CONTROL capability is reported.
      */
     float[] getBandwidthAmplitudeMap();
 
@@ -333,6 +339,8 @@
      *
      * @return The maximum duration allowed for a single PrimitivePwle.
      *         Non-zero value if supported, or value should be ignored if not supported.
+     * @deprecated This method is deprecated from AIDL v3 and is no longer required to be
+     * implemented. Use `IVibrator.getPwleV2PrimitiveDurationMaxMillis` instead.
      */
     int getPwlePrimitiveDurationMax();
 
@@ -344,6 +352,8 @@
      *
      * @return The maximum count allowed. Non-zero value if supported,
      *         or value should be ignored if not supported.
+     * @deprecated This method is deprecated from AIDL v3 and is no longer required to be
+     * implemented. Use `IVibrator.getPwleV2CompositionSizeMax` instead.
      */
     int getPwleCompositionSizeMax();
 
@@ -355,6 +365,8 @@
      * Implementations are optional but encouraged if available.
      *
      * @return The braking mechanisms which are supported by the composePwle API.
+     * @deprecated This method is deprecated from AIDL v3 and is no longer required to be
+     * implemented.
      */
     Braking[] getSupportedBraking();
 
@@ -368,6 +380,8 @@
      * explicitly call off. IVibratorCallback.onComplete() support is required for this API.
      *
      * @param composite Array of PWLEs.
+     * @deprecated This method is deprecated from AIDL v3 and is no longer required to be
+     * implemented. Use `IVibrator.composePwleV2` instead.
      */
     void composePwle(in PrimitivePwle[] composite, in IVibratorCallback callback);
 
@@ -396,12 +410,12 @@
      * Retrieves a mapping of vibration frequency (Hz) to the maximum achievable output
      * acceleration (Gs) the device can reach at that frequency.
      *
-     * The map, represented as a list of `PwleV2OutputMapEntry` (frequency, output acceleration)
-     * pairs, defines the device's frequency response. The platform uses the minimum and maximum
-     * frequency values to determine the supported input range for `IVibrator.composePwleV2`.
-     * Output acceleration values are used to identify a frequency range suitable to safely play
-     * perceivable vibrations with a simple API. The map is also exposed for developers using an
-     * advanced API.
+     * The map, represented as a list of `FrequencyAccelerationMapEntry` (frequency, output
+     * acceleration) pairs, defines the device's frequency response. The platform uses the minimum
+     * and maximum frequency values to determine the supported input range for
+     * `IVibrator.composePwleV2`. Output acceleration values are used to identify a frequency range
+     * suitable to safely play perceivable vibrations with a simple API. The map is also exposed for
+     * developers using an advanced API.
      *
      * The platform does not impose specific requirements on map resolution which can vary
      * depending on the shape of device output curve. The values will be linearly interpolated
@@ -410,7 +424,7 @@
      *
      *
      * This may not be supported and this support is reflected in getCapabilities
-     * (CAP_COMPOSE_PWLE_EFFECTS_V2). If this is supported, it's expected to be non-empty and
+     * (CAP_FREQUENCY_CONTROL). If this is supported, it's expected to be non-empty and
      * describe a valid non-empty frequency range where the simple API can be defined
      * (i.e. a range where the output acceleration is always above 10 db SL).
      *
@@ -418,7 +432,7 @@
      *         mapping.
      * @throws EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities.
      */
-    List<PwleV2OutputMapEntry> getPwleV2FrequencyToOutputAccelerationMap();
+    List<FrequencyAccelerationMapEntry> getFrequencyToOutputAccelerationMap();
 
     /**
      * Retrieve the maximum duration allowed for any primitive PWLE in units of
@@ -436,8 +450,8 @@
      * Retrieve the maximum number of PWLE primitives input supported by IVibrator.composePwleV2.
      *
      * This may not be supported and this support is reflected in
-     * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS_V2). Devices supporting PWLE effects must
-     * support effects with at least 16 PwleV2Primitive.
+     * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS_V2). Devices supporting
+     * PWLE effects must support effects with at least 16 PwleV2Primitive.
      *
      * @return The maximum count allowed. Non-zero value if supported.
      * @throws EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities.
@@ -458,15 +472,23 @@
     int getPwleV2PrimitiveDurationMinMillis();
 
     /**
-     * Play composed sequence of chirps with optional callback upon completion.
+     * Play composed sequence of PWLEs with optional callback upon completion.
+     *
+     * A PWLE (Piecewise-Linear Envelope) effect defines a vibration waveform using amplitude and
+     * frequency points. The envelope linearly interpolates both amplitude and frequency between
+     * consecutive points, creating smooth transitions in the vibration pattern.
      *
      * This may not be supported and this support is reflected in
      * getCapabilities (CAP_COMPOSE_PWLE_EFFECTS_V2).
      *
+     * Note: Devices reporting CAP_COMPOSE_PWLE_EFFECTS_V2 support MUST also have the
+     * CAP_FREQUENCY_CONTROL capability and provide a valid frequency to output acceleration map.
+     *
      * Doing this operation while the vibrator is already on is undefined behavior. Clients should
      * explicitly call off. IVibratorCallback.onComplete() support is required for this API.
      *
-     * @param composite An array of primitives that represents a PWLE (Piecewise-Linear Envelope).
+     * @param composite A CompositePwleV2 representing a composite vibration effect, composed of an
+     *                  array of primitives that define the PWLE (Piecewise-Linear Envelope).
      */
-    void composePwleV2(in PwleV2Primitive[] composite, in IVibratorCallback callback);
+    void composePwleV2(in CompositePwleV2 composite, in IVibratorCallback callback);
 }
diff --git a/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl b/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl
index eb5e9cc..e8b85c5 100644
--- a/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/IVibratorManager.aidl
@@ -16,8 +16,10 @@
 
 package android.hardware.vibrator;
 
+import android.hardware.vibrator.IVibrationSession;
 import android.hardware.vibrator.IVibrator;
 import android.hardware.vibrator.IVibratorCallback;
+import android.hardware.vibrator.VibrationSessionConfig;
 
 @VintfStability
 interface IVibratorManager {
@@ -42,17 +44,23 @@
      */
     const int CAP_MIXED_TRIGGER_ON = 1 << 4;
     /**
-     * Whether IVibrator 'perform' can be triggered with other functions in sync with 'triggerSynced'.
+     * Whether IVibrator 'perform' can be triggered with other functions in sync with
+     * 'triggerSynced'.
      */
     const int CAP_MIXED_TRIGGER_PERFORM = 1 << 5;
     /**
-     * Whether IVibrator 'compose' can be triggered with other functions in sync with 'triggerSynced'.
+     * Whether IVibrator 'compose' can be triggered with other functions in sync with
+     * 'triggerSynced'.
      */
     const int CAP_MIXED_TRIGGER_COMPOSE = 1 << 6;
     /**
      * Whether on w/ IVibratorCallback can be used w/ 'trigerSynced' function.
      */
     const int CAP_TRIGGER_CALLBACK = 1 << 7;
+    /**
+     * Whether vibration sessions are supported.
+     */
+    const int CAP_START_SESSIONS = 1 << 8;
 
     /**
      * Determine capabilities of the vibrator manager HAL (CAP_* mask)
@@ -75,8 +83,8 @@
      * This function must only be called after the previous synced vibration was triggered or
      * canceled (through cancelSynced()).
      *
-     * Doing this operation while any of the specified vibrators is already on is undefined behavior.
-     * Clients should explicitly call off in each vibrator.
+     * Doing this operation while any of the specified vibrators is already on is undefined
+     * behavior. Clients should explicitly call off in each vibrator.
      *
      * @param vibratorIds ids of the vibrators to play vibrations in sync.
      */
@@ -99,4 +107,41 @@
      * Cancel a previously-started preparation for synced vibration, if any.
      */
     void cancelSynced();
+
+    /**
+     * Start a vibration session.
+     *
+     * A vibration session can be used to send commands without resetting the vibrator state. Once a
+     * session starts, the individual vibrators can receive one or more commands like on(),
+     * performEffect(), setAmplitude(), etc. The vibrations performed in a session must have the
+     * same behavior they have outside them. Multiple commands can be synced in a session via
+     * prepareSynced as usual.
+     *
+     * Starting a session on a vibrator already in another session or in a prepareSynced state is
+     * not allowed and should throw illegal state. The end of a session should always notify the
+     * callback provided, even if it ends prematurely due to an error.
+     *
+     * This may not be supported and this support is reflected in
+     * getCapabilities (CAP_START_SESSIONS). IVibratorCallback.onComplete() support is required for
+     * this API.
+     *
+     * @param vibratorIds ids of the vibrators in the session.
+     * @param config The parameters for starting a vibration session.
+     * @param callback A callback used to inform Frameworks of state change.
+     * @throws :
+     *         - EX_UNSUPPORTED_OPERATION if unsupported, as reflected by getCapabilities.
+     *         - EX_ILLEGAL_ARGUMENT for invalid vibrator IDs.
+     *         - EX_ILLEGAL_STATE for vibrator IDs already in a session or in a prepareSynced state.
+     *         - EX_SERVICE_SPECIFIC for bad vendor data.
+     */
+    IVibrationSession startSession(
+            in int[] vibratorIds, in VibrationSessionConfig config, in IVibratorCallback callback);
+
+    /**
+     * Abort and clear all ongoing vibration sessions.
+     *
+     * This can be used to reset the vibrator manager and some individual vibrators to an idle
+     * state.
+     */
+    void clearSessions();
 }
diff --git a/vibrator/aidl/android/hardware/vibrator/PwleV2Primitive.aidl b/vibrator/aidl/android/hardware/vibrator/PwleV2Primitive.aidl
index bd7bec6..1ad1a9f 100644
--- a/vibrator/aidl/android/hardware/vibrator/PwleV2Primitive.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/PwleV2Primitive.aidl
@@ -21,7 +21,7 @@
     /**
      * Input amplitude ranges from 0.0 (inclusive) to 1.0 (inclusive), representing the relative
      * input value. Actual output acceleration depends on frequency and device response curve
-     * (see IVibrator.getPwleV2FrequencyToOutputAccelerationMap for max values).
+     * (see IVibrator.getFrequencyToOutputAccelerationMap for max values).
      *
      * Input amplitude linearly maps to output acceleration (e.g., 0.5 amplitude yields half the
      * max acceleration for that frequency).
@@ -36,7 +36,7 @@
      * Absolute frequency point in the units of hertz
      *
      * Values are within the continuous inclusive frequency range defined by
-     * IVibrator#getPwleV2FrequencyToOutputAccelerationMap.
+     * IVibrator#getFrequencyToOutputAccelerationMap.
      */
     float frequencyHz;
 
diff --git a/vibrator/aidl/android/hardware/vibrator/VibrationSessionConfig.aidl b/vibrator/aidl/android/hardware/vibrator/VibrationSessionConfig.aidl
new file mode 100644
index 0000000..56cdde3
--- /dev/null
+++ b/vibrator/aidl/android/hardware/vibrator/VibrationSessionConfig.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.vibrator;
+
+@VintfStability
+parcelable VibrationSessionConfig {
+    /**
+     * Vendor extension point for starting a vibration session.
+     */
+    ParcelableHolder vendorExtension;
+}
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index b25a5ba..de228cd 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -19,6 +19,7 @@
     ],
     export_include_dirs: ["include"],
     srcs: [
+        "VibrationSession.cpp",
         "Vibrator.cpp",
         "VibratorManager.cpp",
     ],
diff --git a/vibrator/aidl/default/VibrationSession.cpp b/vibrator/aidl/default/VibrationSession.cpp
new file mode 100644
index 0000000..4eac831
--- /dev/null
+++ b/vibrator/aidl/default/VibrationSession.cpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#include "vibrator-impl/VibrationSession.h"
+
+#include <android-base/logging.h>
+#include <thread>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace vibrator {
+
+static constexpr int32_t SESSION_END_DELAY_MS = 20;
+
+ndk::ScopedAStatus VibrationSession::close() {
+    LOG(VERBOSE) << "Vibration Session close";
+    mManager->closeSession(SESSION_END_DELAY_MS);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VibrationSession::abort() {
+    LOG(VERBOSE) << "Vibration Session abort";
+    mManager->abortSession();
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace vibrator
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index 4f8c2b8..165a3bf 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -45,11 +45,62 @@
 // Service specific error code used for vendor vibration effects.
 static constexpr int32_t ERROR_CODE_INVALID_DURATION = 1;
 
+void Vibrator::dispatchVibrate(int32_t timeoutMs,
+                               const std::shared_ptr<IVibratorCallback>& callback) {
+    std::lock_guard lock(mMutex);
+    if (mIsVibrating) {
+        // Already vibrating, ignore new request.
+        return;
+    }
+    mVibrationCallback = callback;
+    mIsVibrating = true;
+    // Note that thread lambdas aren't using implicit capture [=], to avoid capturing "this",
+    // which may be asynchronously destructed.
+    std::thread([timeoutMs, callback, sharedThis = this->ref<Vibrator>()] {
+        LOG(VERBOSE) << "Starting delayed callback on another thread";
+        usleep(timeoutMs * 1000);
+
+        if (sharedThis) {
+            std::lock_guard lock(sharedThis->mMutex);
+            sharedThis->mIsVibrating = false;
+            if (sharedThis->mVibrationCallback && (callback == sharedThis->mVibrationCallback)) {
+                LOG(VERBOSE) << "Notifying callback onComplete";
+                if (!sharedThis->mVibrationCallback->onComplete().isOk()) {
+                    LOG(ERROR) << "Failed to call onComplete";
+                }
+                sharedThis->mVibrationCallback = nullptr;
+            }
+            if (sharedThis->mGlobalVibrationCallback) {
+                LOG(VERBOSE) << "Notifying global callback onComplete";
+                if (!sharedThis->mGlobalVibrationCallback->onComplete().isOk()) {
+                    LOG(ERROR) << "Failed to call onComplete";
+                }
+                sharedThis->mGlobalVibrationCallback = nullptr;
+            }
+        }
+    }).detach();
+}
+
+void Vibrator::setGlobalVibrationCallback(const std::shared_ptr<IVibratorCallback>& callback) {
+    std::lock_guard lock(mMutex);
+    if (mIsVibrating) {
+        mGlobalVibrationCallback = callback;
+    } else if (callback) {
+        std::thread([callback] {
+            LOG(VERBOSE) << "Notifying global callback onComplete";
+            if (!callback->onComplete().isOk()) {
+                LOG(ERROR) << "Failed to call onComplete";
+            }
+        }).detach();
+    }
+}
+
 ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
     LOG(VERBOSE) << "Vibrator reporting capabilities";
     std::lock_guard lock(mMutex);
     if (mCapabilities == 0) {
-        if (!getInterfaceVersion(&mVersion).isOk()) {
+        int32_t version;
+        if (!getInterfaceVersion(&version).isOk()) {
             return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_STATE));
         }
         mCapabilities = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
@@ -59,9 +110,9 @@
                         IVibrator::CAP_GET_Q_FACTOR | IVibrator::CAP_FREQUENCY_CONTROL |
                         IVibrator::CAP_COMPOSE_PWLE_EFFECTS;
 
-        if (mVersion >= 3) {
-            mCapabilities |= (IVibrator::CAP_PERFORM_VENDOR_EFFECTS |
-                              IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2);
+        if (version >= 3) {
+            mCapabilities |=
+                    IVibrator::CAP_PERFORM_VENDOR_EFFECTS | IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2;
         }
     }
 
@@ -71,25 +122,35 @@
 
 ndk::ScopedAStatus Vibrator::off() {
     LOG(VERBOSE) << "Vibrator off";
+    std::lock_guard lock(mMutex);
+    std::shared_ptr<IVibratorCallback> callback = mVibrationCallback;
+    std::shared_ptr<IVibratorCallback> globalCallback = mGlobalVibrationCallback;
+    mIsVibrating = false;
+    mVibrationCallback = nullptr;
+    mGlobalVibrationCallback = nullptr;
+    if (callback || globalCallback) {
+        std::thread([callback, globalCallback] {
+            if (callback) {
+                LOG(VERBOSE) << "Notifying callback onComplete";
+                if (!callback->onComplete().isOk()) {
+                    LOG(ERROR) << "Failed to call onComplete";
+                }
+            }
+            if (globalCallback) {
+                LOG(VERBOSE) << "Notifying global callback onComplete";
+                if (!globalCallback->onComplete().isOk()) {
+                    LOG(ERROR) << "Failed to call onComplete";
+                }
+            }
+        }).detach();
+    }
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs,
                                 const std::shared_ptr<IVibratorCallback>& callback) {
     LOG(VERBOSE) << "Vibrator on for timeoutMs: " << timeoutMs;
-    if (callback != nullptr) {
-        // Note that thread lambdas aren't using implicit capture [=], to avoid capturing "this",
-        // which may be asynchronously destructed.
-        // If "this" is needed, use [sharedThis = this->ref<Vibrator>()].
-        std::thread([timeoutMs, callback] {
-            LOG(VERBOSE) << "Starting on on another thread";
-            usleep(timeoutMs * 1000);
-            LOG(VERBOSE) << "Notifying on complete";
-            if (!callback->onComplete().isOk()) {
-                LOG(ERROR) << "Failed to call onComplete";
-            }
-        }).detach();
-    }
+    dispatchVibrate(timeoutMs, callback);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -107,16 +168,7 @@
     }
 
     constexpr size_t kEffectMillis = 100;
-
-    if (callback != nullptr) {
-        std::thread([callback] {
-            LOG(VERBOSE) << "Starting perform on another thread";
-            usleep(kEffectMillis * 1000);
-            LOG(VERBOSE) << "Notifying perform complete";
-            callback->onComplete();
-        }).detach();
-    }
-
+    dispatchVibrate(kEffectMillis, callback);
     *_aidl_return = kEffectMillis;
     return ndk::ScopedAStatus::ok();
 }
@@ -150,15 +202,7 @@
         return ndk::ScopedAStatus::fromServiceSpecificError(ERROR_CODE_INVALID_DURATION);
     }
 
-    if (callback != nullptr) {
-        std::thread([callback, durationMs] {
-            LOG(VERBOSE) << "Starting perform on another thread for durationMs:" << durationMs;
-            usleep(durationMs * 1000);
-            LOG(VERBOSE) << "Notifying perform vendor effect complete";
-            callback->onComplete();
-        }).detach();
-    }
-
+    dispatchVibrate(durationMs, callback);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -237,28 +281,14 @@
         }
     }
 
-    // The thread may theoretically outlive the vibrator, so take a proper reference to it.
-    std::thread([sharedThis = this->ref<Vibrator>(), composite, callback] {
-        LOG(VERBOSE) << "Starting compose on another thread";
+    int32_t totalDuration = 0;
+    for (auto& e : composite) {
+        int32_t durationMs;
+        getPrimitiveDuration(e.primitive, &durationMs);
+        totalDuration += e.delayMs + durationMs;
+    }
 
-        for (auto& e : composite) {
-            if (e.delayMs) {
-                usleep(e.delayMs * 1000);
-            }
-            LOG(VERBOSE) << "triggering primitive " << static_cast<int>(e.primitive) << " @ scale "
-                         << e.scale;
-
-            int32_t durationMs;
-            sharedThis->getPrimitiveDuration(e.primitive, &durationMs);
-            usleep(durationMs * 1000);
-        }
-
-        if (callback != nullptr) {
-            LOG(VERBOSE) << "Notifying perform complete";
-            callback->onComplete();
-        }
-    }).detach();
-
+    dispatchVibrate(totalDuration, callback);
     return ndk::ScopedAStatus::ok();
 }
 
@@ -460,21 +490,21 @@
         }
     }
 
-    std::thread([totalDuration, callback] {
-        LOG(VERBOSE) << "Starting composePwle on another thread";
-        usleep(totalDuration * 1000);
-        if (callback != nullptr) {
-            LOG(VERBOSE) << "Notifying compose PWLE complete";
-            callback->onComplete();
-        }
-    }).detach();
-
+    dispatchVibrate(totalDuration, callback);
     return ndk::ScopedAStatus::ok();
 }
 
-ndk::ScopedAStatus Vibrator::getPwleV2FrequencyToOutputAccelerationMap(
-        std::vector<PwleV2OutputMapEntry>* _aidl_return) {
-    std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
+ndk::ScopedAStatus Vibrator::getFrequencyToOutputAccelerationMap(
+        std::vector<FrequencyAccelerationMapEntry>* _aidl_return) {
+    int32_t capabilities = 0;
+    if (!getCapabilities(&capabilities).isOk()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    if (!(capabilities & IVibrator::CAP_FREQUENCY_CONTROL)) {
+        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+    }
+
+    std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap;
 
     std::vector<std::pair<float, float>> frequencyToOutputAccelerationData = {
             {30.0f, 0.01f},  {46.0f, 0.09f},  {50.0f, 0.1f},   {55.0f, 0.12f},  {62.0f, 0.66f},
@@ -485,8 +515,8 @@
             {263.0f, 1.39f}, {65.0f, 1.38f},  {278.0f, 1.37f}, {294.0f, 1.35f}, {300.0f, 1.34f}};
     for (const auto& entry : frequencyToOutputAccelerationData) {
         frequencyToOutputAccelerationMap.push_back(
-                PwleV2OutputMapEntry(/*frequency=*/entry.first,
-                                     /*maxOutputAcceleration=*/entry.second));
+                FrequencyAccelerationMapEntry(/*frequency=*/entry.first,
+                                              /*maxOutputAcceleration=*/entry.second));
     }
 
     *_aidl_return = frequencyToOutputAccelerationMap;
@@ -509,7 +539,8 @@
     return ndk::ScopedAStatus::ok();
 }
 
-float getPwleV2FrequencyMinHz(std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap) {
+float getPwleV2FrequencyMinHz(
+        std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap) {
     if (frequencyToOutputAccelerationMap.empty()) {
         return 0.0f;
     }
@@ -525,7 +556,8 @@
     return minFrequency;
 }
 
-float getPwleV2FrequencyMaxHz(std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap) {
+float getPwleV2FrequencyMaxHz(
+        std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap) {
     if (frequencyToOutputAccelerationMap.empty()) {
         return 0.0f;
     }
@@ -541,29 +573,31 @@
     return maxFrequency;
 }
 
-ndk::ScopedAStatus Vibrator::composePwleV2(const std::vector<PwleV2Primitive>& composite,
+ndk::ScopedAStatus Vibrator::composePwleV2(const CompositePwleV2& composite,
                                            const std::shared_ptr<IVibratorCallback>& callback) {
+    LOG(VERBOSE) << "Vibrator compose PWLE V2";
     int32_t capabilities = 0;
     if (!getCapabilities(&capabilities).isOk()) {
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     }
-    if ((capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) == 0) {
+    if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) ||
+        !(capabilities & IVibrator::CAP_FREQUENCY_CONTROL)) {
         return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
     }
 
     int compositionSizeMax;
     getPwleV2CompositionSizeMax(&compositionSizeMax);
-    if (composite.size() <= 0 || composite.size() > compositionSizeMax) {
+    if (composite.pwlePrimitives.empty() || composite.pwlePrimitives.size() > compositionSizeMax) {
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
 
     int32_t totalEffectDuration = 0;
-    std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
-    getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
+    std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap;
+    getFrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
     float minFrequency = getPwleV2FrequencyMinHz(frequencyToOutputAccelerationMap);
     float maxFrequency = getPwleV2FrequencyMaxHz(frequencyToOutputAccelerationMap);
 
-    for (auto& e : composite) {
+    for (auto& e : composite.pwlePrimitives) {
         if (e.timeMillis < 0.0f || e.timeMillis > COMPOSE_PWLE_V2_PRIMITIVE_DURATION_MAX_MS) {
             return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
         }
@@ -576,15 +610,7 @@
         totalEffectDuration += e.timeMillis;
     }
 
-    std::thread([totalEffectDuration, callback] {
-        LOG(VERBOSE) << "Starting composePwleV2 on another thread";
-        usleep(totalEffectDuration * 1000);
-        if (callback != nullptr) {
-            LOG(VERBOSE) << "Notifying compose PWLE V2 complete";
-            callback->onComplete();
-        }
-    }).detach();
-
+    dispatchVibrate(totalEffectDuration, callback);
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/vibrator/aidl/default/VibratorManager.cpp b/vibrator/aidl/default/VibratorManager.cpp
index 26edf5a..c3be468 100644
--- a/vibrator/aidl/default/VibratorManager.cpp
+++ b/vibrator/aidl/default/VibratorManager.cpp
@@ -15,6 +15,9 @@
  */
 
 #include "vibrator-impl/VibratorManager.h"
+#include "vibrator-impl/VibrationSession.h"
+
+#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
 
 #include <android-base/logging.h>
 #include <thread>
@@ -26,25 +29,52 @@
 
 static constexpr int32_t kDefaultVibratorId = 1;
 
+class VibratorCallback : public BnVibratorCallback {
+  public:
+    VibratorCallback(const std::function<void()>& callback) : mCallback(callback) {}
+    ndk::ScopedAStatus onComplete() override {
+        mCallback();
+        return ndk::ScopedAStatus::ok();
+    }
+
+  private:
+    std::function<void()> mCallback;
+};
+
 ndk::ScopedAStatus VibratorManager::getCapabilities(int32_t* _aidl_return) {
-    LOG(INFO) << "Vibrator manager reporting capabilities";
-    *_aidl_return =
-            IVibratorManager::CAP_SYNC | IVibratorManager::CAP_PREPARE_ON |
-            IVibratorManager::CAP_PREPARE_PERFORM | IVibratorManager::CAP_PREPARE_COMPOSE |
-            IVibratorManager::CAP_MIXED_TRIGGER_ON | IVibratorManager::CAP_MIXED_TRIGGER_PERFORM |
-            IVibratorManager::CAP_MIXED_TRIGGER_COMPOSE | IVibratorManager::CAP_TRIGGER_CALLBACK;
+    LOG(VERBOSE) << "Vibrator manager reporting capabilities";
+    std::lock_guard lock(mMutex);
+    if (mCapabilities == 0) {
+        int32_t version;
+        if (!getInterfaceVersion(&version).isOk()) {
+            return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_STATE));
+        }
+        mCapabilities = IVibratorManager::CAP_SYNC | IVibratorManager::CAP_PREPARE_ON |
+                        IVibratorManager::CAP_PREPARE_PERFORM |
+                        IVibratorManager::CAP_PREPARE_COMPOSE |
+                        IVibratorManager::CAP_MIXED_TRIGGER_ON |
+                        IVibratorManager::CAP_MIXED_TRIGGER_PERFORM |
+                        IVibratorManager::CAP_MIXED_TRIGGER_COMPOSE |
+                        IVibratorManager::CAP_TRIGGER_CALLBACK;
+
+        if (version >= 3) {
+            mCapabilities |= IVibratorManager::CAP_START_SESSIONS;
+        }
+    }
+
+    *_aidl_return = mCapabilities;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus VibratorManager::getVibratorIds(std::vector<int32_t>* _aidl_return) {
-    LOG(INFO) << "Vibrator manager getting vibrator ids";
+    LOG(VERBOSE) << "Vibrator manager getting vibrator ids";
     *_aidl_return = {kDefaultVibratorId};
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus VibratorManager::getVibrator(int32_t vibratorId,
                                                 std::shared_ptr<IVibrator>* _aidl_return) {
-    LOG(INFO) << "Vibrator manager getting vibrator " << vibratorId;
+    LOG(VERBOSE) << "Vibrator manager getting vibrator " << vibratorId;
     if (vibratorId == kDefaultVibratorId) {
         *_aidl_return = mDefaultVibrator;
         return ndk::ScopedAStatus::ok();
@@ -55,32 +85,131 @@
 }
 
 ndk::ScopedAStatus VibratorManager::prepareSynced(const std::vector<int32_t>& vibratorIds) {
-    LOG(INFO) << "Vibrator Manager prepare synced";
-    if (vibratorIds.size() == 1 && vibratorIds[0] == kDefaultVibratorId) {
-        return ndk::ScopedAStatus::ok();
-    } else {
+    LOG(VERBOSE) << "Vibrator Manager prepare synced";
+    if (vibratorIds.size() != 1 || vibratorIds[0] != kDefaultVibratorId) {
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
+    std::lock_guard lock(mMutex);
+    if (mIsPreparing) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    mIsPreparing = true;
+    return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus VibratorManager::triggerSynced(
         const std::shared_ptr<IVibratorCallback>& callback) {
-    LOG(INFO) << "Vibrator Manager trigger synced";
+    LOG(VERBOSE) << "Vibrator Manager trigger synced";
+    std::lock_guard lock(mMutex);
+    if (!mIsPreparing) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
     std::thread([callback] {
         if (callback != nullptr) {
-            LOG(INFO) << "Notifying perform complete";
+            LOG(VERBOSE) << "Notifying perform complete";
             callback->onComplete();
         }
     }).detach();
-
+    mIsPreparing = false;
     return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus VibratorManager::cancelSynced() {
-    LOG(INFO) << "Vibrator Manager cancel synced";
+    LOG(VERBOSE) << "Vibrator Manager cancel synced";
+    std::lock_guard lock(mMutex);
+    mIsPreparing = false;
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus VibratorManager::startSession(const std::vector<int32_t>& vibratorIds,
+                                                 const VibrationSessionConfig&,
+                                                 const std::shared_ptr<IVibratorCallback>& callback,
+                                                 std::shared_ptr<IVibrationSession>* _aidl_return) {
+    LOG(VERBOSE) << "Vibrator Manager start session";
+    *_aidl_return = nullptr;
+    int32_t capabilities = 0;
+    if (!getCapabilities(&capabilities).isOk()) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    if ((capabilities & IVibratorManager::CAP_START_SESSIONS) == 0) {
+        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_UNSUPPORTED_OPERATION));
+    }
+    if (vibratorIds.size() != 1 || vibratorIds[0] != kDefaultVibratorId) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    std::lock_guard lock(mMutex);
+    if (mIsPreparing || mSession) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    mSessionCallback = callback;
+    mSession = ndk::SharedRefBase::make<VibrationSession>(this->ref<VibratorManager>());
+    *_aidl_return = static_cast<std::shared_ptr<IVibrationSession>>(mSession);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus VibratorManager::clearSessions() {
+    LOG(VERBOSE) << "Vibrator Manager clear sessions";
+    abortSession();
+    return ndk::ScopedAStatus::ok();
+}
+
+void VibratorManager::abortSession() {
+    std::shared_ptr<IVibrationSession> session;
+    {
+        std::lock_guard lock(mMutex);
+        session = mSession;
+    }
+    if (session) {
+        mDefaultVibrator->off();
+        clearSession(session);
+    }
+}
+
+void VibratorManager::closeSession(int32_t delayMs) {
+    std::shared_ptr<IVibrationSession> session;
+    {
+        std::lock_guard lock(mMutex);
+        if (mIsClosingSession) {
+            // Already closing session, ignore this.
+            return;
+        }
+        session = mSession;
+        mIsClosingSession = true;
+    }
+    if (session) {
+        auto callback = ndk::SharedRefBase::make<VibratorCallback>(
+                [session, delayMs, sharedThis = this->ref<VibratorManager>()] {
+                    LOG(VERBOSE) << "Closing session after vibrator became idle";
+                    usleep(delayMs * 1000);
+
+                    if (sharedThis) {
+                        sharedThis->clearSession(session);
+                    }
+                });
+        mDefaultVibrator->setGlobalVibrationCallback(callback);
+    }
+}
+
+void VibratorManager::clearSession(const std::shared_ptr<IVibrationSession>& session) {
+    std::lock_guard lock(mMutex);
+    if (mSession != session) {
+        // Probably a delayed call from an old session that was already cleared, ignore it.
+        return;
+    }
+    std::shared_ptr<IVibratorCallback> callback = mSessionCallback;
+    mSession = nullptr;
+    mSessionCallback = nullptr;  // make sure any delayed call will not trigger this again.
+    mIsClosingSession = false;
+    if (callback) {
+        std::thread([callback] {
+            LOG(VERBOSE) << "Notifying session complete";
+            if (!callback->onComplete().isOk()) {
+                LOG(ERROR) << "Failed to call onComplete";
+            }
+        }).detach();
+    }
+}
+
 }  // namespace vibrator
 }  // namespace hardware
 }  // namespace android
diff --git a/vibrator/aidl/default/include/vibrator-impl/VibrationSession.h b/vibrator/aidl/default/include/vibrator-impl/VibrationSession.h
new file mode 100644
index 0000000..98bdd1c
--- /dev/null
+++ b/vibrator/aidl/default/include/vibrator-impl/VibrationSession.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/vibrator/BnVibrationSession.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibratorCallback.h>
+#include <android-base/thread_annotations.h>
+
+#include "vibrator-impl/VibratorManager.h"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace vibrator {
+
+class VibrationSession : public BnVibrationSession {
+  public:
+    VibrationSession(std::shared_ptr<VibratorManager> manager) : mManager(std::move(manager)) {};
+
+    ndk::ScopedAStatus close() override;
+    ndk::ScopedAStatus abort() override;
+
+  private:
+    mutable std::mutex mMutex;
+    std::shared_ptr<VibratorManager> mManager;
+};
+
+}  // namespace vibrator
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
index 28bc763..354ba46 100644
--- a/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
+++ b/vibrator/aidl/default/include/vibrator-impl/Vibrator.h
@@ -25,6 +25,7 @@
 namespace vibrator {
 
 class Vibrator : public BnVibrator {
+  public:
     ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override;
     ndk::ScopedAStatus off() override;
     ndk::ScopedAStatus on(int32_t timeoutMs,
@@ -58,18 +59,24 @@
     ndk::ScopedAStatus getSupportedBraking(std::vector<Braking>* supported) override;
     ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle> &composite,
                                    const std::shared_ptr<IVibratorCallback> &callback) override;
-    ndk::ScopedAStatus getPwleV2FrequencyToOutputAccelerationMap(
-            std::vector<PwleV2OutputMapEntry>* _aidl_return) override;
+    ndk::ScopedAStatus getFrequencyToOutputAccelerationMap(
+            std::vector<FrequencyAccelerationMapEntry>* _aidl_return) override;
     ndk::ScopedAStatus getPwleV2PrimitiveDurationMaxMillis(int32_t* maxDurationMs) override;
     ndk::ScopedAStatus getPwleV2PrimitiveDurationMinMillis(int32_t* minDurationMs) override;
     ndk::ScopedAStatus getPwleV2CompositionSizeMax(int32_t* maxSize) override;
-    ndk::ScopedAStatus composePwleV2(const std::vector<PwleV2Primitive>& composite,
+    ndk::ScopedAStatus composePwleV2(const CompositePwleV2& composite,
                                      const std::shared_ptr<IVibratorCallback>& callback) override;
 
+    void setGlobalVibrationCallback(const std::shared_ptr<IVibratorCallback>& callback);
+
   private:
     mutable std::mutex mMutex;
-    int32_t mVersion GUARDED_BY(mMutex) = 0;  // current Hal version
+    bool mIsVibrating GUARDED_BY(mMutex) = false;
     int32_t mCapabilities GUARDED_BY(mMutex) = 0;
+    std::shared_ptr<IVibratorCallback> mVibrationCallback GUARDED_BY(mMutex) = nullptr;
+    std::shared_ptr<IVibratorCallback> mGlobalVibrationCallback GUARDED_BY(mMutex) = nullptr;
+
+    void dispatchVibrate(int32_t timeoutMs, const std::shared_ptr<IVibratorCallback>& callback);
 };
 
 }  // namespace vibrator
diff --git a/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h b/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h
index 319eb05..fe30394 100644
--- a/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h
+++ b/vibrator/aidl/default/include/vibrator-impl/VibratorManager.h
@@ -17,6 +17,9 @@
 #pragma once
 
 #include <aidl/android/hardware/vibrator/BnVibratorManager.h>
+#include <android-base/thread_annotations.h>
+
+#include "vibrator-impl/Vibrator.h"
 
 namespace aidl {
 namespace android {
@@ -25,7 +28,8 @@
 
 class VibratorManager : public BnVibratorManager {
   public:
-    VibratorManager(std::shared_ptr<IVibrator> vibrator) : mDefaultVibrator(std::move(vibrator)){};
+    VibratorManager(std::shared_ptr<Vibrator> vibrator) : mDefaultVibrator(std::move(vibrator)) {};
+
     ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override;
     ndk::ScopedAStatus getVibratorIds(std::vector<int32_t>* _aidl_return) override;
     ndk::ScopedAStatus getVibrator(int32_t vibratorId,
@@ -33,9 +37,25 @@
     ndk::ScopedAStatus prepareSynced(const std::vector<int32_t>& vibratorIds) override;
     ndk::ScopedAStatus triggerSynced(const std::shared_ptr<IVibratorCallback>& callback) override;
     ndk::ScopedAStatus cancelSynced() override;
+    ndk::ScopedAStatus startSession(const std::vector<int32_t>& vibratorIds,
+                                    const VibrationSessionConfig& config,
+                                    const std::shared_ptr<IVibratorCallback>& callback,
+                                    std::shared_ptr<IVibrationSession>* _aidl_return) override;
+    ndk::ScopedAStatus clearSessions() override;
+
+    void abortSession();
+    void closeSession(int32_t delayMs);
 
   private:
-    std::shared_ptr<IVibrator> mDefaultVibrator;
+    std::shared_ptr<Vibrator> mDefaultVibrator;
+    mutable std::mutex mMutex;
+    int32_t mCapabilities GUARDED_BY(mMutex) = 0;
+    bool mIsPreparing GUARDED_BY(mMutex) = false;
+    bool mIsClosingSession GUARDED_BY(mMutex) = false;
+    std::shared_ptr<IVibrationSession> mSession GUARDED_BY(mMutex) = nullptr;
+    std::shared_ptr<IVibratorCallback> mSessionCallback GUARDED_BY(mMutex) = nullptr;
+
+    void clearSession(const std::shared_ptr<IVibrationSession>& session);
 };
 
 }  // namespace vibrator
diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
index 3c2a360..101d4f5 100644
--- a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
@@ -16,12 +16,14 @@
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
+#include <aidl/android/hardware/vibrator/IVibrationSession.h>
 #include <aidl/android/hardware/vibrator/IVibrator.h>
 #include <aidl/android/hardware/vibrator/IVibratorManager.h>
 
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 
+#include <algorithm>
 #include <cmath>
 #include <future>
 
@@ -32,10 +34,14 @@
 using aidl::android::hardware::vibrator::CompositePrimitive;
 using aidl::android::hardware::vibrator::Effect;
 using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::IVibrationSession;
 using aidl::android::hardware::vibrator::IVibrator;
 using aidl::android::hardware::vibrator::IVibratorManager;
+using aidl::android::hardware::vibrator::VibrationSessionConfig;
 using std::chrono::high_resolution_clock;
 
+using namespace ::std::chrono_literals;
+
 const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
                                    ndk::enum_range<Effect>().end()};
 const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
@@ -43,6 +49,11 @@
 const std::vector<CompositePrimitive> kPrimitives{ndk::enum_range<CompositePrimitive>().begin(),
                                                   ndk::enum_range<CompositePrimitive>().end()};
 
+// Timeout to wait for vibration callback completion.
+static constexpr std::chrono::milliseconds VIBRATION_CALLBACK_TIMEOUT = 100ms;
+
+static constexpr int32_t VIBRATION_SESSIONS_MIN_VERSION = 3;
+
 class CompletionCallback : public BnVibratorCallback {
   public:
     CompletionCallback(const std::function<void()>& callback) : mCallback(callback) {}
@@ -64,9 +75,29 @@
         ASSERT_NE(manager, nullptr);
         EXPECT_OK(manager->getCapabilities(&capabilities));
         EXPECT_OK(manager->getVibratorIds(&vibratorIds));
+        EXPECT_OK(manager->getInterfaceVersion(&version));
+    }
+
+    virtual void TearDown() override {
+        // Reset manager state between tests.
+        if (capabilities & IVibratorManager::CAP_SYNC) {
+            manager->cancelSynced();
+        }
+        if (capabilities & IVibratorManager::CAP_START_SESSIONS) {
+            manager->clearSessions();
+        }
+        // Reset all managed vibrators.
+        for (int32_t id : vibratorIds) {
+            std::shared_ptr<IVibrator> vibrator;
+            EXPECT_OK(manager->getVibrator(id, &vibrator));
+            ASSERT_NE(vibrator, nullptr);
+            EXPECT_OK(vibrator->off());
+        }
     }
 
     std::shared_ptr<IVibratorManager> manager;
+    std::shared_ptr<IVibrationSession> session;
+    int32_t version;
     int32_t capabilities;
     std::vector<int32_t> vibratorIds;
 };
@@ -109,7 +140,7 @@
     if (vibratorIds.empty()) return;
     if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
     if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) {
-        uint32_t durationMs = 250;
+        int32_t durationMs = 250;
         EXPECT_OK(manager->prepareSynced(vibratorIds));
         std::shared_ptr<IVibrator> vibrator;
         for (int32_t id : vibratorIds) {
@@ -170,7 +201,7 @@
     std::future<void> completionFuture{completionPromise.get_future()};
     auto callback = ndk::SharedRefBase::make<CompletionCallback>(
             [&completionPromise] { completionPromise.set_value(); });
-    uint32_t durationMs = 250;
+    int32_t durationMs = 250;
     std::chrono::milliseconds timeout{durationMs * 2};
 
     EXPECT_OK(manager->prepareSynced(vibratorIds));
@@ -202,6 +233,435 @@
     }
 }
 
+TEST_P(VibratorAidl, VibrationSessionsSupported) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    int32_t durationMs = 250;
+    std::vector<std::promise<void>> vibrationPromises;
+    std::vector<std::future<void>> vibrationFutures;
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+
+        std::promise<void>& vibrationPromise = vibrationPromises.emplace_back();
+        vibrationFutures.push_back(vibrationPromise.get_future());
+        auto vibrationCallback = ndk::SharedRefBase::make<CompletionCallback>(
+                [&vibrationPromise] { vibrationPromise.set_value(); });
+        EXPECT_OK(vibrator->on(durationMs, vibrationCallback));
+    }
+
+    auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
+    for (std::future<void>& future : vibrationFutures) {
+        EXPECT_EQ(future.wait_for(timeout), std::future_status::ready);
+    }
+
+    // Session callback not triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    // Ending a session should not take long since the vibration was already completed
+    EXPECT_OK(session->close());
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::ready);
+}
+
+TEST_P(VibratorAidl, VibrationSessionInterrupted) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    std::vector<std::promise<void>> vibrationPromises;
+    std::vector<std::future<void>> vibrationFutures;
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+
+        std::promise<void>& vibrationPromise = vibrationPromises.emplace_back();
+        vibrationFutures.push_back(vibrationPromise.get_future());
+        auto vibrationCallback = ndk::SharedRefBase::make<CompletionCallback>(
+                [&vibrationPromise] { vibrationPromise.set_value(); });
+
+        // Vibration longer than test timeout.
+        EXPECT_OK(vibrator->on(2000, vibrationCallback));
+    }
+
+    // Session callback not triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    // Interrupt vibrations and session.
+    EXPECT_OK(session->abort());
+
+    // Both callbacks triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::ready);
+    for (std::future<void>& future : vibrationFutures) {
+        EXPECT_EQ(future.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::ready);
+    }
+}
+
+TEST_P(VibratorAidl, VibrationSessionEndingInterrupted) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    std::vector<std::promise<void>> vibrationPromises;
+    std::vector<std::future<void>> vibrationFutures;
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+
+        std::promise<void>& vibrationPromise = vibrationPromises.emplace_back();
+        vibrationFutures.push_back(vibrationPromise.get_future());
+        auto vibrationCallback = ndk::SharedRefBase::make<CompletionCallback>(
+                [&vibrationPromise] { vibrationPromise.set_value(); });
+
+        // Vibration longer than test timeout.
+        EXPECT_OK(vibrator->on(2000, vibrationCallback));
+    }
+
+    // Session callback not triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    // End session, this might take a while
+    EXPECT_OK(session->close());
+
+    // Interrupt ending session.
+    EXPECT_OK(session->abort());
+
+    // Both callbacks triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::ready);
+    for (std::future<void>& future : vibrationFutures) {
+        EXPECT_EQ(future.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::ready);
+    }
+}
+
+TEST_P(VibratorAidl, VibrationSessionCleared) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    int32_t durationMs = 250;
+    std::vector<std::promise<void>> vibrationPromises;
+    std::vector<std::future<void>> vibrationFutures;
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+
+        std::promise<void>& vibrationPromise = vibrationPromises.emplace_back();
+        vibrationFutures.push_back(vibrationPromise.get_future());
+        auto vibrationCallback = ndk::SharedRefBase::make<CompletionCallback>(
+                [&vibrationPromise] { vibrationPromise.set_value(); });
+        EXPECT_OK(vibrator->on(durationMs, vibrationCallback));
+    }
+
+    // Session callback not triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    // Clearing sessions should abort ongoing session
+    EXPECT_OK(manager->clearSessions());
+
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::ready);
+    for (std::future<void>& future : vibrationFutures) {
+        EXPECT_EQ(future.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::ready);
+    }
+}
+
+TEST_P(VibratorAidl, VibrationSessionsClearedWithoutSession) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+
+    EXPECT_OK(manager->clearSessions());
+}
+
+TEST_P(VibratorAidl, VibrationSessionsWithSyncedVibrations) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_PREPARE_ON)) return;
+    if (!(capabilities & IVibratorManager::CAP_TRIGGER_CALLBACK)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    EXPECT_OK(manager->prepareSynced(vibratorIds));
+
+    int32_t durationMs = 250;
+    std::vector<std::promise<void>> vibrationPromises;
+    std::vector<std::future<void>> vibrationFutures;
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+
+        std::promise<void>& vibrationPromise = vibrationPromises.emplace_back();
+        vibrationFutures.push_back(vibrationPromise.get_future());
+        auto vibrationCallback = ndk::SharedRefBase::make<CompletionCallback>(
+                [&vibrationPromise] { vibrationPromise.set_value(); });
+        EXPECT_OK(vibrator->on(durationMs, vibrationCallback));
+    }
+
+    std::promise<void> triggerPromise;
+    std::future<void> triggerFuture{triggerPromise.get_future()};
+    auto triggerCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&triggerPromise] { triggerPromise.set_value(); });
+
+    EXPECT_OK(manager->triggerSynced(triggerCallback));
+
+    auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
+    EXPECT_EQ(triggerFuture.wait_for(timeout), std::future_status::ready);
+    for (std::future<void>& future : vibrationFutures) {
+        EXPECT_EQ(future.wait_for(timeout), std::future_status::ready);
+    }
+
+    // Session callback not triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    // Ending a session should not take long since the vibration was already completed
+    EXPECT_OK(session->close());
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::ready);
+}
+
+TEST_P(VibratorAidl, VibrationSessionWithMultipleIndependentVibrations) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+
+        EXPECT_OK(vibrator->on(100, nullptr));
+        EXPECT_OK(vibrator->on(200, nullptr));
+        EXPECT_OK(vibrator->on(300, nullptr));
+    }
+
+    // Session callback not triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    EXPECT_OK(session->close());
+
+    int32_t maxDurationMs = 100 + 200 + 300;
+    auto timeout = std::chrono::milliseconds(maxDurationMs) + VIBRATION_CALLBACK_TIMEOUT;
+    EXPECT_EQ(sessionFuture.wait_for(timeout), std::future_status::ready);
+}
+
+TEST_P(VibratorAidl, VibrationSessionsIgnoresSecondSessionWhenFirstIsOngoing) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    std::shared_ptr<IVibrationSession> secondSession;
+    EXPECT_ILLEGAL_STATE(
+            manager->startSession(vibratorIds, sessionConfig, nullptr, &secondSession));
+    EXPECT_EQ(secondSession, nullptr);
+
+    // First session was not cancelled.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    // First session still ongoing, we can still vibrate.
+    int32_t durationMs = 100;
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+        EXPECT_OK(vibrator->on(durationMs, nullptr));
+    }
+
+    EXPECT_OK(session->close());
+
+    auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
+    EXPECT_EQ(sessionFuture.wait_for(timeout), std::future_status::ready);
+}
+
+TEST_P(VibratorAidl, VibrationSessionEndMultipleTimes) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    int32_t durationMs = 250;
+    std::vector<std::promise<void>> vibrationPromises;
+    std::vector<std::future<void>> vibrationFutures;
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+
+        std::promise<void>& vibrationPromise = vibrationPromises.emplace_back();
+        vibrationFutures.push_back(vibrationPromise.get_future());
+        auto vibrationCallback = ndk::SharedRefBase::make<CompletionCallback>(
+                [&vibrationPromise] { vibrationPromise.set_value(); });
+        EXPECT_OK(vibrator->on(durationMs, vibrationCallback));
+    }
+
+    // Session callback not triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    // End session, this might take a while
+    EXPECT_OK(session->close());
+
+    // End session again
+    EXPECT_OK(session->close());
+
+    // Both callbacks triggered within timeout.
+    auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
+    EXPECT_EQ(sessionFuture.wait_for(timeout), std::future_status::ready);
+    for (std::future<void>& future : vibrationFutures) {
+        EXPECT_EQ(future.wait_for(timeout), std::future_status::ready);
+    }
+}
+
+TEST_P(VibratorAidl, VibrationSessionDeletedAfterEnded) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    std::promise<void> sessionPromise;
+    std::future<void> sessionFuture{sessionPromise.get_future()};
+    auto sessionCallback = ndk::SharedRefBase::make<CompletionCallback>(
+            [&sessionPromise] { sessionPromise.set_value(); });
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_OK(manager->startSession(vibratorIds, sessionConfig, sessionCallback, &session));
+    ASSERT_NE(session, nullptr);
+
+    int32_t durationMs = 250;
+    std::vector<std::promise<void>> vibrationPromises;
+    std::vector<std::future<void>> vibrationFutures;
+    for (int32_t id : vibratorIds) {
+        std::shared_ptr<IVibrator> vibrator;
+        EXPECT_OK(manager->getVibrator(id, &vibrator));
+        ASSERT_NE(vibrator, nullptr);
+
+        std::promise<void>& vibrationPromise = vibrationPromises.emplace_back();
+        vibrationFutures.push_back(vibrationPromise.get_future());
+        auto vibrationCallback = ndk::SharedRefBase::make<CompletionCallback>(
+                [&vibrationPromise] { vibrationPromise.set_value(); });
+        EXPECT_OK(vibrator->on(durationMs, vibrationCallback));
+    }
+
+    // Session callback not triggered.
+    EXPECT_EQ(sessionFuture.wait_for(VIBRATION_CALLBACK_TIMEOUT), std::future_status::timeout);
+
+    // End session, this might take a while
+    EXPECT_OK(session->close());
+
+    session.reset();
+
+    // Both callbacks triggered within timeout, even after session was deleted.
+    auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
+    EXPECT_EQ(sessionFuture.wait_for(timeout), std::future_status::ready);
+    for (std::future<void>& future : vibrationFutures) {
+        EXPECT_EQ(future.wait_for(timeout), std::future_status::ready);
+    }
+}
+
+TEST_P(VibratorAidl, VibrationSessionWrongVibratorIdsFail) {
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+
+    auto maxIdIt = std::max_element(vibratorIds.begin(), vibratorIds.end());
+    int32_t wrongId = maxIdIt == vibratorIds.end() ? 0 : *maxIdIt + 1;
+
+    std::vector<int32_t> emptyIds;
+    std::vector<int32_t> wrongIds{wrongId};
+    VibrationSessionConfig sessionConfig;
+    EXPECT_ILLEGAL_ARGUMENT(manager->startSession(emptyIds, sessionConfig, nullptr, &session));
+    EXPECT_ILLEGAL_ARGUMENT(manager->startSession(wrongIds, sessionConfig, nullptr, &session));
+    EXPECT_EQ(session, nullptr);
+}
+
+TEST_P(VibratorAidl, VibrationSessionDuringPrepareSyncedFails) {
+    if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
+    if (!(capabilities & IVibratorManager::CAP_START_SESSIONS)) return;
+    if (vibratorIds.empty()) return;
+
+    EXPECT_OK(manager->prepareSynced(vibratorIds));
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_ILLEGAL_STATE(manager->startSession(vibratorIds, sessionConfig, nullptr, &session));
+    EXPECT_EQ(session, nullptr);
+
+    EXPECT_OK(manager->cancelSynced());
+}
+
+TEST_P(VibratorAidl, VibrationSessionsUnsupported) {
+    if (version < VIBRATION_SESSIONS_MIN_VERSION) {
+        EXPECT_EQ(capabilities & IVibratorManager::CAP_START_SESSIONS, 0)
+                << "Vibrator manager version " << version
+                << " should not report start session capability";
+    }
+    if (capabilities & IVibratorManager::CAP_START_SESSIONS) return;
+
+    VibrationSessionConfig sessionConfig;
+    EXPECT_UNKNOWN_OR_UNSUPPORTED(
+            manager->startSession(vibratorIds, sessionConfig, nullptr, &session));
+    EXPECT_EQ(session, nullptr);
+    EXPECT_UNKNOWN_OR_UNSUPPORTED(manager->clearSessions());
+}
+
 std::vector<std::string> FindVibratorManagerNames() {
     std::vector<std::string> names;
     constexpr auto callback = [](const char* instance, void* context) {
@@ -219,7 +679,7 @@
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
-    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_setThreadPoolMaxThreadCount(2);
     ABinderProcess_startThreadPool();
     return RUN_ALL_TESTS();
 }
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index bc017ae..03ecb1a 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -41,12 +41,13 @@
 using aidl::android::hardware::vibrator::BrakingPwle;
 using aidl::android::hardware::vibrator::CompositeEffect;
 using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::CompositePwleV2;
 using aidl::android::hardware::vibrator::Effect;
 using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::FrequencyAccelerationMapEntry;
 using aidl::android::hardware::vibrator::IVibrator;
 using aidl::android::hardware::vibrator::IVibratorManager;
 using aidl::android::hardware::vibrator::PrimitivePwle;
-using aidl::android::hardware::vibrator::PwleV2OutputMapEntry;
 using aidl::android::hardware::vibrator::PwleV2Primitive;
 using aidl::android::hardware::vibrator::VendorEffect;
 using aidl::android::os::PersistableBundle;
@@ -175,11 +176,23 @@
     return resonantFrequencyHz;
 }
 
+static bool shouldValidateLegacyFrequencyControlResult(int32_t capabilities, int32_t version,
+                                                       ndk::ScopedAStatus& status) {
+    bool hasFrequencyControl = capabilities & IVibrator::CAP_FREQUENCY_CONTROL;
+    // Legacy frequency control APIs deprecated with PWLE V2 feature.
+    bool isDeprecated = version >= PWLE_V2_MIN_VERSION;
+    bool isUnknownOrUnsupported = status.getExceptionCode() == EX_UNSUPPORTED_OPERATION ||
+                                  status.getStatus() == STATUS_UNKNOWN_TRANSACTION;
+
+    // Validate if older HAL or if result is provided, even after deprecation.
+    return hasFrequencyControl && (!isDeprecated || !isUnknownOrUnsupported);
+}
+
 static float getFrequencyResolutionHz(const std::shared_ptr<IVibrator>& vibrator,
-                                      int32_t capabilities) {
-    float freqResolutionHz;
+                                      int32_t capabilities, int32_t version) {
+    float freqResolutionHz = -1;
     ndk::ScopedAStatus status = vibrator->getFrequencyResolution(&freqResolutionHz);
-    if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
+    if (shouldValidateLegacyFrequencyControlResult(capabilities, version, status)) {
         EXPECT_OK(std::move(status));
         EXPECT_GT(freqResolutionHz, 0);
     } else {
@@ -188,11 +201,11 @@
     return freqResolutionHz;
 }
 
-static float getFrequencyMinimumHz(const std::shared_ptr<IVibrator>& vibrator,
-                                   int32_t capabilities) {
+static float getFrequencyMinimumHz(const std::shared_ptr<IVibrator>& vibrator, int32_t capabilities,
+                                   int32_t version) {
     float freqMinimumHz;
     ndk::ScopedAStatus status = vibrator->getFrequencyMinimum(&freqMinimumHz);
-    if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
+    if (shouldValidateLegacyFrequencyControlResult(capabilities, version, status)) {
         EXPECT_OK(std::move(status));
 
         float resonantFrequencyHz = getResonantFrequencyHz(vibrator, capabilities);
@@ -205,19 +218,19 @@
     return freqMinimumHz;
 }
 
-static float getFrequencyMaximumHz(const std::shared_ptr<IVibrator>& vibrator,
-                                   int32_t capabilities) {
+static float getFrequencyMaximumHz(const std::shared_ptr<IVibrator>& vibrator, int32_t capabilities,
+                                   int32_t version) {
     std::vector<float> bandwidthAmplitudeMap;
     ndk::ScopedAStatus status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
-    if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
+    if (shouldValidateLegacyFrequencyControlResult(capabilities, version, status)) {
         EXPECT_OK(std::move(status));
     } else {
         EXPECT_UNKNOWN_OR_UNSUPPORTED(std::move(status));
     }
 
     float freqMaximumHz = ((bandwidthAmplitudeMap.size() - 1) *
-                           getFrequencyResolutionHz(vibrator, capabilities)) +
-                          getFrequencyMinimumHz(vibrator, capabilities);
+                           getFrequencyResolutionHz(vibrator, capabilities, version)) +
+                          getFrequencyMinimumHz(vibrator, capabilities, version);
     return freqMaximumHz;
 }
 
@@ -230,12 +243,16 @@
 }
 
 static ActivePwle composeValidActivePwle(const std::shared_ptr<IVibrator>& vibrator,
-                                         int32_t capabilities) {
+                                         int32_t capabilities, int32_t version) {
     float frequencyHz;
     if (capabilities & IVibrator::CAP_GET_RESONANT_FREQUENCY) {
         frequencyHz = getResonantFrequencyHz(vibrator, capabilities);
     } else if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
-        frequencyHz = getFrequencyMinimumHz(vibrator, capabilities);
+        if (version < PWLE_V2_MIN_VERSION) {
+            frequencyHz = getFrequencyMinimumHz(vibrator, capabilities, version);
+        } else {
+            frequencyHz = pwle_v2_utils::getPwleV2FrequencyMinHz(vibrator);
+        }
     } else {
         frequencyHz = 150.0;  // default value commonly used
     }
@@ -846,23 +863,24 @@
 }
 
 TEST_P(VibratorAidl, GetFrequencyResolution) {
-    getFrequencyResolutionHz(vibrator, capabilities);
+    getFrequencyResolutionHz(vibrator, capabilities, version);
 }
 
 TEST_P(VibratorAidl, GetFrequencyMinimum) {
-    getFrequencyMinimumHz(vibrator, capabilities);
+    getFrequencyMinimumHz(vibrator, capabilities, version);
 }
 
 TEST_P(VibratorAidl, GetBandwidthAmplitudeMap) {
     std::vector<float> bandwidthAmplitudeMap;
     ndk::ScopedAStatus status = vibrator->getBandwidthAmplitudeMap(&bandwidthAmplitudeMap);
-    if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
+
+    if (shouldValidateLegacyFrequencyControlResult(capabilities, version, status)) {
         EXPECT_OK(std::move(status));
         ASSERT_FALSE(bandwidthAmplitudeMap.empty());
 
         int minMapSize = (getResonantFrequencyHz(vibrator, capabilities) -
-                          getFrequencyMinimumHz(vibrator, capabilities)) /
-                         getFrequencyResolutionHz(vibrator, capabilities);
+                          getFrequencyMinimumHz(vibrator, capabilities, version)) /
+                         getFrequencyResolutionHz(vibrator, capabilities, version);
         ASSERT_GT(bandwidthAmplitudeMap.size(), minMapSize);
 
         for (float e : bandwidthAmplitudeMap) {
@@ -911,7 +929,7 @@
 
 TEST_P(VibratorAidl, ComposeValidPwle) {
     if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
-        ActivePwle firstActive = composeValidActivePwle(vibrator, capabilities);
+        ActivePwle firstActive = composeValidActivePwle(vibrator, capabilities, version);
 
         std::vector<Braking> supported;
         EXPECT_OK(vibrator->getSupportedBraking(&supported));
@@ -921,13 +939,17 @@
         firstBraking.braking = isClabSupported ? Braking::CLAB : Braking::NONE;
         firstBraking.duration = 100;
 
-        ActivePwle secondActive = composeValidActivePwle(vibrator, capabilities);
+        ActivePwle secondActive = composeValidActivePwle(vibrator, capabilities, version);
         if (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) {
-            float minFrequencyHz = getFrequencyMinimumHz(vibrator, capabilities);
-            float maxFrequencyHz = getFrequencyMaximumHz(vibrator, capabilities);
-            float freqResolutionHz = getFrequencyResolutionHz(vibrator, capabilities);
-            secondActive.startFrequency = minFrequencyHz + (freqResolutionHz / 2.0f);
-            secondActive.endFrequency = maxFrequencyHz - (freqResolutionHz / 3.0f);
+            float minFrequencyHz = getFrequencyMinimumHz(vibrator, capabilities, version);
+            float maxFrequencyHz = getFrequencyMaximumHz(vibrator, capabilities, version);
+            float freqResolutionHz = getFrequencyResolutionHz(vibrator, capabilities, version);
+            // As of API 16 these APIs are deprecated and no longer required to be implemented
+            //  with frequency control capability.
+            if (minFrequencyHz >= 0 && maxFrequencyHz >= 0 && freqResolutionHz >= 0) {
+                secondActive.startFrequency = minFrequencyHz + (freqResolutionHz / 2.0f);
+                secondActive.endFrequency = maxFrequencyHz - (freqResolutionHz / 3.0f);
+            }
         }
         BrakingPwle secondBraking;
         secondBraking.braking = Braking::NONE;
@@ -955,7 +977,7 @@
     uint32_t durationMs = segmentDurationMaxMs * 2 + 100;  // Sum of 2 active and 1 braking below
     auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
 
-    ActivePwle active = composeValidActivePwle(vibrator, capabilities);
+    ActivePwle active = composeValidActivePwle(vibrator, capabilities, version);
 
     std::vector<Braking> supported;
     EXPECT_OK(vibrator->getSupportedBraking(&supported));
@@ -978,7 +1000,7 @@
         // test empty queue
         EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwle(pwleQueue, nullptr));
 
-        ActivePwle active = composeValidActivePwle(vibrator, capabilities);
+        ActivePwle active = composeValidActivePwle(vibrator, capabilities, version);
 
         PrimitivePwle pwle;
         pwle = active;
@@ -996,7 +1018,7 @@
 
 TEST_P(VibratorAidl, ComposePwleAmplitudeParameterBoundary) {
     if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
-        ActivePwle active = composeValidActivePwle(vibrator, capabilities);
+        ActivePwle active = composeValidActivePwle(vibrator, capabilities, version);
         active.startAmplitude = getAmplitudeMax() + 1.0;  // Amplitude greater than allowed
         active.endAmplitude = getAmplitudeMax() + 1.0;    // Amplitude greater than allowed
 
@@ -1016,11 +1038,18 @@
 TEST_P(VibratorAidl, ComposePwleFrequencyParameterBoundary) {
     if ((capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) &&
         (capabilities & IVibrator::CAP_FREQUENCY_CONTROL)) {
-        float freqMinimumHz = getFrequencyMinimumHz(vibrator, capabilities);
-        float freqMaximumHz = getFrequencyMaximumHz(vibrator, capabilities);
-        float freqResolutionHz = getFrequencyResolutionHz(vibrator, capabilities);
+        float freqMinimumHz = getFrequencyMinimumHz(vibrator, capabilities, version);
+        float freqMaximumHz = getFrequencyMaximumHz(vibrator, capabilities, version);
+        float freqResolutionHz = getFrequencyResolutionHz(vibrator, capabilities, version);
 
-        ActivePwle active = composeValidActivePwle(vibrator, capabilities);
+        // As of API 16 these APIs are deprecated and no longer required to be implemented with
+        // frequency control capability.
+        if (freqMinimumHz < 0 || freqMaximumHz < 0 || freqResolutionHz < 0) {
+            GTEST_SKIP() << "PWLE V1 is not supported, skipping test";
+            return;
+        }
+
+        ActivePwle active = composeValidActivePwle(vibrator, capabilities, version);
         active.startFrequency =
             freqMaximumHz + freqResolutionHz;                    // Frequency greater than allowed
         active.endFrequency = freqMaximumHz + freqResolutionHz;  // Frequency greater than allowed
@@ -1040,7 +1069,7 @@
 
 TEST_P(VibratorAidl, ComposePwleSegmentDurationBoundary) {
     if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS) {
-        ActivePwle active = composeValidActivePwle(vibrator, capabilities);
+        ActivePwle active = composeValidActivePwle(vibrator, capabilities, version);
 
         int32_t segmentDurationMaxMs;
         vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
@@ -1052,15 +1081,15 @@
     }
 }
 
-TEST_P(VibratorAidl, PwleV2FrequencyToOutputAccelerationMapHasValidFrequencyRange) {
-    if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
-        GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+TEST_P(VibratorAidl, FrequencyToOutputAccelerationMapHasValidFrequencyRange) {
+    if (version < PWLE_V2_MIN_VERSION || !(capabilities & IVibrator::CAP_FREQUENCY_CONTROL)) {
+        GTEST_SKIP() << "Frequency control is not supported, skipping test";
         return;
     }
 
-    std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
+    std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap;
     ndk::ScopedAStatus status =
-            vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
+            vibrator->getFrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap);
     EXPECT_OK(std::move(status));
     ASSERT_FALSE(frequencyToOutputAccelerationMap.empty());
     auto sharpnessRange =
@@ -1072,6 +1101,15 @@
     ASSERT_TRUE(sharpnessRange.first < sharpnessRange.second);
 }
 
+TEST_P(VibratorAidl, FrequencyToOutputAccelerationMapUnsupported) {
+    if ((capabilities & IVibrator::CAP_FREQUENCY_CONTROL)) return;
+
+    std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap;
+
+    EXPECT_UNKNOWN_OR_UNSUPPORTED(
+            vibrator->getFrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
+}
+
 TEST_P(VibratorAidl, GetPwleV2PrimitiveDurationMaxMillis) {
     if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
         GTEST_SKIP() << "PWLE V2 not supported, skipping test";
@@ -1111,6 +1149,17 @@
     ASSERT_LE(durationMs, pwle_v2_utils::COMPOSE_PWLE_V2_MAX_ALLOWED_PRIMITIVE_MIN_DURATION_MS);
 }
 
+TEST_P(VibratorAidl, ValidatePwleV2DependencyOnFrequencyControl) {
+    if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
+        GTEST_SKIP() << "PWLE V2 not supported, skipping test";
+        return;
+    }
+
+    // Check if frequency control is supported
+    bool hasFrequencyControl = (capabilities & IVibrator::CAP_FREQUENCY_CONTROL) != 0;
+    ASSERT_TRUE(hasFrequencyControl) << "Frequency control MUST be supported when PWLE V2 is.";
+}
+
 TEST_P(VibratorAidl, ComposeValidPwleV2Effect) {
     if (!(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) {
         GTEST_SKIP() << "PWLE V2 not supported, skipping test";
@@ -1126,12 +1175,13 @@
         EXPECT_EQ(capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2, 0)
                 << "Vibrator version " << version << " should not report PWLE V2 capability.";
     }
-    if (capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2) return;
+    if ((capabilities & IVibrator::CAP_COMPOSE_PWLE_EFFECTS_V2)) return;
 
-    std::vector<PwleV2Primitive> pwleEffect{
-            PwleV2Primitive(/*amplitude=*/1.0f, /*frequencyHz=*/100.0f, /*timeMillis=*/50)};
+    CompositePwleV2 composite;
+    composite.pwlePrimitives.emplace_back(/*amplitude=*/1.0f, /*frequencyHz=*/100.0f,
+                                          /*timeMillis=*/50);
 
-    EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->composePwleV2(pwleEffect, nullptr));
+    EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->composePwleV2(composite, nullptr));
 }
 
 TEST_P(VibratorAidl, ComposeValidPwleV2EffectWithCallback) {
@@ -1150,8 +1200,10 @@
     auto timeout = std::chrono::milliseconds(minDuration) + VIBRATION_CALLBACK_TIMEOUT;
     float minFrequency = pwle_v2_utils::getPwleV2FrequencyMinHz(vibrator);
 
-    EXPECT_OK(vibrator->composePwleV2(
-            {PwleV2Primitive(/*amplitude=*/0.5, minFrequency, minDuration)}, callback));
+    CompositePwleV2 composite;
+    composite.pwlePrimitives.emplace_back(/*amplitude=*/0.5, minFrequency, minDuration);
+
+    EXPECT_OK(vibrator->composePwleV2(composite, callback));
     EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
     EXPECT_OK(vibrator->off());
 }
@@ -1177,43 +1229,48 @@
     EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMinMillis(&minDurationMs));
     EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMaxMillis(&maxDurationMs));
 
-    std::vector<PwleV2Primitive> composePwle;
+    CompositePwleV2 composePwle;
 
     // Negative amplitude
-    composePwle.push_back(PwleV2Primitive(/*amplitude=*/-0.8f, /*frequency=*/100, minDurationMs));
+    composePwle.pwlePrimitives.push_back(
+            PwleV2Primitive(/*amplitude=*/-0.8f, /*frequency=*/100, minDurationMs));
     EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
             << "Composing PWLE V2 effect with negative amplitude should fail";
-    composePwle.clear();
+    composePwle.pwlePrimitives.clear();
 
     // Amplitude exceeding 1.0
-    composePwle.push_back(PwleV2Primitive(/*amplitude=*/1.2f, /*frequency=*/100, minDurationMs));
+    composePwle.pwlePrimitives.push_back(
+            PwleV2Primitive(/*amplitude=*/1.2f, /*frequency=*/100, minDurationMs));
     EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
             << "Composing PWLE V2 effect with amplitude greater than 1.0 should fail";
-    composePwle.clear();
+    composePwle.pwlePrimitives.clear();
 
     // Duration exceeding maximum
-    composePwle.push_back(
+    composePwle.pwlePrimitives.push_back(
             PwleV2Primitive(/*amplitude=*/0.2f, /*frequency=*/100, maxDurationMs + 10));
     EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
             << "Composing PWLE V2 effect with duration exceeding maximum should fail";
-    composePwle.clear();
+    composePwle.pwlePrimitives.clear();
 
     // Negative duration
-    composePwle.push_back(PwleV2Primitive(/*amplitude=*/0.2f, /*frequency=*/100, /*time=*/-1));
+    composePwle.pwlePrimitives.push_back(
+            PwleV2Primitive(/*amplitude=*/0.2f, /*frequency=*/100, /*time=*/-1));
     EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
             << "Composing PWLE V2 effect with negative duration should fail";
-    composePwle.clear();
+    composePwle.pwlePrimitives.clear();
 
     // Frequency below minimum
     float minFrequency = pwle_v2_utils::getPwleV2FrequencyMinHz(vibrator);
-    composePwle.push_back(PwleV2Primitive(/*amplitude=*/0.2f, minFrequency - 1, minDurationMs));
+    composePwle.pwlePrimitives.push_back(
+            PwleV2Primitive(/*amplitude=*/0.2f, minFrequency - 1, minDurationMs));
     EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
             << "Composing PWLE V2 effect with frequency below minimum should fail";
-    composePwle.clear();
+    composePwle.pwlePrimitives.clear();
 
     // Frequency above maximum
     float maxFrequency = pwle_v2_utils::getPwleV2FrequencyMaxHz(vibrator);
-    composePwle.push_back(PwleV2Primitive(/*amplitude=*/0.2f, maxFrequency + 1, minDurationMs));
+    composePwle.pwlePrimitives.push_back(
+            PwleV2Primitive(/*amplitude=*/0.2f, maxFrequency + 1, minDurationMs));
     EXPECT_ILLEGAL_ARGUMENT(vibrator->composePwleV2(composePwle, nullptr))
             << "Composing PWLE V2 effect with frequency above maximum should fail";
 }
diff --git a/vibrator/aidl/vts/pwle_v2_utils.h b/vibrator/aidl/vts/pwle_v2_utils.h
index 2163908..eaa024c 100644
--- a/vibrator/aidl/vts/pwle_v2_utils.h
+++ b/vibrator/aidl/vts/pwle_v2_utils.h
@@ -20,8 +20,8 @@
 #include <aidl/android/hardware/vibrator/IVibrator.h>
 #include "test_utils.h"
 
+using aidl::android::hardware::vibrator::FrequencyAccelerationMapEntry;
 using aidl::android::hardware::vibrator::IVibrator;
-using aidl::android::hardware::vibrator::PwleV2OutputMapEntry;
 using aidl::android::hardware::vibrator::PwleV2Primitive;
 
 namespace aidl {
@@ -116,9 +116,8 @@
 }
 
 static float getPwleV2FrequencyMinHz(const std::shared_ptr<IVibrator>& vibrator) {
-    std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
-    EXPECT_OK(
-            vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
+    std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap;
+    EXPECT_OK(vibrator->getFrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
     EXPECT_TRUE(!frequencyToOutputAccelerationMap.empty());
     // We can't use ASSERT_TRUE() above because this is a non-void function,
     // but we need to return to assure we don't crash from a null dereference.
@@ -134,9 +133,8 @@
 }
 
 static float getPwleV2FrequencyMaxHz(const std::shared_ptr<IVibrator>& vibrator) {
-    std::vector<PwleV2OutputMapEntry> frequencyToOutputAccelerationMap;
-    EXPECT_OK(
-            vibrator->getPwleV2FrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
+    std::vector<FrequencyAccelerationMapEntry> frequencyToOutputAccelerationMap;
+    EXPECT_OK(vibrator->getFrequencyToOutputAccelerationMap(&frequencyToOutputAccelerationMap));
     EXPECT_TRUE(!frequencyToOutputAccelerationMap.empty());
     // We can't use ASSERT_TRUE() above because this is a non-void function,
     // but we need to return to assure we don't crash from a null dereference.
@@ -151,8 +149,7 @@
     return entry->frequencyHz;
 }
 
-static std::vector<PwleV2Primitive> composeValidPwleV2Effect(
-        const std::shared_ptr<IVibrator>& vibrator) {
+static CompositePwleV2 composeValidPwleV2Effect(const std::shared_ptr<IVibrator>& vibrator) {
     int32_t minDurationMs;
     EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMinMillis(&minDurationMs));
     int32_t maxDurationMs;
@@ -162,20 +159,20 @@
     int32_t maxCompositionSize;
     EXPECT_OK(vibrator->getPwleV2CompositionSizeMax(&maxCompositionSize));
 
-    std::vector<PwleV2Primitive> pwleEffect;
+    CompositePwleV2 composite;
 
-    pwleEffect.emplace_back(0.1f, minFrequency, minDurationMs);
-    pwleEffect.emplace_back(0.5f, maxFrequency, maxDurationMs);
+    composite.pwlePrimitives.emplace_back(0.1f, minFrequency, minDurationMs);
+    composite.pwlePrimitives.emplace_back(0.5f, maxFrequency, maxDurationMs);
 
     float variedFrequency = (minFrequency + maxFrequency) / 2.0f;
     for (int i = 0; i < maxCompositionSize - 2; i++) {
-        pwleEffect.emplace_back(0.7f, variedFrequency, minDurationMs);
+        composite.pwlePrimitives.emplace_back(0.7f, variedFrequency, minDurationMs);
     }
 
-    return pwleEffect;
+    return composite;
 }
 
-static std::vector<PwleV2Primitive> composePwleV2EffectWithTooManyPoints(
+static CompositePwleV2 composePwleV2EffectWithTooManyPoints(
         const std::shared_ptr<IVibrator>& vibrator) {
     int32_t minDurationMs, maxCompositionSize;
     EXPECT_OK(vibrator->getPwleV2PrimitiveDurationMinMillis(&minDurationMs));
@@ -187,12 +184,15 @@
     std::fill(pwleEffect.begin(), pwleEffect.end(),
               PwleV2Primitive(/*amplitude=*/0.2f, maxFrequency, minDurationMs));
 
-    return pwleEffect;
+    CompositePwleV2 composite;
+    composite.pwlePrimitives = pwleEffect;
+
+    return composite;
 }
 
 static std::pair<float, float> getPwleV2SharpnessRange(
         const std::shared_ptr<IVibrator>& vibrator,
-        std::vector<PwleV2OutputMapEntry> freqToOutputAccelerationMap) {
+        std::vector<FrequencyAccelerationMapEntry> freqToOutputAccelerationMap) {
     std::pair<float, float> sharpnessRange = {-1, -1};
 
     // Sort the entries by frequency in ascending order
diff --git a/vibrator/aidl/vts/test_utils.h b/vibrator/aidl/vts/test_utils.h
index aaf3211..e884bbd 100644
--- a/vibrator/aidl/vts/test_utils.h
+++ b/vibrator/aidl/vts/test_utils.h
@@ -57,4 +57,17 @@
 #error Macro EXPECT_ILLEGAL_ARGUMENT already defined unexpectedly
 #endif
 
+#if !defined(EXPECT_ILLEGAL_STATE)
+#define EXPECT_ILLEGAL_STATE(expression)                                  \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_                                         \
+    if (const ::ndk::ScopedAStatus&& _status = (expression);              \
+        _status.getExceptionCode() == EX_ILLEGAL_STATE)                   \
+        ;                                                                 \
+    else                                                                  \
+        ADD_FAILURE() << "Expected EX_ILLEGAL_STATE for: " << #expression \
+                      << "\n  Actual: " << _status
+#else
+#error Macro EXPECT_ILLEGAL_STATE already defined unexpectedly
+#endif
+
 #endif  // VIBRATOR_HAL_TEST_UTILS_H
diff --git a/wifi/aidl/Android.bp b/wifi/aidl/Android.bp
index 392d2e9..4b7e372 100644
--- a/wifi/aidl/Android.bp
+++ b/wifi/aidl/Android.bp
@@ -29,7 +29,7 @@
         "android/hardware/wifi/*.aidl",
     ],
     imports: [
-        "android.hardware.wifi.common-V1",
+        "android.hardware.wifi.common-V2",
     ],
     stability: "vintf",
     backend: {
@@ -64,5 +64,5 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Akm.aidl
similarity index 79%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Akm.aidl
index a5eda52..5baf2e8 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/Akm.aidl
@@ -31,9 +31,16 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable Akm {
+  const long NONE = 0;
+  const long PASN = (1 << 0) /* 1 */;
+  const long SAE = (1 << 1) /* 2 */;
+  const long FT_EAP_SHA256 = (1 << 2) /* 4 */;
+  const long FT_PSK_SHA256 = (1 << 3) /* 8 */;
+  const long FT_EAP_SHA384 = (1 << 4) /* 16 */;
+  const long FT_PSK_SHA384 = (1 << 5) /* 32 */;
+  const long FILS_EAP_SHA256 = (1 << 6) /* 64 */;
+  const long FILS_EAP_SHA384 = (1 << 7) /* 128 */;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CipherSuite.aidl
similarity index 86%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CipherSuite.aidl
index a5eda52..32fb5ba 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/CipherSuite.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable CipherSuite {
+  const long NONE = 0;
+  const long CCMP_128 = (1 << 0) /* 1 */;
+  const long CCMP_256 = (1 << 1) /* 2 */;
+  const long GCMP_128 = (1 << 2) /* 4 */;
+  const long GCMP_256 = (1 << 3) /* 8 */;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
index e71dde4..af95bee 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiApIface.aidl
@@ -40,4 +40,5 @@
   void setCountryCode(in byte[2] code);
   void resetToFactoryMacAddress();
   void setMacAddress(in byte[6] mac);
+  boolean usesMlo();
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
index 5ed7517..565f33a 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiChip.aidl
@@ -35,7 +35,13 @@
 @VintfStability
 interface IWifiChip {
   void configureChip(in int modeId);
+  /**
+   * @deprecated This method is deprecated from AIDL v3, newer HALs should use createApOrBridgedApIfaceWithParams.
+   */
   @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApIface();
+  /**
+   * @deprecated This method is deprecated from AIDL v3, newer HALs should use createApOrBridgedApIfaceWithParams.
+   */
   @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createBridgedApIface();
   @PropagateAllowBlocking android.hardware.wifi.IWifiNanIface createNanIface();
   @PropagateAllowBlocking android.hardware.wifi.IWifiP2pIface createP2pIface();
@@ -83,8 +89,12 @@
   void triggerSubsystemRestart();
   void enableStaChannelForPeerNetwork(in int channelCategoryEnableFlag);
   void setMloMode(in android.hardware.wifi.IWifiChip.ChipMloMode mode);
+  /**
+   * @deprecated This method is deprecated from AIDL v3, newer HALs should use createApOrBridgedApIfaceWithParams.
+   */
   @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApOrBridgedApIface(in android.hardware.wifi.IfaceConcurrencyType iface, in android.hardware.wifi.common.OuiKeyedData[] vendorData);
   void setVoipMode(in android.hardware.wifi.IWifiChip.VoipMode mode);
+  @PropagateAllowBlocking android.hardware.wifi.IWifiApIface createApOrBridgedApIfaceWithParams(in android.hardware.wifi.IWifiChip.ApIfaceParams params);
   const int NO_POWER_CAP_CONSTANT = 0x7FFFFFFF;
   @Backing(type="int") @VintfStability
   enum FeatureSetMask {
@@ -98,6 +108,8 @@
     SET_AFC_CHANNEL_ALLOWANCE = (1 << 7) /* 128 */,
     T2LM_NEGOTIATION = (1 << 8) /* 256 */,
     SET_VOIP_MODE = (1 << 9) /* 512 */,
+    MLO_SAP = (1 << 10) /* 1024 */,
+    MULTIPLE_MLD_ON_SAP = (1 << 11) /* 2048 */,
   }
   @VintfStability
   parcelable ChipConcurrencyCombinationLimit {
@@ -180,4 +192,10 @@
     HIGH_THROUGHPUT = 2,
     LOW_POWER = 3,
   }
+  @VintfStability
+  parcelable ApIfaceParams {
+    android.hardware.wifi.IfaceConcurrencyType ifaceType;
+    boolean usesMlo;
+    @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  }
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
index 8c44330..9d982b8 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -72,4 +72,5 @@
   oneway void notifyInitiateBootstrappingResponse(in char id, in android.hardware.wifi.NanStatus status, in int bootstrappingInstanceId);
   oneway void notifyRespondToBootstrappingIndicationResponse(in char id, in android.hardware.wifi.NanStatus status);
   oneway void notifyTerminatePairingResponse(in char id, in android.hardware.wifi.NanStatus status);
+  oneway void notifyRangingResults(in android.hardware.wifi.RttResult[] results, in byte discoverySessionId);
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
index a30893a..0722a04 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanCapabilities.aidl
@@ -54,4 +54,7 @@
   boolean supportsPairing;
   boolean supportsSetClusterId;
   boolean supportsSuspension;
+  boolean supportsPeriodicRanging;
+  android.hardware.wifi.RttBw maxSupportedBandwidth;
+  int maxNumRxChainsSupported;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
index 96d940a..58e62db 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -55,4 +55,7 @@
   char distanceIngressCm;
   char distanceEgressCm;
   boolean enableSessionSuspendability;
+  int rttBurstSize;
+  android.hardware.wifi.RttPreamble preamble;
+  @nullable android.hardware.wifi.WifiChannelInfo channelInfo;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
index bdc8357..90e9a8b 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/NanPublishRequest.aidl
@@ -41,4 +41,5 @@
   android.hardware.wifi.NanPairingConfig pairingConfig;
   byte[16] identityKey;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  boolean rangingResultsRequired;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/PasnConfig.aidl
similarity index 91%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/PasnConfig.aidl
index a5eda52..9b26c97 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/PasnConfig.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable PasnConfig {
+  long baseAkm;
+  long cipherSuite;
+  @nullable byte[] passphrase;
+  @nullable byte[] pmkid;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
index 6c64084..90caa26 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttCapabilities.aidl
@@ -47,4 +47,9 @@
   boolean ntbInitiatorSupported;
   boolean ntbResponderSupported;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  long akmsSupported;
+  long cipherSuitesSupported;
+  boolean secureHeLtfSupported;
+  boolean rangingFrameProtectionSupported;
+  int maxSupportedSecureHeLtfProtocolVersion;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
index 3613616..5507280 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttConfig.aidl
@@ -51,4 +51,5 @@
   long ntbMinMeasurementTime;
   long ntbMaxMeasurementTime;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  @nullable android.hardware.wifi.RttSecureConfig secureConfig;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
index 13202ba..9d62431 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttResult.aidl
@@ -66,4 +66,11 @@
   byte numTxSpatialStreams;
   byte numRxSpatialStreams;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  boolean isRangingFrameProtectionEnabled;
+  boolean isSecureLtfEnabled;
+  long baseAkm;
+  long cipherSuite;
+  int secureHeLtfProtocolVersion;
+  long pasnComebackAfterMillis;
+  @nullable byte[] pasnComebackCookie;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttSecureConfig.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttSecureConfig.aidl
index a5eda52..5cb1aaa 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttSecureConfig.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable RttSecureConfig {
+  android.hardware.wifi.PasnConfig pasnConfig;
+  boolean enableSecureHeLtf;
+  boolean enableRangingFrameProtection;
+  @nullable byte[] pasnComebackCookie;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl
index 2817497..08bca77 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttStatus.aidl
@@ -52,4 +52,9 @@
   FAIL_FTM_PARAM_OVERRIDE = 15,
   NAN_RANGING_PROTOCOL_FAILURE = 16,
   NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17,
+  SECURE_RANGING_FAILURE_INVALID_AKM = 18,
+  SECURE_RANGING_FAILURE_INVALID_CIPHER = 19,
+  SECURE_RANGING_FAILURE_INVALID_CONFIG = 20,
+  SECURE_RANGING_FAILURE_REJECTED = 21,
+  SECURE_RANGING_FAILURE_UNKNOWN = 22,
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
index cb25673..8545d73 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/RttType.aidl
@@ -38,4 +38,5 @@
   TWO_SIDED = 2,
   TWO_SIDED_11MC = TWO_SIDED /* 2 */,
   TWO_SIDED_11AZ_NTB = 3,
+  TWO_SIDED_11AZ_NTB_SECURE = 4,
 }
diff --git a/wifi/aidl/android/hardware/wifi/Akm.aidl b/wifi/aidl/android/hardware/wifi/Akm.aidl
new file mode 100644
index 0000000..e3a913b
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/Akm.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Authentication and Key Management types.
+ */
+@VintfStability
+parcelable Akm {
+    const long NONE = 0;
+    const long PASN = 1 << 0;
+    const long SAE = 1 << 1;
+    const long FT_EAP_SHA256 = 1 << 2;
+    const long FT_PSK_SHA256 = 1 << 3;
+    const long FT_EAP_SHA384 = 1 << 4;
+    const long FT_PSK_SHA384 = 1 << 5;
+    const long FILS_EAP_SHA256 = 1 << 6;
+    const long FILS_EAP_SHA384 = 1 << 7;
+}
diff --git a/wifi/aidl/android/hardware/wifi/CipherSuite.aidl b/wifi/aidl/android/hardware/wifi/CipherSuite.aidl
new file mode 100644
index 0000000..02b62e8
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/CipherSuite.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Cipher Suite types.
+ */
+@VintfStability
+parcelable CipherSuite {
+    const long NONE = 0;
+    const long CCMP_128 = 1 << 0;
+    const long CCMP_256 = 1 << 1;
+    const long GCMP_128 = 1 << 2;
+    const long GCMP_256 = 1 << 3;
+}
diff --git a/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
index b14a800..a350e52 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiApIface.aidl
@@ -85,4 +85,11 @@
      *         |WifiStatusCode.ERROR_UNKNOWN|
      */
     void setMacAddress(in byte[6] mac);
+
+    /**
+     * Check if ApIface is for an AP using Multi-Link Operation
+     *
+     * @return true if it is MLO iface, false otherwise.
+     */
+    boolean usesMlo();
 }
diff --git a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
index d12d26c..5a5e4a7 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiChip.aidl
@@ -87,6 +87,18 @@
          * Chip supports voip mode setting.
          */
         SET_VOIP_MODE = 1 << 9,
+        /**
+         * Chip supports Wi-Fi 7 MLO SoftAp.
+         */
+        MLO_SAP = 1 << 10,
+        /**
+         * Chip supports multiple Wi-Fi 7 multi-link devices (MLD) on SoftAp.
+         * When this feature flag is enabled, it is an indication that the chip can
+         * support Bridged-SoftAp in 11be with separate MLD MAC addresses.
+         * When this feature is disabled, then only one MLD address can be used in 11be mode
+         * (if supported), this includes use of MLO if MLO_SAP flag is set to True.
+         */
+        MULTIPLE_MLD_ON_SAP = 1 << 11,
     }
 
     /**
@@ -429,6 +441,9 @@
      * reached the maximum allowed (specified in |ChipIfaceCombination|) number
      * of ifaces of the AP type.
      *
+     * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+     * createApOrBridgedApIfaceWithParams.
+     *
      * @return AIDL interface object representing the iface if
      *         successful, null otherwise.
      * @throws ServiceSpecificException with one of the following values:
@@ -446,6 +461,9 @@
      * reached the maximum allowed (specified in |ChipIfaceCombination|) number
      * of ifaces of the AP type.
      *
+     * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+     * createApOrBridgedApIfaceWithParams.
+     *
      * @return AIDL interface object representing the iface if
      *         successful, null otherwise.
      * @throws ServiceSpecificException with one of the following values:
@@ -1173,6 +1191,9 @@
      * reached the maximum allowed (specified in |ChipIfaceCombination|) number
      * of ifaces of the AP or AP_BRIDGED type.
      *
+     * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+     * createApOrBridgedApIfaceWithParams.
+     *
      * @param  iface IfaceConcurrencyType to be created. Takes one of
                |IfaceConcurrencyType.AP| or |IfaceConcurrencyType.AP_BRIDGED|
      * @param  vendorData Vendor-provided configuration data as a list of |OuiKeyedData|.
@@ -1206,4 +1227,42 @@
      *         |WifiStatusCode.ERROR_UNKNOWN|
      */
     void setVoipMode(in VoipMode mode);
+
+    /**
+     * Parameters for setting up access point (AP) interfaces.
+     */
+    @VintfStability
+    parcelable ApIfaceParams {
+        /**
+         * IfaceConcurrencyType to be created. Takes one of
+         * |IfaceConcurrencyType.AP| or |IfaceConcurrencyType.AP_BRIDGED|
+         */
+        IfaceConcurrencyType ifaceType;
+        /**
+         * Whether the current iface will be operated on Multi-links on the one MLD device (MLO).
+         */
+        boolean usesMlo;
+        /**
+         * Optional vendor-specific configuration parameters.
+         */
+        @nullable OuiKeyedData[] vendorData;
+    }
+
+    /**
+     * Create an AP or bridged AP iface on the chip based on ApIfaceParamss.
+     *
+     * Depending on the mode the chip is configured in, the interface creation
+     * may fail (code: |WifiStatusCode.ERROR_NOT_AVAILABLE|) if we've already
+     * reached the maximum allowed (specified in |ChipIfaceCombination|) number
+     * of ifaces of the AP type.
+     *
+     * @return AIDL interface object representing the iface if
+     *         successful, null otherwise.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
+     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
+     *         |WifiStatusCode.ERROR_NOT_AVAILABLE|
+     */
+    @PropagateAllowBlocking
+    IWifiApIface createApOrBridgedApIfaceWithParams(in ApIfaceParams params);
 }
diff --git a/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
index 3649b7b..376dcac 100644
--- a/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
+++ b/wifi/aidl/android/hardware/wifi/IWifiNanIfaceEventCallback.aidl
@@ -29,6 +29,7 @@
 import android.hardware.wifi.NanPairingRequestInd;
 import android.hardware.wifi.NanStatus;
 import android.hardware.wifi.NanSuspensionModeChangeInd;
+import android.hardware.wifi.RttResult;
 /**
  * NAN Response and Asynchronous Event Callbacks.
  *
@@ -461,4 +462,12 @@
      *        |NanStatusCode.INVALID_PAIRING_ID|
      */
     void notifyTerminatePairingResponse(in char id, in NanStatus status);
+
+    /**
+     * Callback is invoked when ranging results are available.
+     *
+     * @param results RttResult data.
+     * @param discoverySessionId Discovery session ID.
+     */
+    void notifyRangingResults(in RttResult[] results, in byte discoverySessionId);
 }
diff --git a/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
index f581c5e..f9f825f 100644
--- a/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanCapabilities.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.wifi;
 
+import android.hardware.wifi.RttBw;
+
 /**
  * NDP Capabilities response.
  */
@@ -103,4 +105,16 @@
      * Flag to indicate if NAN suspension is supported.
      */
     boolean supportsSuspension;
+    /**
+     * Flag to indicate if NAN periodic ranging is supported.
+     */
+    boolean supportsPeriodicRanging;
+    /**
+     * Maximum supported bandwidth.
+     */
+    RttBw maxSupportedBandwidth;
+    /**
+     * Maximum number of supported receive chains.
+     */
+    int maxNumRxChainsSupported;
 }
diff --git a/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
index 4bedce0..725ed3c 100644
--- a/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanDiscoveryCommonConfig.aidl
@@ -18,6 +18,8 @@
 
 import android.hardware.wifi.NanDataPathSecurityConfig;
 import android.hardware.wifi.NanMatchAlg;
+import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.WifiChannelInfo;
 
 /**
  * Configurations of NAN discovery sessions. Common to publish and subscribe discovery.
@@ -136,10 +138,14 @@
      */
     boolean rangingRequired;
     /**
-     * Interval in ms between two ranging measurements. Only relevant if |rangingRequired| is true.
+     * Interval in ms between two ranging measurements. Only applies to periodic ranging and is
+     * only relevant if |rangingRequired| is true.
+     *
      * If the Awake DW interval specified either in |discoveryWindowPeriod| or in
      * |NanBandSpecificConfig.discoveryWindowIntervalVal| is larger than the ranging interval then
      * priority is given to Awake DW interval.
+     *
+     * If this is set to 0, then only one ranging is performed.
      */
     int rangingIntervalMs;
     /**
@@ -162,4 +168,16 @@
      * |NanCapabilities.supportsSuspension| is false.
      */
     boolean enableSessionSuspendability;
+    /**
+     * The number of FTM packets used to estimate a range.
+     */
+    int rttBurstSize;
+    /**
+     * RTT preamble to be used in the RTT frames.
+     */
+    RttPreamble preamble;
+    /**
+     * Channel information.
+     */
+    @nullable WifiChannelInfo channelInfo;
 }
diff --git a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
index ae75caf..09ea496 100644
--- a/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/NanPublishRequest.aidl
@@ -61,4 +61,9 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+    /**
+     * If |NanCapabilities.supportsPeriodicRanging| is true, then this field specifies whether the
+     * ranging results need to be notified to the Publisher when they are available.
+     */
+    boolean rangingResultsRequired;
 }
diff --git a/wifi/aidl/android/hardware/wifi/PasnConfig.aidl b/wifi/aidl/android/hardware/wifi/PasnConfig.aidl
new file mode 100644
index 0000000..37ef03c
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/PasnConfig.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+/**
+ * Pre-Association Security Negotiation (PASN) configuration.
+ */
+@VintfStability
+parcelable PasnConfig {
+    /**
+     * Base Authentication and Key Management (AKM) protocol used for PASN. Represented as
+     * at bitmap of |Akm|.
+     */
+    long baseAkm;
+    /**
+     * Pairwise cipher suite used for the PTKSA (Pairwise Transient Key Security Association).
+     * Represented as a bitmap of |CipherSuite|.
+     */
+    long cipherSuite;
+    /**
+     * Passphrase for the base AKM. This can be null based on the AKM type.
+     */
+    @nullable byte[] passphrase;
+    /**
+     * PMKID corresponding to the cached PMK from the base AKM. PMKID can be null if no cached PMK
+     * is present.
+     */
+    @nullable byte[] pmkid;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
index c193924..48e211d 100644
--- a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
@@ -84,4 +84,24 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+    /**
+     * Bitmap of |Akm| values indicating the set of supported AKMs.
+     */
+    long akmsSupported;
+    /**
+     * Bitmap of |CipherSuite| values indicating the set of supported pairwise cipher suites.
+     */
+    long cipherSuitesSupported;
+    /**
+     * Whether secure HE-LTF is supported.
+     */
+    boolean secureHeLtfSupported;
+    /**
+     * Whether frame protection for ranging is supported.
+     */
+    boolean rangingFrameProtectionSupported;
+    /**
+     * Maximum supported secure HE-LTF protocol version.
+     */
+    int maxSupportedSecureHeLtfProtocolVersion;
 }
diff --git a/wifi/aidl/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
index 496ffd2..8dfbea8 100644
--- a/wifi/aidl/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
@@ -19,6 +19,7 @@
 import android.hardware.wifi.RttBw;
 import android.hardware.wifi.RttPeerType;
 import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.RttSecureConfig;
 import android.hardware.wifi.RttType;
 import android.hardware.wifi.WifiChannelInfo;
 import android.hardware.wifi.common.OuiKeyedData;
@@ -140,4 +141,8 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+    /**
+     * Secure Ranging configuration
+     */
+    @nullable RttSecureConfig secureConfig;
 }
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
index 2f9aefe..361d7e9 100644
--- a/wifi/aidl/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -213,4 +213,41 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+    /**
+     * Whether ranging frame protection is enabled.
+     */
+    boolean isRangingFrameProtectionEnabled;
+    /**
+     * Whether Secure HE-LTF is enabled.
+     */
+    boolean isSecureLtfEnabled;
+    /**
+     * Base Authentication and Key Management (AKM) protocol used for PASN. Represented as
+     * at bitmap of |Akm|.
+     */
+    long baseAkm;
+    /**
+     * Pairwise cipher suite used for the PTKSA (Pairwise Transient Key Security Association).
+     * Represented as a bitmap of |CipherSuite|.
+     */
+    long cipherSuite;
+    /**
+     * Secure HE-LTF protocol version used.
+     */
+    int secureHeLtfProtocolVersion;
+    /**
+     * When an AP receives a large volume of initial PASN Authentication frames, it can use the
+     * comeback after field in the PASN Parameters element to indicate a deferral time and
+     * optionally provide a comeback cookie which is an opaque sequence of octets. This field is
+     * set to 0 to indicate that the subsequent ranging request can be retried with the
+     * |pasnComebackCookie|.
+     */
+    long pasnComebackAfterMillis;
+    /**
+     * Comeback cookie is an opaque sequence of octects sent by the AP when PASN authentication
+     * needs to be deferred. The same cookie needs to be passed in |RttSecureConfig| when the
+     * station has to range with the AP after |RttResult.pasnComebackAfterMillis|. Maximum size of
+     * cookie is 255 bytes. Refer IEEE Std 802.11az‐2022, section 9.4.2.303 PASN Parameters element.
+     */
+    @nullable byte[] pasnComebackCookie;
 }
diff --git a/wifi/aidl/android/hardware/wifi/RttSecureConfig.aidl b/wifi/aidl/android/hardware/wifi/RttSecureConfig.aidl
new file mode 100644
index 0000000..0d1350e
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/RttSecureConfig.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi;
+
+import android.hardware.wifi.PasnConfig;
+
+/**
+ * RTT secure configuration.
+ */
+@VintfStability
+parcelable RttSecureConfig {
+    /**
+     * Pre-Association Security Negotiation (PASN) configuration.
+     */
+    PasnConfig pasnConfig;
+    /**
+     * Enable secure HE-LTF (High Efficiency Long Training Field).
+     */
+    boolean enableSecureHeLtf;
+    /**
+     * Enable Ranging frame protection.
+     */
+    boolean enableRangingFrameProtection;
+    /**
+     * Comeback cookie is an opaque sequence of octets retrieved from |RttResult|.
+     */
+    @nullable byte[] pasnComebackCookie;
+}
diff --git a/wifi/aidl/android/hardware/wifi/RttStatus.aidl b/wifi/aidl/android/hardware/wifi/RttStatus.aidl
index 600165c..94bc9e3 100644
--- a/wifi/aidl/android/hardware/wifi/RttStatus.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttStatus.aidl
@@ -88,4 +88,24 @@
      * NAN concurrency not supported (NDP + RTT).
      */
     NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17,
+    /**
+     * Secure Ranging failed due to invalid AKM (Authentication and Key Management)
+     */
+    SECURE_RANGING_FAILURE_INVALID_AKM = 18,
+    /**
+     * Secure Ranging failed due to invalid Cipher.
+     */
+    SECURE_RANGING_FAILURE_INVALID_CIPHER = 19,
+    /**
+     * Secure Ranging failed due to invalid configuration.
+     */
+    SECURE_RANGING_FAILURE_INVALID_CONFIG = 20,
+    /**
+     * Secure ranging rejected by the AP.
+     */
+    SECURE_RANGING_FAILURE_REJECTED = 21,
+    /**
+     * Secure ranging failure unknown.
+     */
+    SECURE_RANGING_FAILURE_UNKNOWN = 22,
 }
diff --git a/wifi/aidl/android/hardware/wifi/RttType.aidl b/wifi/aidl/android/hardware/wifi/RttType.aidl
index 3f1a2f1..d7cf9fe 100644
--- a/wifi/aidl/android/hardware/wifi/RttType.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttType.aidl
@@ -37,4 +37,8 @@
      * Two-sided RTT 11az non trigger based (non-TB) type.
      */
     TWO_SIDED_11AZ_NTB = 3,
+    /**
+     * Two-sided RTT 11az non trigger based (non-TB) secure type.
+     */
+    TWO_SIDED_11AZ_NTB_SECURE = 4,
 }
diff --git a/wifi/aidl/default/Android.bp b/wifi/aidl/default/Android.bp
index 3fcb77f..c2e8541 100644
--- a/wifi/aidl/default/Android.bp
+++ b/wifi/aidl/default/Android.bp
@@ -106,7 +106,7 @@
         "libwifi-hal",
         "libwifi-system-iface",
         "libxml2",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
     ],
 
     export_include_dirs: ["."],
@@ -138,7 +138,7 @@
         "libwifi-hal",
         "libwifi-system-iface",
         "libxml2",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
     ],
     static_libs: ["android.hardware.wifi-service-lib"],
     init_rc: ["android.hardware.wifi-service.rc"],
@@ -167,7 +167,7 @@
         "libwifi-hal",
         "libwifi-system-iface",
         "libxml2",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
     ],
     static_libs: ["android.hardware.wifi-service-lib"],
     init_rc: ["android.hardware.wifi-service-lazy.rc"],
@@ -199,8 +199,8 @@
     static_libs: [
         "libgmock",
         "libgtest",
-        "android.hardware.wifi-V2-ndk",
-        "android.hardware.wifi.common-V1-ndk",
+        "android.hardware.wifi-V3-ndk",
+        "android.hardware.wifi.common-V2-ndk",
         "android.hardware.wifi-service-lib",
     ],
     shared_libs: [
diff --git a/wifi/aidl/default/aidl_callback_util.h b/wifi/aidl/default/aidl_callback_util.h
index f8ba53b..d077683 100644
--- a/wifi/aidl/default/aidl_callback_util.h
+++ b/wifi/aidl/default/aidl_callback_util.h
@@ -26,6 +26,7 @@
 namespace {
 std::unordered_map<void* /* callback */, void* /* handler */> callback_handler_map_;
 std::mutex callback_handler_lock_;
+int32_t min_callback_version_ = INT_MAX;
 }
 
 namespace aidl {
@@ -45,6 +46,18 @@
     ~AidlCallbackHandler() { invalidate(); }
 
     bool addCallback(const std::shared_ptr<CallbackType>& cb) {
+        if (cb == nullptr) {
+            LOG(ERROR) << "Unable to register a null callback";
+            return false;
+        }
+
+        // Callback interface version indicates which methods are available
+        int callbackVersion = getCallbackInterfaceVersion(cb);
+        if (callbackVersion < min_callback_version_) {
+            LOG(INFO) << "Setting min callback version to " << callbackVersion;
+            min_callback_version_ = callbackVersion;
+        }
+
         std::unique_lock<std::mutex> lk(callback_handler_lock_);
         void* cbPtr = reinterpret_cast<void*>(cb->asBinder().get());
         const auto& cbPosition = findCbInSet(cbPtr);
@@ -106,6 +119,8 @@
         // unique_lock unlocked here
     }
 
+    int32_t getMinCallbackVersion() { return min_callback_version_; }
+
   private:
     std::set<std::shared_ptr<CallbackType>> cb_set_;
     AIBinder_DeathRecipient* death_handler_;
@@ -140,6 +155,15 @@
         }
     }
 
+    static int32_t getCallbackInterfaceVersion(std::shared_ptr<CallbackType> callback) {
+        int32_t callbackVersion;
+        if (!callback->getInterfaceVersion(&callbackVersion).isOk()) {
+            LOG(ERROR) << "Unable to check the callback version";
+            return INT_MAX;
+        }
+        return callbackVersion;
+    }
+
     DISALLOW_COPY_AND_ASSIGN(AidlCallbackHandler);
 };
 
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index d99edaa..0203874 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -26,6 +26,9 @@
 namespace aidl_struct_util {
 
 WifiChannelWidthInMhz convertLegacyWifiChannelWidthToAidl(legacy_hal::wifi_channel_width type);
+bool convertAidlWifiChannelInfoToLegacy(const WifiChannelInfo& aidl_info,
+                                        legacy_hal::wifi_channel_info* legacy_info);
+RttBw convertLegacyRttBwToAidl(legacy_hal::wifi_rtt_bw type);
 
 std::string safeConvertChar(const char* str, size_t max_len) {
     const char* c = str;
@@ -61,6 +64,8 @@
             return IWifiChip::FeatureSetMask::SET_AFC_CHANNEL_ALLOWANCE;
         case WIFI_FEATURE_SET_VOIP_MODE:
             return IWifiChip::FeatureSetMask::SET_VOIP_MODE;
+        case WIFI_FEATURE_MLO_SAP:
+            return IWifiChip::FeatureSetMask::MLO_SAP;
     };
     CHECK(false) << "Unknown legacy feature: " << feature;
     return {};
@@ -2294,6 +2299,10 @@
     aidl_response->supportsPairing = legacy_response.is_pairing_supported;
     aidl_response->supportsSetClusterId = legacy_response.is_set_cluster_id_supported;
     aidl_response->supportsSuspension = legacy_response.is_suspension_supported;
+    // TODO: Retrieve values from the legacy HAL
+    aidl_response->supportsPeriodicRanging = false;
+    aidl_response->maxSupportedBandwidth = RttBw::BW_UNSPECIFIED;
+    aidl_response->maxNumRxChainsSupported = 2;
 
     return true;
 }
@@ -2476,6 +2485,8 @@
             return legacy_hal::RTT_TYPE_2_SIDED_11MC;
         case RttType::TWO_SIDED_11AZ_NTB:
             return legacy_hal::RTT_TYPE_2_SIDED_11AZ_NTB;
+        case RttType::TWO_SIDED_11AZ_NTB_SECURE:
+            return legacy_hal::RTT_TYPE_2_SIDED_11AZ_NTB_SECURE;
     };
     CHECK(false);
 }
@@ -2489,6 +2500,8 @@
             return RttType::TWO_SIDED_11MC;
         case legacy_hal::RTT_TYPE_2_SIDED_11AZ_NTB:
             return RttType::TWO_SIDED_11AZ_NTB;
+        case legacy_hal::RTT_TYPE_2_SIDED_11AZ_NTB_SECURE:
+            return RttType::TWO_SIDED_11AZ_NTB_SECURE;
     };
     CHECK(false) << "Unknown legacy type: " << type;
 }
@@ -2721,6 +2734,16 @@
             return RttStatus::NAN_RANGING_PROTOCOL_FAILURE;
         case legacy_hal::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED:
             return RttStatus::NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
+        case legacy_hal::RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_AKM:
+            return RttStatus::SECURE_RANGING_FAILURE_INVALID_AKM;
+        case legacy_hal::RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_CIPHER:
+            return RttStatus::SECURE_RANGING_FAILURE_INVALID_CIPHER;
+        case legacy_hal::RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_CONFIG:
+            return RttStatus::SECURE_RANGING_FAILURE_INVALID_CONFIG;
+        case legacy_hal::RTT_STATUS_SECURE_RANGING_FAILURE_REJECTED:
+            return RttStatus::SECURE_RANGING_FAILURE_REJECTED;
+        case legacy_hal::RTT_STATUS_SECURE_RANGING_FAILURE_UNKNOWN:
+            return RttStatus::SECURE_RANGING_FAILURE_UNKNOWN;
     };
     CHECK(false) << "Unknown legacy status: " << status;
 }
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
index 2574f95..9a3c535 100644
--- a/wifi/aidl/default/aidl_struct_util.h
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -231,6 +231,8 @@
                                       TwtSession* aidl_twt_session);
 bool convertLegacyHalTwtSessionStatsToAidl(legacy_hal::wifi_twt_session_stats twt_stats,
                                            TwtSessionStats* aidl_twt_stats);
+legacy_hal::wifi_rtt_preamble convertAidlRttPreambleToLegacy(RttPreamble type);
+
 }  // namespace aidl_struct_util
 }  // namespace wifi
 }  // namespace hardware
diff --git a/wifi/aidl/default/android.hardware.wifi-service.xml b/wifi/aidl/default/android.hardware.wifi-service.xml
index 3b68c8e..9bfffb6 100644
--- a/wifi/aidl/default/android.hardware.wifi-service.xml
+++ b/wifi/aidl/default/android.hardware.wifi-service.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
 	<hal format="aidl">
 		<name>android.hardware.wifi</name>
-		<version>2</version>
+		<version>3</version>
 		<fqname>IWifi/default</fqname>
 	</hal>
 </manifest>
diff --git a/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
index d58a9b0..513f440 100644
--- a/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
+++ b/wifi/aidl/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -138,6 +138,7 @@
     MOCK_METHOD2(notifyResumeResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
     MOCK_METHOD2(notifyTerminatePairingResponse, ndk::ScopedAStatus(char16_t, const NanStatus&));
     MOCK_METHOD1(eventSuspensionModeChanged, ndk::ScopedAStatus(const NanSuspensionModeChangeInd&));
+    MOCK_METHOD2(notifyRangingResults, ndk::ScopedAStatus(const std::vector<RttResult>&, int8_t));
 };
 
 class WifiNanIfaceTest : public Test {
diff --git a/wifi/aidl/default/wifi_ap_iface.cpp b/wifi/aidl/default/wifi_ap_iface.cpp
index 7779750..6a73cc8 100644
--- a/wifi/aidl/default/wifi_ap_iface.cpp
+++ b/wifi/aidl/default/wifi_ap_iface.cpp
@@ -28,10 +28,12 @@
 namespace wifi {
 using aidl_return_util::validateAndCall;
 
-WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+WifiApIface::WifiApIface(const std::string& ifname, const bool usesMlo,
+                         const std::vector<std::string>& instances,
                          const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
                          const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
     : ifname_(ifname),
+      uses_mlo_(usesMlo),
       instances_(instances),
       legacy_hal_(legacy_hal),
       iface_util_(iface_util),
@@ -50,6 +52,10 @@
     return ifname_;
 }
 
+bool WifiApIface::usesMlo() {
+    return uses_mlo_;
+}
+
 void WifiApIface::removeInstance(std::string instance) {
     instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end());
 }
@@ -72,7 +78,7 @@
 ndk::ScopedAStatus WifiApIface::getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
                            &WifiApIface::getFactoryMacAddressInternal, _aidl_return,
-                           instances_.size() > 0 ? instances_[0] : ifname_);
+                           getOperatingInstanceName());
 }
 
 ndk::ScopedAStatus WifiApIface::resetToFactoryMacAddress() {
@@ -90,14 +96,14 @@
 }
 
 ndk::ScopedAStatus WifiApIface::setCountryCodeInternal(const std::array<uint8_t, 2>& code) {
-    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
-            instances_.size() > 0 ? instances_[0] : ifname_, code);
+    legacy_hal::wifi_error legacy_status =
+            legacy_hal_.lock()->setCountryCode(getOperatingInstanceName(), code);
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
 ndk::ScopedAStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
     // Support random MAC up to 2 interfaces
-    if (instances_.size() == 2) {
+    if (instances_.size() == 2 && !uses_mlo_) {
         int rbyte = 1;
         for (auto const& intf : instances_) {
             std::array<uint8_t, 6> rmac = mac;
@@ -131,7 +137,7 @@
 
 ndk::ScopedAStatus WifiApIface::resetToFactoryMacAddressInternal() {
     std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getMacResult;
-    if (instances_.size() == 2) {
+    if (instances_.size() == 2 && !uses_mlo_) {
         for (auto const& intf : instances_) {
             getMacResult = getFactoryMacAddressInternal(intf);
             LOG(DEBUG) << "Reset MAC to factory MAC on " << intf;
@@ -166,6 +172,11 @@
     return {instances_, ndk::ScopedAStatus::ok()};
 }
 
+ndk::ScopedAStatus WifiApIface::usesMlo(bool* _aidl_return) {
+    *_aidl_return = uses_mlo_;
+    return ndk::ScopedAStatus::ok();
+}
+
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
diff --git a/wifi/aidl/default/wifi_ap_iface.h b/wifi/aidl/default/wifi_ap_iface.h
index 7378f98..e07154d 100644
--- a/wifi/aidl/default/wifi_ap_iface.h
+++ b/wifi/aidl/default/wifi_ap_iface.h
@@ -33,13 +33,15 @@
  */
 class WifiApIface : public BnWifiApIface {
   public:
-    WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
+    WifiApIface(const std::string& ifname, const bool usesMlo,
+                const std::vector<std::string>& instances,
                 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
                 const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util);
     // Refer to |WifiChip::invalidate()|.
     void invalidate();
     bool isValid();
     std::string getName();
+    bool usesMlo();
     void removeInstance(std::string instance);
 
     // AIDL methods exposed.
@@ -49,6 +51,7 @@
     ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
     ndk::ScopedAStatus resetToFactoryMacAddress() override;
     ndk::ScopedAStatus getBridgedInstances(std::vector<std::string>* _aidl_return) override;
+    ndk::ScopedAStatus usesMlo(bool* _aidl_return) override;
 
   private:
     // Corresponding worker functions for the AIDL methods.
@@ -61,11 +64,18 @@
     std::pair<std::vector<std::string>, ndk::ScopedAStatus> getBridgedInstancesInternal();
 
     std::string ifname_;
+    bool uses_mlo_;
     std::vector<std::string> instances_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
     std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
     bool is_valid_;
 
+    // The mlo is using one interface but owning two link instances.
+    // The operating should be based on interface.
+    inline std::string getOperatingInstanceName() {
+        return (instances_.size() > 0 && !uses_mlo_) ? instances_[0] : ifname_;
+    };
+
     DISALLOW_COPY_AND_ASSIGN(WifiApIface);
 };
 
diff --git a/wifi/aidl/default/wifi_chip.cpp b/wifi/aidl/default/wifi_chip.cpp
index fccfc15..045e07d 100644
--- a/wifi/aidl/default/wifi_chip.cpp
+++ b/wifi/aidl/default/wifi_chip.cpp
@@ -369,7 +369,7 @@
 
 ndk::ScopedAStatus WifiChip::createBridgedApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
-                           &WifiChip::createBridgedApIfaceInternal, _aidl_return);
+                           &WifiChip::createBridgedApIfaceInternal, _aidl_return, false);
 }
 
 ndk::ScopedAStatus WifiChip::createApOrBridgedApIface(
@@ -613,6 +613,13 @@
                            &WifiChip::setVoipModeInternal, in_mode);
 }
 
+ndk::ScopedAStatus WifiChip::createApOrBridgedApIfaceWithParams(
+        const ApIfaceParams& in_params, std::shared_ptr<IWifiApIface>* _aidl_return) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::createApOrBridgedApIfaceWithParamsInternal, _aidl_return,
+                           in_params);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
     invalidateAndClearBridgedApAll();
     invalidateAndClearAll(ap_ifaces_);
@@ -797,15 +804,15 @@
     return ndk::ScopedAStatus::ok();
 }
 
-std::shared_ptr<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
+std::shared_ptr<WifiApIface> WifiChip::newWifiApIface(std::string& ifname, bool usesMlo) {
     std::vector<std::string> ap_instances;
     for (auto const& it : br_ifaces_ap_instances_) {
         if (it.first == ifname) {
             ap_instances = it.second;
         }
     }
-    std::shared_ptr<WifiApIface> iface =
-            ndk::SharedRefBase::make<WifiApIface>(ifname, ap_instances, legacy_hal_, iface_util_);
+    std::shared_ptr<WifiApIface> iface = ndk::SharedRefBase::make<WifiApIface>(
+            ifname, usesMlo, ap_instances, legacy_hal_, iface_util_);
     ap_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
         if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
@@ -826,47 +833,60 @@
     if (!status.isOk()) {
         return {std::shared_ptr<WifiApIface>(), std::move(status)};
     }
-    std::shared_ptr<WifiApIface> iface = newWifiApIface(ifname);
+    std::shared_ptr<WifiApIface> iface = newWifiApIface(ifname, false);
     return {iface, ndk::ScopedAStatus::ok()};
 }
 
-std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus>
-WifiChip::createBridgedApIfaceInternal() {
+std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::createBridgedApIfaceInternal(
+        bool usesMlo) {
     if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
         return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
     }
-    std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
+    std::string br_ifname;
+    std::vector<std::string> ap_instances = allocateBridgedApInstanceNames(usesMlo);
     if (ap_instances.size() < 2) {
         LOG(ERROR) << "Fail to allocate two instances";
         return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
     }
-    std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
-    for (int i = 0; i < 2; i++) {
-        ndk::ScopedAStatus status = createVirtualApInterface(ap_instances[i]);
-        if (!status.isOk()) {
-            if (i != 0) {  // The failure happened when creating second virtual
-                           // iface.
-                legacy_hal_.lock()->deleteVirtualInterface(
-                        ap_instances.front());  // Remove the first virtual iface.
+    if (usesMlo) {
+        // MLO SoftAp is using single interface with two links. So only need to create 1 interface.
+        br_ifname = allocateApIfaceName();
+    } else {
+        br_ifname = kApBridgeIfacePrefix + ap_instances[0];
+        for (int i = 0; i < 2; i++) {
+            ndk::ScopedAStatus status = createVirtualApInterface(ap_instances[i]);
+            if (!status.isOk()) {
+                if (i != 0) {  // The failure happened when creating second virtual
+                               // iface.
+                    legacy_hal_.lock()->deleteVirtualInterface(
+                            ap_instances.front());  // Remove the first virtual iface.
+                }
+                return {nullptr, std::move(status)};
             }
-            return {nullptr, std::move(status)};
         }
     }
     br_ifaces_ap_instances_[br_ifname] = ap_instances;
-    if (!iface_util_->createBridge(br_ifname)) {
-        LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
-        deleteApIface(br_ifname);
-        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
-    }
-    for (auto const& instance : ap_instances) {
-        // Bind ap instance interface to AP bridge
-        if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
-            LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
+    if (usesMlo) {
+        ndk::ScopedAStatus status = createVirtualApInterface(br_ifname);
+        if (!status.isOk()) {
+            return {nullptr, std::move(status)};
+        }
+    } else {
+        if (!iface_util_->createBridge(br_ifname)) {
+            LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
             deleteApIface(br_ifname);
             return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
         }
+        for (auto const& instance : ap_instances) {
+            // Bind ap instance interface to AP bridge
+            if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
+                LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
+                deleteApIface(br_ifname);
+                return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
+            }
+        }
     }
-    std::shared_ptr<WifiApIface> iface = newWifiApIface(br_ifname);
+    std::shared_ptr<WifiApIface> iface = newWifiApIface(br_ifname, usesMlo);
     return {iface, ndk::ScopedAStatus::ok()};
 }
 
@@ -876,7 +896,18 @@
     if (ifaceType == IfaceConcurrencyType::AP) {
         return createApIfaceInternal();
     } else if (ifaceType == IfaceConcurrencyType::AP_BRIDGED) {
-        return createBridgedApIfaceInternal();
+        return createBridgedApIfaceInternal(false);
+    } else {
+        return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
+    }
+}
+
+std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus>
+WifiChip::createApOrBridgedApIfaceWithParamsInternal(const ApIfaceParams& params) {
+    if (params.ifaceType == IfaceConcurrencyType::AP) {
+        return createApIfaceInternal();
+    } else if (params.ifaceType == IfaceConcurrencyType::AP_BRIDGED) {
+        return createBridgedApIfaceInternal(params.usesMlo);
     } else {
         return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
     }
@@ -925,23 +956,28 @@
     if (!iface.get() || ifInstanceName.empty()) {
         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
     }
+
     // Requires to remove one of the instance in bridge mode
     for (auto const& it : br_ifaces_ap_instances_) {
         if (it.first == ifname) {
             std::vector<std::string> ap_instances = it.second;
-            for (auto const& iface : ap_instances) {
-                if (iface == ifInstanceName) {
-                    if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
-                        LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
-                                   << ifname;
-                        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
-                    }
-                    legacy_hal::wifi_error legacy_status =
-                            legacy_hal_.lock()->deleteVirtualInterface(iface);
-                    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
-                        LOG(ERROR) << "Failed to del interface: " << iface << " "
-                                   << legacyErrorToString(legacy_status);
-                        return createWifiStatusFromLegacyError(legacy_status);
+            for (auto const& instance : ap_instances) {
+                if (instance == ifInstanceName) {
+                    if (iface->usesMlo()) {
+                        LOG(INFO) << "Remove Link " << ifInstanceName << " from " << ifname;
+                    } else {
+                        if (!iface_util_->removeIfaceFromBridge(it.first, instance)) {
+                            LOG(ERROR) << "Failed to remove interface: " << ifInstanceName
+                                       << " from " << ifname;
+                            return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
+                        }
+                        legacy_hal::wifi_error legacy_status =
+                                legacy_hal_.lock()->deleteVirtualInterface(instance);
+                        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+                            LOG(ERROR) << "Failed to del interface: " << instance << " "
+                                       << legacyErrorToString(legacy_status);
+                            return createWifiStatusFromLegacyError(legacy_status);
+                        }
                     }
                     ap_instances.erase(
                             std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
@@ -1729,7 +1765,7 @@
         // If the first active wlan iface is bridged iface.
         // Return first instance name.
         for (auto const& it : br_ifaces_ap_instances_) {
-            if (it.first == ap_ifaces_[0]->getName()) {
+            if (it.first == ap_ifaces_[0]->getName() && !ap_ifaces_[0]->usesMlo()) {
                 return it.second[0];
             }
         }
@@ -1782,9 +1818,19 @@
     return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
 }
 
-std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
-    // Check if we have a dedicated iface for AP.
-    std::vector<std::string> instances = getPredefinedApIfaceNames(true);
+std::vector<std::string> WifiChip::allocateBridgedApInstanceNames(bool usesMlo) {
+    std::vector<std::string> instances;
+    if (usesMlo) {
+        // For MLO AP, the instances are MLO links and it will be maintained in hostapd.
+        // The hostapd will use 0 as an initial link id and 1 as the next.
+        // Considering Android didn't support link reconfiguration. Forcing to use 0 & 1
+        // should work.
+        instances.push_back("0");
+        instances.push_back("1");
+    } else {
+        // Check if we have a dedicated iface for AP.
+        instances = getPredefinedApIfaceNames(true);
+    }
     if (instances.size() == 2) {
         return instances;
     } else {
@@ -1856,11 +1902,14 @@
 
 void WifiChip::invalidateAndClearBridgedApAll() {
     for (auto const& it : br_ifaces_ap_instances_) {
-        for (auto const& iface : it.second) {
-            iface_util_->removeIfaceFromBridge(it.first, iface);
-            legacy_hal_.lock()->deleteVirtualInterface(iface);
+        const auto iface = findUsingName(ap_ifaces_, it.first);
+        if (!iface->usesMlo()) {
+            for (auto const& iface : it.second) {
+                iface_util_->removeIfaceFromBridge(it.first, iface);
+                legacy_hal_.lock()->deleteVirtualInterface(iface);
+            }
+            iface_util_->deleteBridge(it.first);
         }
-        iface_util_->deleteBridge(it.first);
     }
     br_ifaces_ap_instances_.clear();
 }
@@ -1868,16 +1917,19 @@
 void WifiChip::deleteApIface(const std::string& if_name) {
     if (if_name.empty()) return;
     // delete bridged interfaces if any
-    for (auto const& it : br_ifaces_ap_instances_) {
-        if (it.first == if_name) {
-            for (auto const& iface : it.second) {
-                iface_util_->removeIfaceFromBridge(if_name, iface);
-                legacy_hal_.lock()->deleteVirtualInterface(iface);
+    const auto iface = findUsingName(ap_ifaces_, if_name);
+    if (!iface->usesMlo()) {
+        for (auto const& it : br_ifaces_ap_instances_) {
+            if (it.first == if_name) {
+                for (auto const& instance : it.second) {
+                    iface_util_->removeIfaceFromBridge(if_name, instance);
+                    legacy_hal_.lock()->deleteVirtualInterface(instance);
+                }
+                iface_util_->deleteBridge(if_name);
+                br_ifaces_ap_instances_.erase(if_name);
+                // ifname is bridged AP, return here.
+                return;
             }
-            iface_util_->deleteBridge(if_name);
-            br_ifaces_ap_instances_.erase(if_name);
-            // ifname is bridged AP, return here.
-            return;
         }
     }
 
diff --git a/wifi/aidl/default/wifi_chip.h b/wifi/aidl/default/wifi_chip.h
index ffd507f..24dd00d 100644
--- a/wifi/aidl/default/wifi_chip.h
+++ b/wifi/aidl/default/wifi_chip.h
@@ -159,6 +159,8 @@
     binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
     ndk::ScopedAStatus setMloMode(const ChipMloMode in_mode) override;
     ndk::ScopedAStatus setVoipMode(const VoipMode in_mode) override;
+    ndk::ScopedAStatus createApOrBridgedApIfaceWithParams(
+            const ApIfaceParams& in_params, std::shared_ptr<IWifiApIface>* _aidl_return) override;
 
   private:
     void invalidateAndRemoveAllIfaces();
@@ -178,12 +180,15 @@
     std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> requestChipDebugInfoInternal();
     std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> requestDriverDebugDumpInternal();
     std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> requestFirmwareDebugDumpInternal();
-    std::shared_ptr<WifiApIface> newWifiApIface(std::string& ifname);
+    std::shared_ptr<WifiApIface> newWifiApIface(std::string& ifname, bool usesMlo);
     ndk::ScopedAStatus createVirtualApInterface(const std::string& apVirtIf);
     std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createApIfaceInternal();
-    std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createBridgedApIfaceInternal();
+    std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createBridgedApIfaceInternal(
+            bool usesMlo);
     std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> createApOrBridgedApIfaceInternal(
             IfaceConcurrencyType ifaceType, const std::vector<common::OuiKeyedData>& vendorData);
+    std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus>
+    createApOrBridgedApIfaceWithParamsInternal(const ApIfaceParams& params);
     std::pair<std::vector<std::string>, ndk::ScopedAStatus> getApIfaceNamesInternal();
     std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> getApIfaceInternal(
             const std::string& ifname);
@@ -258,7 +263,7 @@
     std::string getFirstActiveWlanIfaceName();
     std::string allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx);
     std::string allocateApIfaceName();
-    std::vector<std::string> allocateBridgedApInstanceNames();
+    std::vector<std::string> allocateBridgedApInstanceNames(bool usesMlo);
     std::string allocateStaIfaceName();
     bool writeRingbufferFilesInternal();
     std::string getWlanIfaceNameWithType(IfaceType type, unsigned idx);
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index bd92a20..8d69013 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -372,6 +372,16 @@
     }
 }
 
+std::function<void(wifi_rtt_result* rtt_results[], uint32_t num_results, uint16_t session_id)>
+        on_nan_event_ranging_results_callback;
+void onAsyncNanEventRangingResults(wifi_rtt_result* rtt_results[], uint32_t num_results,
+                                   uint16_t session_id) {
+    const auto lock = aidl_sync_util::acquireGlobalLock();
+    if (on_nan_event_ranging_results_callback && rtt_results) {
+        on_nan_event_ranging_results_callback(rtt_results, num_results, session_id);
+    }
+}
+
 std::function<void(const NanPairingRequestInd&)> on_nan_event_pairing_request_user_callback;
 void onAsyncNanEventPairingRequest(NanPairingRequestInd* event) {
     const auto lock = aidl_sync_util::acquireGlobalLock();
@@ -1510,6 +1520,7 @@
     on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update;
     on_nan_event_suspension_mode_change_user_callback =
             user_callbacks.on_event_suspension_mode_change;
+    on_nan_event_ranging_results_callback = user_callbacks.on_ranging_results;
 
     return global_func_table_.wifi_nan_register_handler(getIfaceHandle(iface_name),
                                                         {onAsyncNanNotifyResponse,
@@ -1534,7 +1545,8 @@
                                                          onAsyncNanEventPairingConfirm,
                                                          onAsyncNanEventBootstrappingRequest,
                                                          onAsyncNanEventBootstrappingConfirm,
-                                                         onAsyncNanEventSuspensionModeChange});
+                                                         onAsyncNanEventSuspensionModeChange,
+                                                         onAsyncNanEventRangingResults});
 }
 
 wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id,
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index 3fd567b..f603210 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -63,6 +63,7 @@
 using ::NAN_DP_REQUEST_CHANNEL_SETUP;
 using ::NAN_DP_REQUEST_REJECT;
 using ::NAN_DP_RESPONDER_RESPONSE;
+using ::NAN_ENABLE_RANGE_REPORT;
 using ::NAN_GET_CAPABILITIES;
 using ::NAN_MATCH_ALG_MATCH_CONTINUOUS;
 using ::NAN_MATCH_ALG_MATCH_NEVER;
@@ -212,10 +213,16 @@
 using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
 using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE;
 using ::RTT_STATUS_NO_WIFI;
+using ::RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_AKM;
+using ::RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_CIPHER;
+using ::RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_CONFIG;
+using ::RTT_STATUS_SECURE_RANGING_FAILURE_REJECTED;
+using ::RTT_STATUS_SECURE_RANGING_FAILURE_UNKNOWN;
 using ::RTT_STATUS_SUCCESS;
 using ::RTT_TYPE_1_SIDED;
 using ::RTT_TYPE_2_SIDED;
 using ::RTT_TYPE_2_SIDED_11AZ_NTB;
+using ::RTT_TYPE_2_SIDED_11AZ_NTB_SECURE;
 using ::RTT_TYPE_2_SIDED_11MC;
 using ::RX_PKT_FATE_DRV_DROP_FILTER;
 using ::RX_PKT_FATE_DRV_DROP_INVALID;
@@ -482,6 +489,8 @@
     std::function<void(const NanBootstrappingRequestInd&)> on_event_bootstrapping_request;
     std::function<void(const NanBootstrappingConfirmInd&)> on_event_bootstrapping_confirm;
     std::function<void(const NanSuspensionModeChangeInd&)> on_event_suspension_mode_change;
+    std::function<void(wifi_rtt_result* rtt_results[], uint32_t num_results, uint16_t session_id)>
+            on_ranging_results;
 };
 
 // Full scan results contain IE info and are hence passed by reference, to
diff --git a/wifi/aidl/default/wifi_nan_iface.cpp b/wifi/aidl/default/wifi_nan_iface.cpp
index cefe7f7..950e647 100644
--- a/wifi/aidl/default/wifi_nan_iface.cpp
+++ b/wifi/aidl/default/wifi_nan_iface.cpp
@@ -613,7 +613,36 @@
                     }
                 }
             };
+    callback_handlers.on_ranging_results = [weak_ptr_this](
+                                                   legacy_hal::wifi_rtt_result* rtt_results[],
+                                                   uint32_t num_results, uint16_t session_id) {
+        const auto shared_ptr_this = weak_ptr_this.lock();
+        if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
+            LOG(ERROR) << "Callback invoked on an invalid object";
+            return;
+        }
+        if (shared_ptr_this->getMinCallbackVersion() < 3) {
+            LOG(INFO) << "notifyRangingResults requires callback version 3";
+            return;
+        }
 
+        std::vector<const wifi_rtt_result*> legacy_results;
+        std::copy_if(rtt_results, rtt_results + num_results, back_inserter(legacy_results),
+                     [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
+
+        std::vector<RttResult> aidl_results;
+        if (!aidl_struct_util::convertLegacyVectorOfRttResultToAidl(legacy_results,
+                                                                    &aidl_results)) {
+            LOG(ERROR) << "Failed to convert RTT results to AIDL structs";
+            return;
+        }
+
+        for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
+            if (!callback->notifyRangingResults(aidl_results, session_id).isOk()) {
+                LOG(ERROR) << "Failed to invoke the callback";
+            }
+        }
+    };
     legacy_hal::wifi_error legacy_status =
             legacy_hal_.lock()->nanRegisterCallbackHandlers(ifname_, callback_handlers);
     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
@@ -672,6 +701,10 @@
     return ifname_;
 }
 
+int32_t WifiNanIface::getMinCallbackVersion() {
+    return event_cb_handler_.getMinCallbackVersion();
+}
+
 std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> WifiNanIface::getEventCallbacks() {
     LOG(ERROR) << "Using original getEventCallbacks";
     return event_cb_handler_.getCallbacks();
diff --git a/wifi/aidl/default/wifi_nan_iface.h b/wifi/aidl/default/wifi_nan_iface.h
index a49ae8c..d2d1d5c 100644
--- a/wifi/aidl/default/wifi_nan_iface.h
+++ b/wifi/aidl/default/wifi_nan_iface.h
@@ -134,6 +134,8 @@
     ndk::ScopedAStatus suspendRequestInternal(char16_t in_cmdId, int8_t sessionId);
     ndk::ScopedAStatus resumeRequestInternal(char16_t in_cmdId, int8_t sessionId);
 
+    int32_t getMinCallbackVersion();
+
     // Overridden in the gTest suite.
     virtual std::set<std::shared_ptr<IWifiNanIfaceEventCallback>> getEventCallbacks();
 
diff --git a/wifi/aidl/vts/functional/Android.bp b/wifi/aidl/vts/functional/Android.bp
index 9994d09..429c0c5 100644
--- a/wifi/aidl/vts/functional/Android.bp
+++ b/wifi/aidl/vts/functional/Android.bp
@@ -40,8 +40,8 @@
     ],
     static_libs: [
         "VtsHalWifiTargetTestUtil",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "libwifi-system-iface",
     ],
     test_suites: [
@@ -66,8 +66,8 @@
     ],
     static_libs: [
         "VtsHalWifiTargetTestUtil",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "libwifi-system-iface",
     ],
     test_suites: [
@@ -92,8 +92,8 @@
     ],
     static_libs: [
         "VtsHalWifiTargetTestUtil",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "libwifi-system-iface",
     ],
     test_suites: [
@@ -118,8 +118,8 @@
     ],
     static_libs: [
         "VtsHalWifiTargetTestUtil",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "libwifi-system-iface",
     ],
     test_suites: [
@@ -144,8 +144,8 @@
     ],
     static_libs: [
         "VtsHalWifiTargetTestUtil",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "libwifi-system-iface",
     ],
     test_suites: [
@@ -169,8 +169,8 @@
         "libnativehelper",
     ],
     static_libs: [
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "libwifi-system-iface",
     ],
 }
diff --git a/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
index bc169a4..d646162 100644
--- a/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_nan_iface_aidl_test.cpp
@@ -58,6 +58,7 @@
 using aidl::android::hardware::wifi::NanStatusCode;
 using aidl::android::hardware::wifi::NanSuspensionModeChangeInd;
 using aidl::android::hardware::wifi::NanTxType;
+using aidl::android::hardware::wifi::RttResult;
 
 #define TIMEOUT_PERIOD 10
 
@@ -106,6 +107,7 @@
         NOTIFY_SUSPEND_RESPONSE,
         NOTIFY_RESUME_RESPONSE,
         NOTIFY_TERMINATE_PAIRING_RESPONSE,
+        NOTIFY_RANGING_RESULTS,
 
         EVENT_CLUSTER_EVENT,
         EVENT_DISABLED,
@@ -400,6 +402,12 @@
             parent_.notify(NOTIFY_TERMINATE_PAIRING_RESPONSE);
             return ndk::ScopedAStatus::ok();
         }
+        ::ndk::ScopedAStatus notifyRangingResults(const std::vector<RttResult>& /* results */,
+                                                  int8_t discoverySessionId) override {
+            parent_.session_id_ = discoverySessionId;
+            parent_.notify(NOTIFY_RANGING_RESULTS);
+            return ndk::ScopedAStatus::ok();
+        }
 
       private:
         WifiNanIfaceAidlTest& parent_;
diff --git a/wifi/common/aidl/Android.bp b/wifi/common/aidl/Android.bp
index 0920a55..8ea54be 100644
--- a/wifi/common/aidl/Android.bp
+++ b/wifi/common/aidl/Android.bp
@@ -54,6 +54,6 @@
             imports: [],
         },
     ],
-    frozen: true,
+    frozen: false,
 
 }
diff --git a/wifi/common/aidl/aidl_api/android.hardware.wifi.common/current/android/hardware/wifi/common/DeauthenticationReasonCode.aidl b/wifi/common/aidl/aidl_api/android.hardware.wifi.common/current/android/hardware/wifi/common/DeauthenticationReasonCode.aidl
new file mode 100644
index 0000000..2404b2c
--- /dev/null
+++ b/wifi/common/aidl/aidl_api/android.hardware.wifi.common/current/android/hardware/wifi/common/DeauthenticationReasonCode.aidl
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi.common;
+@Backing(type="int") @VintfStability
+enum DeauthenticationReasonCode {
+  HOSTAPD_NO_REASON = 0,
+  UNSPECIFIED = 1,
+  PREV_AUTH_NOT_VALID = 2,
+  DEAUTH_LEAVING = 3,
+  DISASSOC_DUE_TO_INACTIVITY = 4,
+  DISASSOC_AP_BUSY = 5,
+  CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+  CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+  DISASSOC_STA_HAS_LEFT = 8,
+  STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+  PWR_CAPABILITY_NOT_VALID = 10,
+  SUPPORTED_CHANNEL_NOT_VALID = 11,
+  BSS_TRANSITION_DISASSOC = 12,
+  INVALID_IE = 13,
+  MICHAEL_MIC_FAILURE = 14,
+  FOURWAY_HANDSHAKE_TIMEOUT = 15,
+  GROUP_KEY_UPDATE_TIMEOUT = 16,
+  IE_IN_4WAY_DIFFERS = 17,
+  GROUP_CIPHER_NOT_VALID = 18,
+  PAIRWISE_CIPHER_NOT_VALID = 19,
+  AKMP_NOT_VALID = 20,
+  UNSUPPORTED_RSN_IE_VERSION = 21,
+  INVALID_RSN_IE_CAPAB = 22,
+  IEEE_802_1X_AUTH_FAILED = 23,
+  CIPHER_SUITE_REJECTED = 24,
+  TDLS_TEARDOWN_UNREACHABLE = 25,
+  TDLS_TEARDOWN_UNSPECIFIED = 26,
+  SSP_REQUESTED_DISASSOC = 27,
+  NO_SSP_ROAMING_AGREEMENT = 28,
+  BAD_CIPHER_OR_AKM = 29,
+  NOT_AUTHORIZED_THIS_LOCATION = 30,
+  SERVICE_CHANGE_PRECLUDES_TS = 31,
+  UNSPECIFIED_QOS_REASON = 32,
+  NOT_ENOUGH_BANDWIDTH = 33,
+  DISASSOC_LOW_ACK = 34,
+  EXCEEDED_TXOP = 35,
+  STA_LEAVING = 36,
+  END_TS_BA_DLS = 37,
+  UNKNOWN_TS_BA = 38,
+  TIMEOUT = 39,
+  PEERKEY_MISMATCH = 45,
+  AUTHORIZED_ACCESS_LIMIT_REACHED = 46,
+  EXTERNAL_SERVICE_REQUIREMENTS = 47,
+  INVALID_FT_ACTION_FRAME_COUNT = 48,
+  INVALID_PMKID = 49,
+  INVALID_MDE = 50,
+  INVALID_FTE = 51,
+  MESH_PEERING_CANCELLED = 52,
+  MESH_MAX_PEERS = 53,
+  MESH_CONFIG_POLICY_VIOLATION = 54,
+  MESH_CLOSE_RCVD = 55,
+  MESH_MAX_RETRIES = 56,
+  MESH_CONFIRM_TIMEOUT = 57,
+  MESH_INVALID_GTK = 58,
+  MESH_INCONSISTENT_PARAMS = 59,
+  MESH_INVALID_SECURITY_CAP = 60,
+  MESH_PATH_ERROR_NO_PROXY_INFO = 61,
+  MESH_PATH_ERROR_NO_FORWARDING_INFO = 62,
+  MESH_PATH_ERROR_DEST_UNREACHABLE = 63,
+  MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
+  MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65,
+  MESH_CHANNEL_SWITCH_UNSPECIFIED = 66,
+}
diff --git a/wifi/common/aidl/android/hardware/wifi/common/DeauthenticationReasonCode.aidl b/wifi/common/aidl/android/hardware/wifi/common/DeauthenticationReasonCode.aidl
new file mode 100644
index 0000000..95eb31d
--- /dev/null
+++ b/wifi/common/aidl/android/hardware/wifi/common/DeauthenticationReasonCode.aidl
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.common;
+
+/**
+ * Reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45).
+ *
+ * Note: HOSTAPD_NO_REASON is the default return from hostapd, even though it
+ * does not appear in the IEEE spec.
+ */
+@VintfStability
+@Backing(type="int")
+enum DeauthenticationReasonCode {
+    HOSTAPD_NO_REASON = 0,
+    UNSPECIFIED = 1,
+    PREV_AUTH_NOT_VALID = 2,
+    DEAUTH_LEAVING = 3,
+    DISASSOC_DUE_TO_INACTIVITY = 4,
+    DISASSOC_AP_BUSY = 5,
+    CLASS2_FRAME_FROM_NONAUTH_STA = 6,
+    CLASS3_FRAME_FROM_NONASSOC_STA = 7,
+    DISASSOC_STA_HAS_LEFT = 8,
+    STA_REQ_ASSOC_WITHOUT_AUTH = 9,
+    PWR_CAPABILITY_NOT_VALID = 10,
+    SUPPORTED_CHANNEL_NOT_VALID = 11,
+    BSS_TRANSITION_DISASSOC = 12,
+    INVALID_IE = 13,
+    MICHAEL_MIC_FAILURE = 14,
+    FOURWAY_HANDSHAKE_TIMEOUT = 15,
+    GROUP_KEY_UPDATE_TIMEOUT = 16,
+    IE_IN_4WAY_DIFFERS = 17,
+    GROUP_CIPHER_NOT_VALID = 18,
+    PAIRWISE_CIPHER_NOT_VALID = 19,
+    AKMP_NOT_VALID = 20,
+    UNSUPPORTED_RSN_IE_VERSION = 21,
+    INVALID_RSN_IE_CAPAB = 22,
+    IEEE_802_1X_AUTH_FAILED = 23,
+    CIPHER_SUITE_REJECTED = 24,
+    TDLS_TEARDOWN_UNREACHABLE = 25,
+    TDLS_TEARDOWN_UNSPECIFIED = 26,
+    SSP_REQUESTED_DISASSOC = 27,
+    NO_SSP_ROAMING_AGREEMENT = 28,
+    BAD_CIPHER_OR_AKM = 29,
+    NOT_AUTHORIZED_THIS_LOCATION = 30,
+    SERVICE_CHANGE_PRECLUDES_TS = 31,
+    UNSPECIFIED_QOS_REASON = 32,
+    NOT_ENOUGH_BANDWIDTH = 33,
+    DISASSOC_LOW_ACK = 34,
+    EXCEEDED_TXOP = 35,
+    STA_LEAVING = 36,
+    END_TS_BA_DLS = 37,
+    UNKNOWN_TS_BA = 38,
+    TIMEOUT = 39,
+    PEERKEY_MISMATCH = 45,
+    AUTHORIZED_ACCESS_LIMIT_REACHED = 46,
+    EXTERNAL_SERVICE_REQUIREMENTS = 47,
+    INVALID_FT_ACTION_FRAME_COUNT = 48,
+    INVALID_PMKID = 49,
+    INVALID_MDE = 50,
+    INVALID_FTE = 51,
+    MESH_PEERING_CANCELLED = 52,
+    MESH_MAX_PEERS = 53,
+    MESH_CONFIG_POLICY_VIOLATION = 54,
+    MESH_CLOSE_RCVD = 55,
+    MESH_MAX_RETRIES = 56,
+    MESH_CONFIRM_TIMEOUT = 57,
+    MESH_INVALID_GTK = 58,
+    MESH_INCONSISTENT_PARAMS = 59,
+    MESH_INVALID_SECURITY_CAP = 60,
+    MESH_PATH_ERROR_NO_PROXY_INFO = 61,
+    MESH_PATH_ERROR_NO_FORWARDING_INFO = 62,
+    MESH_PATH_ERROR_DEST_UNREACHABLE = 63,
+    MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS = 64,
+    MESH_CHANNEL_SWITCH_REGULATORY_REQ = 65,
+    MESH_CHANNEL_SWITCH_UNSPECIFIED = 66,
+}
diff --git a/wifi/hostapd/aidl/Android.bp b/wifi/hostapd/aidl/Android.bp
index 88f4ef2..85d71f3 100644
--- a/wifi/hostapd/aidl/Android.bp
+++ b/wifi/hostapd/aidl/Android.bp
@@ -29,7 +29,7 @@
         "android/hardware/wifi/hostapd/*.aidl",
     ],
     imports: [
-        "android.hardware.wifi.common-V1",
+        "android.hardware.wifi.common-V2",
     ],
     stability: "vintf",
     backend: {
@@ -41,7 +41,9 @@
             ],
             min_sdk_version: "30",
             lint: {
-                baseline_filename: "lint-baseline.xml",
+                // Disable linter to avoid error about fixed size arrays.
+                // Interface will only be accessed on devices >= T.
+                enabled: false,
             },
         },
         ndk: {
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
index 1a66105..0af90d2 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
@@ -41,4 +41,5 @@
   android.hardware.wifi.hostapd.Generation generation;
   byte[] apIfaceInstanceMacAddress;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  @nullable byte[6] mldMacAddress;
 }
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ClientInfo.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ClientInfo.aidl
index c4d62b6..c4db789 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ClientInfo.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ClientInfo.aidl
@@ -38,4 +38,5 @@
   String apIfaceInstance;
   byte[] clientAddress;
   boolean isConnected;
+  android.hardware.wifi.common.DeauthenticationReasonCode disconnectReasonCode;
 }
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IHostapd.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IHostapd.aidl
index ff941fd..3898bb8 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IHostapd.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IHostapd.aidl
@@ -40,4 +40,5 @@
   void removeAccessPoint(in String ifaceName);
   void setDebugParams(in android.hardware.wifi.hostapd.DebugLevel level);
   oneway void terminate();
+  void removeLinkFromMultipleLinkBridgedApIface(in String ifaceName, in String linkIdentity);
 }
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
index 8da3441..7b67102 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/IfaceParams.aidl
@@ -39,5 +39,5 @@
   android.hardware.wifi.hostapd.ChannelParams[] channelParams;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
   @nullable String[] instanceIdentities;
-  boolean isMlo;
+  boolean usesMlo;
 }
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
index 4554223..b6c5cf2 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/NetworkParams.aidl
@@ -40,4 +40,5 @@
   String passphrase;
   boolean isMetered;
   byte[] vendorElements;
+  boolean isClientIsolationEnabled;
 }
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
index f2b2ee6..8aea70c 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
@@ -63,4 +63,9 @@
      * Optional vendor-specific information.
      */
     @nullable OuiKeyedData[] vendorData;
+
+    /**
+     * MAC Address of the multiple link device (MLD) which apIfaceInstance is associated with.
+     */
+    @nullable byte[6] mldMacAddress;
 }
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ClientInfo.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ClientInfo.aidl
index 7bed658..a7ca1ec 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ClientInfo.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ClientInfo.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.wifi.hostapd;
 
+import android.hardware.wifi.common.DeauthenticationReasonCode;
+
 /**
  * Parameters to control the channel selection for the interface.
  */
@@ -42,4 +44,9 @@
      * True when client connected, false when client disconnected.
      */
     boolean isConnected;
+
+    /**
+     * Reason for client disconnect from soft ap.
+     */
+    DeauthenticationReasonCode disconnectReasonCode;
 }
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IHostapd.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IHostapd.aidl
index d2f4795..cd552ab 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IHostapd.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IHostapd.aidl
@@ -103,4 +103,22 @@
      * wait to be restarted.
      */
     oneway void terminate();
+
+    /**
+     * Removes an existing link from multiple link device which the current AP resides on.
+     *
+     * The multiple link device is an access point which was added by |IHostapd.addAccessPoint| with
+     * |IfaceParams.usesMlo| set to true.
+     *
+     * @param ifaceName Name of the interface which was added by |IHostapd.addAccessPoint|
+     * @param linkIdentity the identity of the link which associated to the multiple link device
+     * that the current AP resides on. The link identity should be one of the identities provided in
+     * |IfaceParams.instanceIdentities| when this iface was created.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |HostapdStatusCode.FAILURE_UNKNOWN|,
+     *         |HostapdStatusCode.FAILURE_ARGS_INVALID| when the linkIdentity mis-matches one of the
+     *             identities provided in |IfaceParams.instanceIdentities|.
+     *         |HostapdStatusCode.FAILURE_IFACE_UNKNOWN| when current existing AP isn't using mlo.
+     */
+    void removeLinkFromMultipleLinkBridgedApIface(in String ifaceName, in String linkIdentity);
 }
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
index bb646e3..f4e4647 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/IfaceParams.aidl
@@ -46,7 +46,7 @@
      */
     @nullable String[] instanceIdentities;
     /**
-     * Whether the current iface is MLO.
+     * Whether the current iface is using multi-link operation.
      */
-    boolean isMlo;
+    boolean usesMlo;
 }
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
index 47d9e6f..acc2cad 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/NetworkParams.aidl
@@ -52,4 +52,8 @@
      * one or more elements). Example: byte[]{ 221, 4, 17, 34, 51, 1 }
      */
     byte[] vendorElements;
+    /**
+     * Whether the network uses client isolation.
+     */
+    boolean isClientIsolationEnabled;
 }
diff --git a/wifi/hostapd/aidl/lint-baseline.xml b/wifi/hostapd/aidl/lint-baseline.xml
index 4329e12..23fe690 100644
--- a/wifi/hostapd/aidl/lint-baseline.xml
+++ b/wifi/hostapd/aidl/lint-baseline.xml
@@ -63,4 +63,22 @@
             file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V3-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"/>
     </issue>
 
-</issues>
\ No newline at end of file
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V4-java-source/gen/android/hardware/wifi/hostapd/IHostapd.java"/>
+    </issue>
+
+    <issue
+        id="NewApi"
+        message="Call requires API level 31 (current min is 30): `android.os.Binder#markVintfStability`"
+        errorLine1="      this.markVintfStability();"
+        errorLine2="           ~~~~~~~~~~~~~~~~~~">
+        <location
+            file="out/soong/.intermediates/hardware/interfaces/wifi/hostapd/aidl/android.hardware.wifi.hostapd-V4-java-source/gen/android/hardware/wifi/hostapd/IHostapdCallback.java"/>
+    </issue>
+
+</issues>
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index bf1b0d0..de31e14 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -37,8 +37,8 @@
         "android.hardware.wifi@1.4",
         "android.hardware.wifi@1.5",
         "android.hardware.wifi@1.6",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "libwifi-system",
         "libwifi-system-iface",
         "VtsHalWifiTargetTestUtil",
diff --git a/wifi/legacy_headers/include/hardware_legacy/rtt.h b/wifi/legacy_headers/include/hardware_legacy/rtt.h
index 426abe0..3fa4e95 100644
--- a/wifi/legacy_headers/include/hardware_legacy/rtt.h
+++ b/wifi/legacy_headers/include/hardware_legacy/rtt.h
@@ -7,24 +7,33 @@
 
 /* Ranging status */
 typedef enum {
-    RTT_STATUS_SUCCESS       = 0,
-    RTT_STATUS_FAILURE       = 1,           // general failure status
-    RTT_STATUS_FAIL_NO_RSP   = 2,           // target STA does not respond to request
-    RTT_STATUS_FAIL_REJECTED = 3,           // request rejected. Applies to 2-sided RTT only
-    RTT_STATUS_FAIL_NOT_SCHEDULED_YET  = 4,
-    RTT_STATUS_FAIL_TM_TIMEOUT         = 5, // timing measurement times out
-    RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6, // Target on different channel, cannot range
-    RTT_STATUS_FAIL_NO_CAPABILITY  = 7,     // ranging not supported
-    RTT_STATUS_ABORTED             = 8,     // request aborted for unknown reason
-    RTT_STATUS_FAIL_INVALID_TS     = 9,     // Invalid T1-T4 timestamp
-    RTT_STATUS_FAIL_PROTOCOL       = 10,    // 11mc protocol failed
-    RTT_STATUS_FAIL_SCHEDULE       = 11,    // request could not be scheduled
-    RTT_STATUS_FAIL_BUSY_TRY_LATER = 12,    // responder cannot collaborate at time of request
-    RTT_STATUS_INVALID_REQ         = 13,    // bad request args
-    RTT_STATUS_NO_WIFI             = 14,    // WiFi not enabled
-    RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15, // Responder overrides param info, cannot range with new params
-    RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE =16, //Negotiation failure
-    RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED=17, //concurrency not supported (NDP+RTT)
+    RTT_STATUS_SUCCESS = 0,
+    RTT_STATUS_FAILURE = 1,        // general failure status
+    RTT_STATUS_FAIL_NO_RSP = 2,    // target STA does not respond to request
+    RTT_STATUS_FAIL_REJECTED = 3,  // request rejected. Applies to 2-sided RTT only
+    RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4,
+    RTT_STATUS_FAIL_TM_TIMEOUT = 5,          // timing measurement times out
+    RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6,  // Target on different channel, cannot range
+    RTT_STATUS_FAIL_NO_CAPABILITY = 7,       // ranging not supported
+    RTT_STATUS_ABORTED = 8,                  // request aborted for unknown reason
+    RTT_STATUS_FAIL_INVALID_TS = 9,          // Invalid T1-T4 timestamp
+    RTT_STATUS_FAIL_PROTOCOL = 10,           // 11mc protocol failed
+    RTT_STATUS_FAIL_SCHEDULE = 11,           // request could not be scheduled
+    RTT_STATUS_FAIL_BUSY_TRY_LATER = 12,     // responder cannot collaborate at time of request
+    RTT_STATUS_INVALID_REQ = 13,             // bad request args
+    RTT_STATUS_NO_WIFI = 14,                 // WiFi not enabled
+    RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE =
+            15,  // Responder overrides param info, cannot range with new params
+    RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE = 16,           // Negotiation failure
+    RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED = 17,  // concurrency not supported (NDP+RTT)
+    RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_AKM = 18,  // Secure Ranging failed due to invalid AKM
+                                                         // (Authentication and Key Management)
+    RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_CIPHER = 19,  // Secure Ranging failed due to invalid
+                                                            // Cipher
+    RTT_STATUS_SECURE_RANGING_FAILURE_INVALID_CONFIG = 20,  // Secure Ranging failed due to invalid
+                                                            // configuration
+    RTT_STATUS_SECURE_RANGING_FAILURE_REJECTED = 21,        // Secure ranging rejected by the AP.2
+    RTT_STATUS_SECURE_RANGING_FAILURE_UNKNOWN = 22,         // Secure ranging failure unknown
 } wifi_rtt_status;
 
 /* RTT peer type */
@@ -60,14 +69,60 @@
 
 /* RTT Type */
 typedef enum {
-    RTT_TYPE_1_SIDED          = 0x1,
+    RTT_TYPE_1_SIDED = 0x1,
     /* Deprecated. Use RTT_TYPE_2_SIDED_11MC instead. */
-    RTT_TYPE_2_SIDED          = 0x2,
-    RTT_TYPE_2_SIDED_11MC     = RTT_TYPE_2_SIDED,
+    RTT_TYPE_2_SIDED = 0x2,
+    RTT_TYPE_2_SIDED_11MC = RTT_TYPE_2_SIDED,
     RTT_TYPE_2_SIDED_11AZ_NTB = 0x3,
-
+    RTT_TYPE_2_SIDED_11AZ_NTB_SECURE = 0x4,
 } wifi_rtt_type;
 
+/* RTT AKM type */
+typedef enum {
+    WPA_KEY_MGMT_NONE = 0x0,
+    WPA_KEY_MGMT_PASN = 0x1,
+    WPA_KEY_MGMT_SAE = 0x2,
+    WPA_KEY_MGMT_EAP_FT_SHA256 = 0x4,
+    WPA_KEY_MGMT_FT_PSK_SHA256 = 0x8,
+    WPA_KEY_MGMT_EAP_FT_SHA384 = 0x10,
+    WPA_KEY_MGMT_FT_PSK_SHA384 = 0x20,
+    WPA_KEY_MGMT_EAP_FILS_SHA256 = 0x40,
+    WPA_KEY_MGMT_EAP_FILS_SHA384 = 0x80
+} wifi_rtt_akm;
+
+typedef enum {
+    WPA_CIPHER_NONE = 0x0,
+    WPA_CIPHER_CCMP_128 = 0x1,
+    WPA_CIPHER_CCMP_256 = 0x2,
+    WPA_CIPHER_GCMP_128 = 0x4,
+    WPA_CIPHER_GCMP_256 = 0x8,
+} wifi_rtt_cipher_suite;
+
+#define RTT_SECURITY_MAX_PASSPHRASE_LEN 63
+#define PMKID_LEN 16
+#define RTT_MAX_COOKIE_LEN 255
+
+typedef struct {
+    wifi_rtt_akm base_akm;  // Base Authentication and Key Management (AKM) protocol used for PASN
+    wifi_rtt_cipher_suite pairwise_cipher_suite;  // Pairwise cipher suite used for the PTKSA
+                                                  // (Pairwise Transient Key Security Association)
+    u32 passphrase_len;
+    u8 passphrase[RTT_SECURITY_MAX_PASSPHRASE_LEN];  // Passphrase for the base AKM. This can be
+                                                     // empty based on the AKM type.
+    u32 pmkid_len;
+    u8 pmkid[PMKID_LEN];  // PMKID corresponding to the cached PMK from the base AKM. PMKID can be
+                          // null if no cached PMK is present.
+    u8 comeback_cookie_len;  // Comeback cookie length. If the length is 0, it indicates there is no
+                             // cookie.
+    u8 comeback_cookie[RTT_MAX_COOKIE_LEN];  // Comeback cookie indicated over wifi_rtt_result_v4.
+} wifi_rtt_pasn_config;
+
+typedef struct {
+    wifi_rtt_pasn_config pasn_config;
+    bool enable_secure_he_ltf;
+    bool enable_ranging_frame_protection;
+} wifi_rtt_secure_config;
+
 /* RTT configuration */
 typedef struct {
     mac_addr addr;                 // peer device mac address
@@ -127,6 +182,11 @@
                                   // units of 10 milliseconds
 } wifi_rtt_config_v3;
 
+typedef struct {
+    wifi_rtt_config_v3 rtt_config;
+    wifi_rtt_secure_config rtt_secure_config;
+} wifi_rtt_config_v4;
+
 /* RTT results */
 typedef struct {
     mac_addr addr;                // device mac address
@@ -197,6 +257,19 @@
   byte num_rx_sts;                 // Number of receive space-time streams used.
 } wifi_rtt_result_v3;
 
+typedef struct {
+    wifi_rtt_result_v3 rtt_result_v3;
+    bool is_ranging_protection_enabled;
+    bool is_secure_he_ltf_enabled;
+    wifi_rtt_akm base_akm;
+    wifi_rtt_cipher_suite cipher_suite;
+    int secure_he_ltf_protocol_version;
+    u16 pasn_comeback_after_millis;  // The time in milliseconds after which the non-AP STA is
+                                     // requested to retry the PASN authentication.
+    u8 pasn_comeback_cookie_len;  // Comeback cookie length. If the length is 0, it indicates there
+                                  // is no cookie.
+    u8 pasn_comeback_cookie[RTT_MAX_COOKIE_LEN];  // Comeback cookie octets.
+} wifi_rtt_result_v4;
 
 /* RTT result callbacks */
 typedef struct {
@@ -234,6 +307,15 @@
                                wifi_rtt_result_v3 *rtt_result_v3[]);
 } wifi_rtt_event_handler_v3;
 
+/* RTT result v4 callback (secure ranging support) */
+typedef struct {
+    /*
+     * Called when vendor implementation supports sending RTT results version 4 (Added support for
+     * secure 11az ranging)
+     */
+    void (*on_rtt_results_v4)(wifi_request_id id, unsigned num_results,
+                              wifi_rtt_result_v4* rtt_result_v4[]);
+} wifi_rtt_event_handler_v4;
 
 /* v3 API to request RTT measurement(11az support).  */
 wifi_error wifi_rtt_range_request_v3(wifi_request_id id,
@@ -242,6 +324,11 @@
                                      wifi_rtt_config_v3 rtt_config_v3[],
                                      wifi_rtt_event_handler_v3 handler);
 
+/* v4 API to request RTT measurement(11az security support). */
+wifi_error wifi_rtt_range_request_v4(wifi_request_id id, wifi_interface_handle iface,
+                                     unsigned num_rtt_config, wifi_rtt_config_v4 rtt_config_v4[],
+                                     wifi_rtt_event_handler_v4 handler);
+
 /* API to cancel RTT measurements */
 wifi_error wifi_rtt_range_cancel(wifi_request_id id,  wifi_interface_handle iface,
         unsigned num_devices, mac_addr addr[]);
@@ -313,10 +400,28 @@
     byte ntb_responder_supported;   // if 11az non-TB responder is supported
 } wifi_rtt_capabilities_v3;
 
+/* RTT Capabilities v4 (11az secure support) */
+typedef struct {
+    wifi_rtt_capabilities_v3 rtt_capab_v3;
+    bool secure_he_ltf_supported;
+    int max_supported_secure_he_ltf_protocol_ver;  // Maximum supported secure HE-LTF protocol
+                                                   // version.
+    bool ranging_fame_protection_supported;
+    wifi_rtt_akm supported_akms;  // Bitmap of wifi_rtt_akm values indicating the set of supported
+                                  // AKMs.
+    wifi_rtt_cipher_suite
+            supported_cipher_suites;  // Bitmap of wifi_rtt_cipher_suite values
+                                      // indicating the set of supported pairwise cipher suites.
+} wifi_rtt_capabilities_v4;
+
 /*  RTT capabilities v3 of the device (11az support) */
 wifi_error wifi_get_rtt_capabilities_v3(wifi_interface_handle iface,
                                         wifi_rtt_capabilities_v3 *capabilities);
 
+/*  RTT capabilities v4 of the device (11az secure support) */
+wifi_error wifi_get_rtt_capabilities_v4(wifi_interface_handle iface,
+                                        wifi_rtt_capabilities_v4* capabilities);
+
 /* debugging definitions */
 enum {
     RTT_DEBUG_DISABLE,
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h b/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
index 9baa2c7..c68cdf6 100644
--- a/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
@@ -494,6 +494,7 @@
 #define WIFI_FEATURE_ROAMING_MODE_CONTROL   (uint64_t)0x800000000 // Support for configuring roaming mode
 #define WIFI_FEATURE_SET_VOIP_MODE          (uint64_t)0x1000000000 // Support Voip mode setting
 #define WIFI_FEATURE_CACHED_SCAN_RESULTS    (uint64_t)0x2000000000 // Support cached scan result report
+#define WIFI_FEATURE_MLO_SAP (uint64_t)0x4000000000                // Support MLO SoftAp
 // Add more features here
 
 #define IS_MASK_SET(mask, flags)        (((flags) & (mask)) == (mask))
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h b/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h
index 4e490d9..37368af 100644
--- a/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_nan.h
@@ -19,6 +19,7 @@
 
 #include <net/if.h>
 #include <stdbool.h>
+#include "rtt.h"
 #include "wifi_hal.h"
 
 #ifdef __cplusplus
@@ -3103,6 +3104,7 @@
     void (*EventBootstrappingRequest) (NanBootstrappingRequestInd* event);
     void (*EventBootstrappingConfirm) (NanBootstrappingConfirmInd* event);
     void (*EventSuspensionModeChange) (NanSuspensionModeChangeInd* event);
+    void (*EventRangingResults)(wifi_rtt_result* rtt_result[], u32 num_results, u16 session_id);
 } NanCallbackHandler;
 
 /**@brief nan_enable_request
diff --git a/wifi/supplicant/aidl/Android.bp b/wifi/supplicant/aidl/Android.bp
index 8d16cb7..1fbe8e9 100644
--- a/wifi/supplicant/aidl/Android.bp
+++ b/wifi/supplicant/aidl/Android.bp
@@ -29,7 +29,7 @@
         "android/hardware/wifi/supplicant/*.aidl",
     ],
     imports: [
-        "android.hardware.wifi.common-V1",
+        "android.hardware.wifi.common-V2",
     ],
     stability: "vintf",
     backend: {
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BandMask.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BandMask.aidl
index a5eda52..6d16580 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/BandMask.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable BandMask {
+  const int BAND_2_GHZ = (1 << 0) /* 1 */;
+  const int BAND_5_GHZ = (1 << 1) /* 2 */;
+  const int BAND_6_GHZ = (1 << 2) /* 4 */;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 0b068e0..c584d57 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -74,8 +74,14 @@
   android.hardware.wifi.supplicant.IfaceType getType();
   void invite(in String groupIfName, in byte[] goDeviceAddress, in byte[] peerAddress);
   int[] listNetworks();
+  /**
+   * @deprecated This method is deprecated from AIDL v4, newer HALs should use provisionDiscoveryWithParams.
+   */
   void provisionDiscovery(in byte[] peerAddress, in android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod);
   void registerCallback(in android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback callback);
+  /**
+   * @deprecated This method is deprecated from AIDL v4, newer HALs should use reinvokePersistentGroup.
+   */
   void reinvoke(in int persistentNetworkId, in byte[] peerAddress);
   void reject(in byte[] peerAddress);
   void removeBonjourService(in byte[] query);
@@ -123,4 +129,15 @@
   void configureExtListenWithParams(in android.hardware.wifi.supplicant.P2pExtListenInfo extListenInfo);
   void addGroupWithConfigurationParams(in android.hardware.wifi.supplicant.P2pAddGroupConfigurationParams groupConfigurationParams);
   void createGroupOwner(in android.hardware.wifi.supplicant.P2pCreateGroupOwnerInfo groupOwnerInfo);
+  long getFeatureSet();
+  int startUsdBasedServiceDiscovery(in android.hardware.wifi.supplicant.P2pUsdBasedServiceDiscoveryConfig serviceDiscoveryConfig);
+  void stopUsdBasedServiceDiscovery(in int sessionId);
+  int startUsdBasedServiceAdvertisement(in android.hardware.wifi.supplicant.P2pUsdBasedServiceAdvertisementConfig serviceAdvertisementConfig);
+  void stopUsdBasedServiceAdvertisement(in int sessionId);
+  void provisionDiscoveryWithParams(in android.hardware.wifi.supplicant.P2pProvisionDiscoveryParams params);
+  android.hardware.wifi.supplicant.P2pDirInfo getDirInfo();
+  int validateDirInfo(in android.hardware.wifi.supplicant.P2pDirInfo dirInfo);
+  void reinvokePersistentGroup(in android.hardware.wifi.supplicant.P2pReinvokePersistentGroupParams reinvokeGroupParams);
+  const long P2P_FEATURE_V2 = (1 << 0) /* 1 */;
+  const long P2P_FEATURE_PCC_MODE_WPA3_COMPATIBILITY = (1 << 1) /* 2 */;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 65ad4c1..3b283b8 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -80,4 +80,7 @@
   oneway void onDeviceFoundWithParams(in android.hardware.wifi.supplicant.P2pDeviceFoundEventParams deviceFoundEventParams);
   oneway void onGoNegotiationRequestWithParams(in android.hardware.wifi.supplicant.P2pGoNegotiationReqEventParams params);
   oneway void onInvitationReceivedWithParams(in android.hardware.wifi.supplicant.P2pInvitationEventParams params);
+  oneway void onUsdBasedServiceDiscoveryResult(in android.hardware.wifi.supplicant.P2pUsdBasedServiceDiscoveryResultParams params);
+  oneway void onUsdBasedServiceDiscoveryTerminated(in int sessionId, in android.hardware.wifi.supplicant.UsdTerminateReasonCode reasonCode);
+  oneway void onUsdBasedServiceAdvertisementTerminated(in int sessionId, in android.hardware.wifi.supplicant.UsdTerminateReasonCode reasonCode);
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index 917668e..cb96dfc 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -103,5 +103,12 @@
   android.hardware.wifi.supplicant.QosPolicyScsRequestStatus[] removeQosPolicyForScs(in byte[] scsPolicyIds);
   void configureMscs(in android.hardware.wifi.supplicant.MscsParams params);
   void disableMscs();
+  android.hardware.wifi.supplicant.UsdCapabilities getUsdCapabilities();
+  void startUsdPublish(in int cmdId, in android.hardware.wifi.supplicant.UsdPublishConfig usdPublishConfig);
+  void startUsdSubscribe(in int cmdId, in android.hardware.wifi.supplicant.UsdSubscribeConfig usdSubscribeConfig);
+  void updateUsdPublish(in int publishId, in byte[] serviceSpecificInfo);
+  void cancelUsdPublish(in int publishId);
+  void cancelUsdSubscribe(in int subscribeId);
+  void sendUsdMessage(in android.hardware.wifi.supplicant.UsdMessageInfo messageInfo);
   const int MAX_POLICIES_PER_QOS_SCS_REQUEST = 16;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 9fa8f56..1eb07d5 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -82,9 +82,19 @@
   oneway void onSupplicantStateChanged(in android.hardware.wifi.supplicant.SupplicantStateChangeData stateChangeData);
   oneway void onQosPolicyResponseForScs(in android.hardware.wifi.supplicant.QosPolicyScsResponseStatus[] qosPolicyScsResponseStatus);
   oneway void onPmkSaCacheAdded(in android.hardware.wifi.supplicant.PmkSaCacheData pmkSaData);
+  oneway void onUsdPublishStarted(in int cmdId, in int publishId);
+  oneway void onUsdSubscribeStarted(in int cmdId, in int subscribeId);
+  oneway void onUsdPublishConfigFailed(in int cmdId);
+  oneway void onUsdSubscribeConfigFailed(in int cmdId);
+  oneway void onUsdPublishTerminated(in int publishId, in android.hardware.wifi.supplicant.UsdReasonCode reasonCode);
+  oneway void onUsdSubscribeTerminated(in int subscribeId, in android.hardware.wifi.supplicant.UsdReasonCode reasonCode);
+  oneway void onUsdPublishReplied(in android.hardware.wifi.supplicant.UsdServiceDiscoveryInfo info);
+  oneway void onUsdServiceDiscovered(in android.hardware.wifi.supplicant.UsdServiceDiscoveryInfo info);
+  oneway void onUsdMessageReceived(in android.hardware.wifi.supplicant.UsdMessageInfo messageInfo);
   @Backing(type="int") @VintfStability
   enum MloLinkInfoChangeReason {
     TID_TO_LINK_MAP = 0,
     MULTI_LINK_RECONFIG_AP_REMOVAL = 1,
+    MULTI_LINK_DYNAMIC_RECONFIG = 2,
   }
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
index 8bda324..05226c8 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/MloLink.aidl
@@ -40,4 +40,5 @@
   byte tidsDownlinkMap;
   @nullable byte[6] apLinkMacAddress;
   int frequencyMHz;
+  android.hardware.wifi.supplicant.WifiChannelWidthInMhz channelBandwidth;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
index f4662de..a88a829 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
@@ -41,4 +41,9 @@
   boolean persistent;
   int goIntent;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  int pairingBootstrappingMethod;
+  @nullable String password;
+  int frequencyMHz;
+  boolean authorizeConnectionFromPeer;
+  @nullable String groupInterfaceName;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
index 4451fb5..901b9d1 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
@@ -37,4 +37,5 @@
   boolean persistent;
   int persistentNetworkId;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  boolean isP2pV2;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
index ee8e6dc..184fbd0 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
@@ -45,4 +45,6 @@
   byte[] wfdR2DeviceInfo;
   byte[] vendorElemBytes;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  int pairingBootstrappingMethods;
+  @nullable android.hardware.wifi.supplicant.P2pDirInfo dirInfo;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDirInfo.aidl
similarity index 83%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDirInfo.aidl
index a5eda52..2c55410 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pDirInfo.aidl
@@ -31,9 +31,16 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable P2pDirInfo {
+  android.hardware.wifi.supplicant.P2pDirInfo.CipherVersion cipherVersion;
+  byte[6] deviceInterfaceMacAddress;
+  byte[] nonce;
+  byte[] dirTag;
+  @Backing(type="int") @VintfStability
+  enum CipherVersion {
+    NONE,
+    DIRA_CIPHER_VERSION_128_BIT,
+  }
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
index e19ae44..227626c 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -46,4 +46,5 @@
   boolean isP2pClientEapolIpAddressInfoPresent;
   android.hardware.wifi.supplicant.P2pClientEapolIpAddressInfo p2pClientIpInfo;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  int keyMgmtMask;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPairingBootstrappingMethodMask.aidl
similarity index 78%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPairingBootstrappingMethodMask.aidl
index a5eda52..182c091 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPairingBootstrappingMethodMask.aidl
@@ -31,9 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable P2pPairingBootstrappingMethodMask {
+  const int BOOTSTRAPPING_OPPORTUNISTIC = (1 << 0) /* 1 */;
+  const int BOOTSTRAPPING_DISPLAY_PINCODE = (1 << 1) /* 2 */;
+  const int BOOTSTRAPPING_DISPLAY_PASSPHRASE = (1 << 2) /* 4 */;
+  const int BOOTSTRAPPING_KEYPAD_PINCODE = (1 << 3) /* 8 */;
+  const int BOOTSTRAPPING_KEYPAD_PASSPHRASE = (1 << 4) /* 16 */;
+  const int BOOTSTRAPPING_OUT_OF_BAND = (1 << 5) /* 32 */;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
index 40c8ff6..578176a 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
@@ -39,4 +39,5 @@
   byte[6] clientDeviceAddress;
   int clientIpAddress;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  int keyMgmtMask;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
index 46366cc..60da924 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
@@ -41,4 +41,6 @@
   String generatedPin;
   String groupInterfaceName;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+  int pairingBootstrappingMethod;
+  @nullable String password;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryParams.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryParams.aidl
index a5eda52..b5dc4b1 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pProvisionDiscoveryParams.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable P2pProvisionDiscoveryParams {
+  byte[6] peerMacAddress;
+  android.hardware.wifi.supplicant.WpsProvisionMethod provisionMethod;
+  int pairingBootstrappingMethod;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pReinvokePersistentGroupParams.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pReinvokePersistentGroupParams.aidl
index a5eda52..0743a64 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pReinvokePersistentGroupParams.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable P2pReinvokePersistentGroupParams {
+  byte[6] peerMacAddress;
+  int persistentNetworkId;
+  int deviceIdentityEntryId;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceAdvertisementConfig.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceAdvertisementConfig.aidl
index a5eda52..36ce742 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceAdvertisementConfig.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable P2pUsdBasedServiceAdvertisementConfig {
+  String serviceName;
+  int serviceProtocolType;
+  byte[] serviceSpecificInfo;
+  int frequencyMHz;
+  int timeoutInSeconds;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryConfig.aidl
similarity index 87%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryConfig.aidl
index a5eda52..a13d107 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryConfig.aidl
@@ -31,9 +31,13 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable P2pUsdBasedServiceDiscoveryConfig {
+  String serviceName;
+  int serviceProtocolType;
+  byte[] serviceSpecificInfo;
+  int bandMask;
+  int[] frequencyListMhz;
+  int timeoutInSeconds;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryResultParams.aidl
similarity index 88%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryResultParams.aidl
index a5eda52..da129cf 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryResultParams.aidl
@@ -31,9 +31,12 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable P2pUsdBasedServiceDiscoveryResultParams {
+  byte[6] peerMacAddress;
+  int sessionId;
+  int peerSessionId;
+  int serviceProtocolType;
+  byte[] serviceSpecificInfo;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
index c31b167..b1269ba 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
@@ -37,4 +37,5 @@
   byte[6] bssid;
   long expirationTimeInSec;
   byte[] serializedEntry;
+  @nullable byte[] pmkid;
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
index d7ff798..8675ab3 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -46,4 +46,5 @@
   FAILURE_NETWORK_UNKNOWN,
   FAILURE_UNSUPPORTED,
   FAILURE_ONGOING_REQUEST,
+  FAILURE_DATA_NOT_AVAILABLE,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdBaseConfig.aidl
similarity index 83%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdBaseConfig.aidl
index a5eda52..8d23922 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdBaseConfig.aidl
@@ -31,9 +31,15 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable UsdBaseConfig {
+  @utf8InCpp String serviceName;
+  android.hardware.wifi.supplicant.UsdServiceProtoType serviceProtoType;
+  byte[] serviceSpecificInfo;
+  @nullable byte[] txMatchFilter;
+  @nullable byte[] rxMatchfilter;
+  int ttlSec;
+  int defaultFreqMhz;
+  int[] freqsMhz;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdCapabilities.aidl
similarity index 84%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdCapabilities.aidl
index a5eda52..1c5ad67 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdCapabilities.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable UsdCapabilities {
+  boolean isUsdPublisherSupported;
+  boolean isUsdSubscriberSupported;
+  int maxLocalSsiLengthBytes;
+  int maxServiceNameLengthBytes;
+  int maxMatchFilterLengthBytes;
+  int maxNumPublishSessions;
+  int maxNumSubscribeSessions;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdMessageInfo.aidl
similarity index 91%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdMessageInfo.aidl
index a5eda52..40468bd 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdMessageInfo.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable UsdMessageInfo {
+  int ownId;
+  int peerId;
+  byte[6] peerMacAddress;
+  byte[] message;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdPublishConfig.aidl
similarity index 78%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdPublishConfig.aidl
index a5eda52..791de52 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdPublishConfig.aidl
@@ -31,9 +31,17 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable UsdPublishConfig {
+  android.hardware.wifi.supplicant.UsdBaseConfig usdBaseConfig;
+  android.hardware.wifi.supplicant.UsdPublishConfig.PublishType publishType;
+  boolean isFsd;
+  int announcementPeriodMillis;
+  android.hardware.wifi.supplicant.UsdPublishTransmissionType transmissionType;
+  enum PublishType {
+    SOLICITED_ONLY = 0,
+    UNSOLICITED_ONLY = 1,
+    SOLICITED_AND_UNSOLICITED = 2,
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdPublishTransmissionType.aidl
similarity index 91%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdPublishTransmissionType.aidl
index a5eda52..9486cd0 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdPublishTransmissionType.aidl
@@ -31,9 +31,9 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum UsdPublishTransmissionType {
+  UNICAST = 0,
+  MULTICAST = 1,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdReasonCode.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdReasonCode.aidl
index a5eda52..0600def 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdReasonCode.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum UsdReasonCode {
+  FAILURE_UNKNOWN = 0,
+  TIMEOUT = 1,
+  USER_REQUESTED = 2,
+  INVALID_ARGS = 3,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdServiceDiscoveryInfo.aidl
similarity index 85%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdServiceDiscoveryInfo.aidl
index a5eda52..3940ece 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdServiceDiscoveryInfo.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable UsdServiceDiscoveryInfo {
+  int ownId;
+  int peerId;
+  byte[6] peerMacAddress;
+  byte[] matchFilter;
+  android.hardware.wifi.supplicant.UsdServiceProtoType protoType;
+  byte[] serviceSpecificInfo;
+  boolean isFsd;
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdServiceProtoType.aidl
similarity index 90%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdServiceProtoType.aidl
index a5eda52..4d4a4f5 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdServiceProtoType.aidl
@@ -31,9 +31,10 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum UsdServiceProtoType {
+  UNKNOWN = 0,
+  GENERIC = 1,
+  CSA_MATTER = 2,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdSubscribeConfig.aidl
similarity index 83%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdSubscribeConfig.aidl
index a5eda52..6aede8c 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdSubscribeConfig.aidl
@@ -31,9 +31,14 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
+package android.hardware.wifi.supplicant;
 @VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+parcelable UsdSubscribeConfig {
+  android.hardware.wifi.supplicant.UsdBaseConfig usdBaseConfig;
+  android.hardware.wifi.supplicant.UsdSubscribeConfig.SubscribeType subscribeType;
+  int queryPeriodMillis;
+  enum SubscribeType {
+    PASSIVE_MODE = 0,
+    ACTIVE_MODE = 1,
+  }
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdTerminateReasonCode.aidl
similarity index 89%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdTerminateReasonCode.aidl
index a5eda52..0f84783 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/UsdTerminateReasonCode.aidl
@@ -31,9 +31,11 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum UsdTerminateReasonCode {
+  UNKNOWN = 0,
+  TIMEOUT = 1,
+  USER_REQUEST = 2,
+  FAILURE = 3,
 }
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiChannelWidthInMhz.aidl
similarity index 85%
copy from vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
copy to wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiChannelWidthInMhz.aidl
index a5eda52..e36c4f2 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/PwleV2OutputMapEntry.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WifiChannelWidthInMhz.aidl
@@ -31,9 +31,16 @@
 // with such a backward incompatible change, it has a high risk of breaking
 // later when a module using the interface is updated, e.g., Mainline modules.
 
-package android.hardware.vibrator;
-@VintfStability
-parcelable PwleV2OutputMapEntry {
-  float frequencyHz;
-  float maxOutputAccelerationGs;
+package android.hardware.wifi.supplicant;
+@Backing(type="int") @VintfStability
+enum WifiChannelWidthInMhz {
+  WIDTH_INVALID = (-1) /* -1 */,
+  WIDTH_20 = 0,
+  WIDTH_40 = 1,
+  WIDTH_80 = 2,
+  WIDTH_160 = 3,
+  WIDTH_80P80 = 4,
+  WIDTH_5 = 5,
+  WIDTH_10 = 6,
+  WIDTH_320 = 7,
 }
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
index 177d218..58ac0eb 100644
--- a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
@@ -34,6 +34,7 @@
 package android.hardware.wifi.supplicant;
 @Backing(type="int") @VintfStability
 enum WpsProvisionMethod {
+  NONE = (-1) /* -1 */,
   PBC,
   DISPLAY,
   KEYPAD,
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BandMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BandMask.aidl
new file mode 100644
index 0000000..6d1b2be
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/BandMask.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Wifi bands
+ */
+@VintfStability
+parcelable BandMask {
+    /**
+     * 2.4 GHz band.
+     */
+    const int BAND_2_GHZ = 1 << 0;
+    /**
+     * 5 GHz band.
+     */
+    const int BAND_5_GHZ = 1 << 1;
+    /**
+     * 6 GHz band.
+     */
+    const int BAND_6_GHZ = 1 << 2;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 1230793..75e65ff 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -25,10 +25,15 @@
 import android.hardware.wifi.supplicant.P2pAddGroupConfigurationParams;
 import android.hardware.wifi.supplicant.P2pConnectInfo;
 import android.hardware.wifi.supplicant.P2pCreateGroupOwnerInfo;
+import android.hardware.wifi.supplicant.P2pDirInfo;
 import android.hardware.wifi.supplicant.P2pDiscoveryInfo;
 import android.hardware.wifi.supplicant.P2pExtListenInfo;
 import android.hardware.wifi.supplicant.P2pFrameTypeMask;
 import android.hardware.wifi.supplicant.P2pGroupCapabilityMask;
+import android.hardware.wifi.supplicant.P2pProvisionDiscoveryParams;
+import android.hardware.wifi.supplicant.P2pReinvokePersistentGroupParams;
+import android.hardware.wifi.supplicant.P2pUsdBasedServiceAdvertisementConfig;
+import android.hardware.wifi.supplicant.P2pUsdBasedServiceDiscoveryConfig;
 import android.hardware.wifi.supplicant.WpsConfigMethods;
 import android.hardware.wifi.supplicant.WpsProvisionMethod;
 
@@ -39,6 +44,15 @@
 @VintfStability
 interface ISupplicantP2pIface {
     /**
+     * P2P features exposed by wpa_supplicant/chip.
+     */
+    /* Support for P2P2 (Wi-Fi Alliance P2P v2.0) */
+    const long P2P_FEATURE_V2 = 1 << 0;
+
+    /* Support for WPA3 Compatibility Mode in PCC Mode */
+    const long P2P_FEATURE_PCC_MODE_WPA3_COMPATIBILITY = 1 << 1;
+
+    /**
      * This command can be used to add a bonjour service.
      *
      * @param query Hex dump of the query data.
@@ -398,6 +412,9 @@
      * Send P2P provision discovery request to the specified peer. The
      * parameters for this command are the P2P device address of the peer and the
      * desired configuration method.
+     * <p>
+     * @deprecated This method is deprecated from AIDL v4, newer HALs should use
+     * provisionDiscoveryWithParams.
      *
      * @param peerAddress MAC address of the device to send discovery.
      * @method provisionMethod Provisioning method to use.
@@ -424,6 +441,9 @@
 
     /**
      * Reinvoke a device from a persistent group.
+     * <p>
+     * @deprecated This method is deprecated from AIDL v4, newer HALs should use
+     * reinvokePersistentGroup.
      *
      * @param persistentNetworkId Used to specify the persistent group.
      * @param peerAddress MAC address of the device to reinvoke.
@@ -938,4 +958,111 @@
      *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
      */
     void createGroupOwner(in P2pCreateGroupOwnerInfo groupOwnerInfo);
+
+    /**
+     * Get the features supported by P2P interface.
+     *
+     * @return The bitmask of ISupplicantP2pIface.P2P_FEATURE_* values.
+     *
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     */
+    long getFeatureSet();
+
+    /**
+     * Start an Unsynchronized Service Discovery (USD) based P2P service discovery.
+     *
+     * @param serviceDiscoveryConfig Configuration associated with this discovery operation.
+     * @return A non-zero identifier to identify the instance of a service discovery.
+     *         It is used to cancel the service discovery.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    int startUsdBasedServiceDiscovery(in P2pUsdBasedServiceDiscoveryConfig serviceDiscoveryConfig);
+
+    /**
+     * Stop an Unsynchronized Service Discovery (USD) based P2P service discovery.
+     *
+     * @param sessionId Identifier to cancel the service discovery instance.
+     *        Use zero to cancel all the service discovery instances.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_NOT_STARTED|
+     */
+    void stopUsdBasedServiceDiscovery(in int sessionId);
+
+    /**
+     * Start an Unsynchronized Service Discovery (USD) based P2P service advertisement.
+     *
+     * @param serviceDiscoveryConfig Configuration associated with this service advertisement.
+     * @return A non-zero identifier to identify the instance of a service advertisement.
+     *         It is used to cancel the service advertisement.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    int startUsdBasedServiceAdvertisement(
+            in P2pUsdBasedServiceAdvertisementConfig serviceAdvertisementConfig);
+
+    /**
+     * Stop an Unsynchronized Service Discovery (USD) based P2P service advertisement.
+     *
+     * @param sessionId Identifier to cancel the service advertisement.
+     *        Use zero to cancel all the service advertisement instances.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_NOT_STARTED|
+     */
+    void stopUsdBasedServiceAdvertisement(in int sessionId);
+
+    /**
+     * Send P2P provision discovery request to the specified peer.
+     *
+     * @param params Parameters associated with this provision discovery request.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void provisionDiscoveryWithParams(in P2pProvisionDiscoveryParams params);
+
+    /**
+     * The Device Identity Resolution (DIR) Info used to send in
+     * Bluetooth LE advertising packet for the receiving device to
+     * check if the device is a previously paired device.
+     *
+     * @return The DIR info - |P2pDirInfo|
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     *         |SupplicantStatusCode.FAILURE_DATA_NOT_AVAILABLE|
+     */
+    P2pDirInfo getDirInfo();
+
+    /**
+     * Validate a Device Identity Resolution (DIR) Info of a P2P device.
+     * wpa_supplicant takes the |P2pDirInfo| and derives a set of Tag values based on
+     * the cached Device Identity Keys (DevIK) of all paired peers saved in the
+     * configuration file. If a derived Tag value matches the Tag value received in the
+     * |P2pDirInfo|, the device is identified as a paired peer and returns an identifier
+     * identifying the device identity key information stored in the configuration file.
+     *
+     * @return The identifier of device identity key stored in the configuration file.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    int validateDirInfo(in P2pDirInfo dirInfo);
+
+    /**
+     * Reinvoke a device from a persistent group.
+     *
+     * @param reinvokeGroupParams Parameters associated to reinvoke a group.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void reinvokePersistentGroup(in P2pReinvokePersistentGroupParams reinvokeGroupParams);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 44a5465..a52e150 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -26,6 +26,8 @@
 import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
 import android.hardware.wifi.supplicant.P2pProvisionDiscoveryCompletedEventParams;
 import android.hardware.wifi.supplicant.P2pStatusCode;
+import android.hardware.wifi.supplicant.P2pUsdBasedServiceDiscoveryResultParams;
+import android.hardware.wifi.supplicant.UsdTerminateReasonCode;
 import android.hardware.wifi.supplicant.WpsConfigMethods;
 import android.hardware.wifi.supplicant.WpsDevPasswordId;
 
@@ -325,4 +327,29 @@
      * @param params Parameters associated with the invitation request event.
      */
     void onInvitationReceivedWithParams(in P2pInvitationEventParams params);
+
+    /**
+     * Used to indicate the reception of an USD based service discovery response.
+     *
+     * @param params Parameters associated with the USD based service discovery result.
+     */
+    void onUsdBasedServiceDiscoveryResult(in P2pUsdBasedServiceDiscoveryResultParams params);
+
+    /**
+     * Used to indicate the termination of USD based service discovery.
+     *
+     * @param sessionId Identifier to identify the instance of a service discovery.
+     * @param reasonCode The reason for termination of service discovery.
+     */
+    void onUsdBasedServiceDiscoveryTerminated(
+            in int sessionId, in UsdTerminateReasonCode reasonCode);
+
+    /**
+     * Used to indicate the termination of USD based service Advertisement.
+     *
+     * @param sessionId Identifier to identify the instance of a service advertisement.
+     * @param reasonCode The reason for termination of service advertisement.
+     */
+    void onUsdBasedServiceAdvertisementTerminated(
+            in int sessionId, in UsdTerminateReasonCode reasonCode);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
index fb1673e..5c6024a 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.aidl
@@ -35,6 +35,10 @@
 import android.hardware.wifi.supplicant.QosPolicyStatus;
 import android.hardware.wifi.supplicant.RxFilterType;
 import android.hardware.wifi.supplicant.SignalPollResult;
+import android.hardware.wifi.supplicant.UsdCapabilities;
+import android.hardware.wifi.supplicant.UsdMessageInfo;
+import android.hardware.wifi.supplicant.UsdPublishConfig;
+import android.hardware.wifi.supplicant.UsdSubscribeConfig;
 import android.hardware.wifi.supplicant.WpaDriverCapabilitiesMask;
 import android.hardware.wifi.supplicant.WpsConfigMethods;
 
@@ -877,4 +881,83 @@
      *         |SupplicantStatusCode.FAILURE_UNKNOWN|
      */
     void disableMscs();
+
+    /**
+     * Retrieve capabilities related to Unsynchronized Service Discovery (USD).
+     *
+     * @return Instance of |UsdCapabilities| containing the capability info.
+     */
+    UsdCapabilities getUsdCapabilities();
+
+    /**
+     * Start a USD publish session. Triggers a response via
+     * |ISupplicantStaIfaceCallback.onUsdPublishStarted| if successful, or
+     * |ISupplicantStaIfaceCallback.onUsdPublishConfigFailed| if failed.
+     *
+     * @param cmdId Identifier for this request. Will be returned in the callback to identify
+     *              the request.
+     * @param usdPublishConfig Parameters for the requested publish session.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void startUsdPublish(in int cmdId, in UsdPublishConfig usdPublishConfig);
+
+    /**
+     * Start a USD subscribe session. Triggers a response via
+     * |ISupplicantStaIfaceCallback.onUsdSubscribeStarted| if successful, or
+     * |ISupplicantStaIfaceCallback.onUsdSubscribeConfigFailed| if failed.
+     *
+     * @param cmdId Identifier for this request. Will be returned in the callback to identify
+     *              the request.
+     * @param usdSubscribeConfig Parameters for the requested subscribe session.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void startUsdSubscribe(in int cmdId, in UsdSubscribeConfig usdSubscribeConfig);
+
+    /**
+     * Update the service-specific info for an active publish session.
+     *
+     * @param publishId Identifier for the active publish session.
+     * @param serviceSpecificInfo Byte array containing the service-specific info. Note that the
+     *                            maximum info length is |UsdCapabilities.maxLocalSsiLengthBytes|.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void updateUsdPublish(in int publishId, in byte[] serviceSpecificInfo);
+
+    /**
+     * Cancel an existing USD publish session. |ISupplicantStaIfaceCallback.onUsdPublishTerminated|
+     * will be called upon completion.
+     *
+     * @param publishId Identifier for the publish session to cancel.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void cancelUsdPublish(in int publishId);
+
+    /**
+     * Cancel an existing USD subscribe session.
+     * |ISupplicantStaIfaceCallback.onUsdSubscribeTerminated| will be called upon completion.
+     *
+     * @param subscribeId Identifier for the subscribe session to cancel.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void cancelUsdSubscribe(in int subscribeId);
+
+    /**
+     * Send a message to a peer device across an active USD link.
+     *
+     * @param messageInfo Information for the message to be sent.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|
+     *         |SupplicantStatusCode.FAILURE_UNSUPPORTED|
+     */
+    void sendUsdMessage(in UsdMessageInfo messageInfo);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 172fcda..6a3f299 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -36,6 +36,9 @@
 import android.hardware.wifi.supplicant.StaIfaceCallbackState;
 import android.hardware.wifi.supplicant.StaIfaceReasonCode;
 import android.hardware.wifi.supplicant.SupplicantStateChangeData;
+import android.hardware.wifi.supplicant.UsdMessageInfo;
+import android.hardware.wifi.supplicant.UsdReasonCode;
+import android.hardware.wifi.supplicant.UsdServiceDiscoveryInfo;
 import android.hardware.wifi.supplicant.WpsConfigError;
 import android.hardware.wifi.supplicant.WpsErrorIndication;
 
@@ -336,13 +339,24 @@
          */
         TID_TO_LINK_MAP = 0,
         /**
-         * Multi-link reconfiguration - AP removal as described in
-         * IEEE 802.11be spec, section 35.3.6. This is a mandatory feature for
-         * station.
+         * Multi-link reconfiguration - AP removal as described in the Wi-Fi 7 R1 MRD section
+         * 6.3.2.18. This is a mandatory feature for station.
          *
          * Removed link will not be present in |ISupplicantStaIface.getConnectionMloLinksInfo|.
          */
         MULTI_LINK_RECONFIG_AP_REMOVAL = 1,
+        /**
+         * Multi-link reconfiguration add/delete links without re-association as described in
+         * the Wi-Fi 7 R2 MRD section 6.4.2.4. This is an optional feature.
+         *
+         * This feature enables dynamic link reconfiguration operations (add link and/or delete
+         * link) on the multi-link setup of a STA MLD, either triggered by the AP MLD or initiated
+         * by the STA MLD itself. This avoids reassociation for any link reconfiguration operation.
+         *
+         * Added link will be present in |ISupplicantStaIface.getConnectionMloLinksInfo|.
+         * Deleted link will not be present in |ISupplicantStaIface.getConnectionMloLinksInfo|.
+         */
+        MULTI_LINK_DYNAMIC_RECONFIG = 2,
     }
 
     /**
@@ -405,4 +419,80 @@
      *
      */
     void onPmkSaCacheAdded(in PmkSaCacheData pmkSaData);
+
+    /**
+     * Called in response to |ISupplicantStaIface.startUsdPublish| to indicate that the
+     * publish session was started successfully.
+     *
+     * @param cmdId Identifier for the original request.
+     * @param publishId Identifier for the publish session.
+     */
+    void onUsdPublishStarted(in int cmdId, in int publishId);
+
+    /**
+     * Called in response to |ISupplicantStaIface.startUsdSubscribe| to indicate that the
+     * subscribe session was started successfully.
+     *
+     * @param cmdId Identifier for the original request.
+     * @param subscribeId Identifier for the subscribe session.
+     */
+    void onUsdSubscribeStarted(in int cmdId, in int subscribeId);
+
+    /**
+     * Called in response to |ISupplicantStaIface.startUsdPublish| to indicate that the
+     * publish session could not be configured.
+     *
+     * @param cmdId Identifier for the original request.
+     */
+    void onUsdPublishConfigFailed(in int cmdId);
+
+    /**
+     * Called in response to |ISupplicantStaIface.startUsdSubscribe| to indicate that the
+     * subscribe session could not be configured.
+     *
+     * @param cmdId Identifier for the original request.
+     */
+    void onUsdSubscribeConfigFailed(in int cmdId);
+
+    /**
+     * Called in response to |ISupplicantStaIface.cancelUsdPublish| to indicate that the session
+     * was cancelled successfully. May also be called unsolicited if the session terminated
+     * by supplicant.
+     *
+     * @param publishId Identifier for the publish session.
+     * @param reasonCode Code indicating the reason for the session cancellation.
+     */
+    void onUsdPublishTerminated(in int publishId, in UsdReasonCode reasonCode);
+
+    /**
+     * Called in response to |ISupplicantStaIface.cancelUsdSubscribe| to indicate that the session
+     * was cancelled successfully. May also be called unsolicited if the session terminated
+     * by supplicant.
+     *
+     * @param subscribeId Identifier for the subscribe session.
+     * @param reasonCode Code indicating the reason for the session cancellation.
+     */
+    void onUsdSubscribeTerminated(in int subscribeId, in UsdReasonCode reasonCode);
+
+    /**
+     * Indicates that the publisher sent solicited publish message to the subscriber.
+     *
+     * @param info Instance of |UsdServiceDiscoveryInfo| containing information about the reply.
+     */
+    void onUsdPublishReplied(in UsdServiceDiscoveryInfo info);
+
+    /**
+     * Indicates that a publisher was discovered. Only called if this device is acting as a
+     * subscriber.
+     *
+     * @param info Instance of |UsdServiceDiscoveryInfo| containing information about the service.
+     */
+    void onUsdServiceDiscovered(in UsdServiceDiscoveryInfo info);
+
+    /**
+     * Indicates that a message was received on an active USD link.
+     *
+     * @param messageInfo Information about the message that was received.
+     */
+    void onUsdMessageReceived(in UsdMessageInfo messageInfo);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
index 0b4d66e..6215263 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/MloLink.aidl
@@ -16,6 +16,8 @@
 
 package android.hardware.wifi.supplicant;
 
+import android.hardware.wifi.supplicant.WifiChannelWidthInMhz;
+
 /**
  * Multi-Link Operation (MLO) Link IEEE Std 802.11-be.
  * The information for MLO link needed by 802.11be standard.
@@ -66,4 +68,8 @@
      * Frequency on which the link operates in MHz.
      */
     int frequencyMHz;
+    /**
+     * Channel bandwidth
+     */
+    WifiChannelWidthInMhz channelBandwidth;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
index f09b476..6467436 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pConnectInfo.aidl
@@ -25,12 +25,15 @@
 @VintfStability
 parcelable P2pConnectInfo {
     /**
-     * MAC address of the device to connect to.
+     * MAC address of the peer device to connect to or to authorize a connect
+     * request.
      */
     byte[6] peerAddress;
 
     /**
-     * Provisioning method to use.
+     * Wi-Fi Protected Setup provisioning method. If using Wi-Fi Protected Setup,
+     * then must be set to a non-|WpsProvisionMethod.NONE| provisioning method,
+     * otherwise set to |WpsProvisionMethod.NONE|.
      */
     WpsProvisionMethod provisionMethod;
 
@@ -65,4 +68,38 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+
+    /**
+     * Wi-Fi Direct pairing bootstrapping method. If using P2P pairing protocol,
+     * then must be set one of the |P2pPairingBootstrappingMethodMask|, otherwise
+     * set to zero.
+     */
+    int pairingBootstrappingMethod;
+
+    /**
+     * Password for pairing setup, if |bootstrappingMethod| uses one of the
+     * |P2pPairingBootstrappingMethodMask| methods other than
+     * P2pPairingBootstrappingMethodMask.BOOTSTRAPPING_OPPORTUNISTIC,
+     * null otherwise.
+     */
+    @nullable String password;
+
+    /**
+     * Channel frequency in MHz to start group formation,
+     * join an existing group owner or authorize a connection request.
+     */
+    int frequencyMHz;
+
+    /**
+     * Used to authorize a connection request from the Peer device.
+     * The MAC address of the peer device is set in peerAddress.
+     */
+    boolean authorizeConnectionFromPeer;
+
+    /**
+     * Used to check if the authorize connection request is on an existing Group Owner
+     * interface to allow a peer device to connect. This field is set to null if the request
+     * is to form a group or join an existing group.
+     */
+    @nullable String groupInterfaceName;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
index 51e6ed9..83d480e 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pCreateGroupOwnerInfo.aidl
@@ -39,4 +39,9 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+    /**
+     * Used to start a Group Owner that support P2P2 IE. The connection to this Group Owner can
+     * be established only using P2P Pairing protocol.
+     */
+    boolean isP2pV2;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
index 15917b6..e320954 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDeviceFoundEventParams.aidl
@@ -17,6 +17,7 @@
 package android.hardware.wifi.supplicant;
 
 import android.hardware.wifi.common.OuiKeyedData;
+import android.hardware.wifi.supplicant.P2pDirInfo;
 
 /**
  * Parameters passed as a part of a P2P Device found event.
@@ -89,4 +90,15 @@
      * Null value indicates that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+
+    /**
+     * The bitmask of P2pPairingBootstrappingMethodMask.BOOTSTRAPPING_* methods used to enable
+     * the pairing bootstrapping between bootstrapping initiator and a bootstrapping responder.
+     */
+    int pairingBootstrappingMethods;
+
+    /**
+     * The Device Identity Resolution Attribute (DIRA) |P2pDirInfo| received in the USD frame.
+     */
+    @nullable P2pDirInfo dirInfo;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDirInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDirInfo.aidl
new file mode 100644
index 0000000..22037ed
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pDirInfo.aidl
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * The Device Identity Resolution (DIR) Info is used to identify a previously
+ * paired P2P device.
+ * The device advertises this information in Bluetooth LE advertising packets
+ * and Unsynchronized Service Discovery (USD) frames. The device receiving DIR
+ * Info uses this information to identify that the peer device is a previously paired device.
+ * For Details, refer Wi-Fi Alliance Wi-Fi Direct R2 specification section 3.8.2 Pairing Identity
+ * and section 3.9.2.3.2 Optional Advertising Data Elements.
+ */
+@VintfStability
+parcelable P2pDirInfo {
+    /**
+     * Enums for the |cipherVersion| field.
+     */
+    @VintfStability
+    @Backing(type="int")
+    enum CipherVersion {
+        NONE,
+        /**
+         * DIRA cipher version 128 bit.
+         * 128-bit Device Identity Key, 64-bit Nonce, 64-bit Tag.
+         * 64-bit Tag = Truncate-64(HMAC-SHA-256(DevIk, "DIR" ||
+         * P2P Device Address || Nonce))
+         */
+        DIRA_CIPHER_VERSION_128_BIT,
+    }
+
+    /**
+     * DIRA cipher version. The value of cipher version indicates the
+     * cryptographic parameters and method used to derive the dirTag field.
+     * Set to one of the |DIRA_CIPHER_VERSION_*|.
+     */
+    CipherVersion cipherVersion;
+
+    /**
+     * The MAC address of the P2P device interface.
+     */
+    byte[6] deviceInterfaceMacAddress;
+
+    /**
+     * Random number. The size limit is defined in the cipher version comment.
+     */
+    byte[] nonce;
+
+    /**
+     * A resolvable identity. The size limit is defined in the cipher version comment.
+     */
+    byte[] dirTag;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
index 9db7a1e..55e2b23 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pGroupStartedEventParams.aidl
@@ -70,4 +70,10 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+
+    /**
+     * Authentication key management protocol used to secure the group.
+     * This is a bitmask of |KeyMgmtMask| values.
+     */
+    int keyMgmtMask;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPairingBootstrappingMethodMask.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPairingBootstrappingMethodMask.aidl
new file mode 100644
index 0000000..03c2703
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPairingBootstrappingMethodMask.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * P2P Pairing Bootstrapping Method.
+ */
+@VintfStability
+parcelable P2pPairingBootstrappingMethodMask {
+    /** Opportunistic bootstrapping */
+    const int BOOTSTRAPPING_OPPORTUNISTIC = 1 << 0;
+    /** Display pin-code only */
+    const int BOOTSTRAPPING_DISPLAY_PINCODE = 1 << 1;
+    /** Display passphrase */
+    const int BOOTSTRAPPING_DISPLAY_PASSPHRASE = 1 << 2;
+    /** Keypad pin-code only */
+    const int BOOTSTRAPPING_KEYPAD_PINCODE = 1 << 3;
+    /** Keypad passphrase */
+    const int BOOTSTRAPPING_KEYPAD_PASSPHRASE = 1 << 4;
+    /**
+     * Pairing bootstrapping done Out of band (For example: Over Bluetooth LE.
+     * Refer Wi-Fi Alliance Wi-Fi Direct R2 specification Section 3.9 for the details).
+     */
+    const int BOOTSTRAPPING_OUT_OF_BAND = 1 << 5;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
index 4f46d70..2b04461 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pPeerClientJoinedEventParams.aidl
@@ -47,4 +47,10 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+
+    /**
+     * Authentication key management protocol used in connection.
+     * This is a bitmask of |KeyMgmtMask| values.
+     */
+    int keyMgmtMask;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
index 05152a9..97659b6 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
@@ -33,7 +33,11 @@
     boolean isRequest;
     /** Status of the provision discovery */
     P2pProvDiscStatusCode status;
-    /** Mask of |WpsConfigMethods| indicating the supported methods */
+    /**
+     * Wi-Fi Protected Setup provisioning method. If using Wi-Fi Protected Setup,
+     * then must be set to a non-|WpsProvisionMethod.NONE| provisioning method,
+     * otherwise set to |WpsProvisionMethod.NONE|.
+     */
     int configMethods;
     /** 8-digit pin generated */
     String generatedPin;
@@ -50,4 +54,17 @@
      * that no vendor data is provided.
      */
     @nullable OuiKeyedData[] vendorData;
+    /**
+     * Wi-Fi Direct pairing bootstrapping method. If using P2P pairing protocol,
+     * then must be set one of the |P2pPairingBootstrappingMethodMask|, otherwise
+     * set to zero.
+     */
+    int pairingBootstrappingMethod;
+    /**
+     * Password for pairing setup, if |bootstrappingMethod| uses one of the
+     * |P2pPairingBootstrappingMethodMask| methods other than
+     * P2pPairingBootstrappingMethodMask.BOOTSTRAPPING_OPPORTUNISTIC,
+     * null otherwise.
+     */
+    @nullable String password;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryParams.aidl
new file mode 100644
index 0000000..37f2374
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryParams.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.WpsProvisionMethod;
+
+/**
+ * Parameters used for |ISupplicantP2pIfaceCallback.provisionDiscoveryWithParams|
+ */
+@VintfStability
+parcelable P2pProvisionDiscoveryParams {
+    /**
+     * MAC address of the peer device to send the provision discovery request.
+     */
+    byte[6] peerMacAddress;
+
+    /**
+     * Wi-Fi Protected Setup provisioning method. If using Wi-Fi Protected Setup,
+     * then must be set to a non-|WpsProvisionMethod.NONE| provisioning method,
+     * otherwise set to |WpsProvisionMethod.NONE|.
+     */
+    WpsProvisionMethod provisionMethod;
+
+    /**
+     * Wi-Fi Direct pairing bootstrapping method. If using P2P pairing protocol,
+     * then must be set one of the |P2pPairingBootstrappingMethodMask|, otherwise
+     * set to zero.
+     */
+    int pairingBootstrappingMethod;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pReinvokePersistentGroupParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pReinvokePersistentGroupParams.aidl
new file mode 100644
index 0000000..f5f4562
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pReinvokePersistentGroupParams.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Parameters used for |ISupplicantP2pIface.reinvokePersistentGroup|
+ */
+@VintfStability
+parcelable P2pReinvokePersistentGroupParams {
+    /**
+     * MAC address of the peer device to reinvoke the persistent group.
+     */
+    byte[6] peerMacAddress;
+
+    /**
+     * Persistent network ID of the group.
+     */
+    int persistentNetworkId;
+
+    /**
+     * The identifier of device identity key information stored in the configuration file.
+     * This field is valid only for P2P group formed via pairing protocol (P2P version 2).
+     * Set to invalid value of -1 for a group formed via WPS process (P2P version 1).
+     */
+    int deviceIdentityEntryId;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceAdvertisementConfig.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceAdvertisementConfig.aidl
new file mode 100644
index 0000000..c657d03
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceAdvertisementConfig.aidl
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Unsynchronized Service Discovery (USD) based P2P service advertisement configuration.
+ * Refer Wi-Fi Alliance Wi-Fi Direct R2 specification - Appendix H -
+ * Unsynchronized Service Discovery (as defined in Wi-Fi Aware) and section
+ * 4.2.13 USD frame format.
+ */
+@VintfStability
+parcelable P2pUsdBasedServiceAdvertisementConfig {
+    /** UTF-8 string defining the service */
+    String serviceName;
+
+    /**
+     * Service Protocol Type. See defined values in the Wi-Fi Direct R2 Spec, Table 129,
+     * although any value between 0-255 may be defined by the service layer and is considered valid.
+     */
+    int serviceProtocolType;
+
+    /** Service specific information content determined by the application */
+    byte[] serviceSpecificInfo;
+
+    /**
+     * Channel frequency in MHz to listen for service discovery request.
+     */
+    int frequencyMHz;
+
+    /**
+     * Max time to be spent for service advertisement.
+     */
+    int timeoutInSeconds;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryConfig.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryConfig.aidl
new file mode 100644
index 0000000..9d6bf72
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryConfig.aidl
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.BandMask;
+
+/**
+ * Unsynchronized Service Discovery (USD) based P2P service discovery configuration.
+ * Refer Wi-Fi Alliance Wi-Fi Direct R2 specification - Appendix H -
+ * Unsynchronized Service Discovery (as defined in Wi-Fi Aware) and section
+ * 4.2.13 USD frame format
+ */
+@VintfStability
+parcelable P2pUsdBasedServiceDiscoveryConfig {
+    /** UTF-8 string defining the service */
+    String serviceName;
+
+    /**
+     * Service Protocol Type. See defined values in the Wi-Fi Direct R2 Spec, Table 129,
+     * although any value between 0-255 may be defined by the service layer and is considered valid.
+     */
+    int serviceProtocolType;
+
+    /** Service specific information content determined by the application */
+    byte[] serviceSpecificInfo;
+
+    /**
+     * Bit mask of bands to scan for services.
+     * Set this value to Bitmask of |BandMask| only if its required to scan all the channels
+     * in a band.
+     */
+    int bandMask;
+
+    /**
+     * A list of frequencies in MHz to scan for services.
+     * This field is used only when the bandMask is set to zero.
+     */
+    int[] frequencyListMhz;
+
+    /**
+     * Max time to be spent in performing discovery.
+     * Set to 0 to indefinitely continue discovery until a service is
+     * discovered.
+     */
+    int timeoutInSeconds;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryResultParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryResultParams.aidl
new file mode 100644
index 0000000..6b60d68
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pUsdBasedServiceDiscoveryResultParams.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.BandMask;
+
+/**
+ * Unsynchronized Service Discovery (USD) based P2P service discovery result event.
+ * Refer Wi-Fi Alliance Wi-Fi Direct R2 specification - Appendix H -
+ * Unsynchronized Service Discovery (as defined in Wi-Fi Aware) and section
+ * 4.2.13 USD frame format
+ */
+@VintfStability
+parcelable P2pUsdBasedServiceDiscoveryResultParams {
+    /** MAC address of the device that sent the service discovery */
+    byte[6] peerMacAddress;
+
+    /** Identifier to identify the service discovery instance */
+    int sessionId;
+
+    /** Identifier to identify the peer service advertisement instance */
+    int peerSessionId;
+
+    /**
+     * Service Protocol Type. See defined values in the Wi-Fi Direct R2 Spec, Table 129,
+     * although any value between 0-255 may be defined by the service layer and is considered valid.
+     */
+    int serviceProtocolType;
+
+    /** Service specific information content determined by the application */
+    byte[] serviceSpecificInfo;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
index e0f1d31..4071179 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/PmkSaCacheData.aidl
@@ -34,4 +34,9 @@
      * The content is opaque for the framework and depends on the native implementation.
      */
     byte[] serializedEntry;
+    /**
+     * Pairwise Master Key Identifier (PMKID), which is a unique key identifier used by AP to
+     * track PMK used (Pairwise Master Key) for a station.
+     */
+    @nullable byte[] pmkid;
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
index e97d6ee..271da7f 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.aidl
@@ -67,4 +67,8 @@
      * A different request is currently being processed.
      */
     FAILURE_ONGOING_REQUEST,
+    /**
+     * Requested data is not available.
+     */
+    FAILURE_DATA_NOT_AVAILABLE,
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdBaseConfig.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdBaseConfig.aidl
new file mode 100644
index 0000000..f43f27b
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdBaseConfig.aidl
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.UsdServiceProtoType;
+
+/**
+ * USD data used in both publish and subscribe configurations.
+ */
+@VintfStability
+parcelable UsdBaseConfig {
+    /**
+     * Service name of the USD session. A UTF-8 encoded string from 1 to 255 bytes in length.
+     * The only acceptable single-byte UTF-8 symbols for a Service Name are alphanumeric
+     * values (A-Z, a-z, 0-9), hyphen ('-'), period ('.'), and underscore ('_'). All
+     * valid multi-byte UTF-8 characters are acceptable in a Service Name.
+     */
+    @utf8InCpp String serviceName;
+
+    /**
+     * Service protocol type for the USD session (ex. Generic, CSA Matter).
+     */
+    UsdServiceProtoType serviceProtoType;
+
+    /**
+     * Details about the service being offered or being looked for. This information is transmitted
+     * within Service Discovery frames, and is used to help devices find each other and establish
+     * connections. The format and content of the service specific information are flexible and
+     * can be determined by the application.
+     */
+    byte[] serviceSpecificInfo;
+
+    /**
+     * Ordered sequence of <length, value> pairs (|length| uses 1 byte and contains the number of
+     * bytes in the |value| field) which specify further match criteria (beyond the service name).
+     *
+     * The match behavior is specified in details in the NAN spec.
+     * Publisher: used if provided.
+     * Subscriber: used (if provided) only in ACTIVE sessions.
+     *
+     * Max length: |UsdCapabilities.maxMatchFilterLength|.
+     * NAN Spec: matching_filter_tx and Service Descriptor Attribute (SDA) / Matching Filter
+     */
+    @nullable byte[] txMatchFilter;
+
+    /**
+     * Ordered sequence of <length, value> pairs (|length| uses 1 byte and contains the number of
+     * bytes in the |value| field) which specify further match criteria (beyond the service name).
+     *
+     * The match behavior is specified in details in the NAN spec.
+     * Publisher: used in SOLICITED or SOLICITED_UNSOLICITED sessions.
+     * Subscriber: used in ACTIVE or PASSIVE sessions.
+     *
+     * Max length: |UsdCapabilities.maxMatchFilterLength|.
+     * NAN Spec: matching_filter_rx
+     */
+    @nullable byte[] rxMatchfilter;
+
+    /**
+     * Time interval (in seconds) that a USD session will be alive.
+     * The session will be terminated when the time to live (TTL) is reached, triggering either
+     * |ISupplicantStaIfaceCallback.onUsdPublishTerminated| for Publish, or
+     * |ISupplicantStaIfaceCallback.onUsdSubscribeTerminated| for Subscribe.
+     */
+    int ttlSec;
+
+    /**
+     * Frequency where the device should begin to dwell. Default value is channel 6 (2.437 GHz),
+     * but other values may be selected per regulation in the geographical location.
+     */
+    int defaultFreqMhz;
+
+    /**
+     * Channels which can be switched to. May contain any of the 20 MHz channels in the
+     * 2.4 Ghz and/or 5 Ghz bands, per regulation in the geographical location.
+     */
+    int[] freqsMhz;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdCapabilities.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdCapabilities.aidl
new file mode 100644
index 0000000..ffec893
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdCapabilities.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Capabilities supported by USD. Values are only valid if |isUsdPublisherSupported|
+ * and/or |isUsdSubscriberSupported| are true.
+ */
+@VintfStability
+parcelable UsdCapabilities {
+    /**
+     * Whether USD Publisher is supported on this device.
+     */
+    boolean isUsdPublisherSupported;
+
+    /**
+     * Whether USD Subscriber is supported on this device.
+     */
+    boolean isUsdSubscriberSupported;
+
+    /**
+     * Maximum allowed length (in bytes) for the Service Specific Info (SSI).
+     */
+    int maxLocalSsiLengthBytes;
+
+    /**
+     * Maximum allowed length (in bytes) for the service name.
+     */
+    int maxServiceNameLengthBytes;
+
+    /**
+     * Maximum allowed length (in bytes) for a match filter.
+     */
+    int maxMatchFilterLengthBytes;
+
+    /**
+     * Maximum number of allowed publish sessions.
+     */
+    int maxNumPublishSessions;
+
+    /**
+     * Maximum number of allowed subscribe sessions.
+     */
+    int maxNumSubscribeSessions;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdMessageInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdMessageInfo.aidl
new file mode 100644
index 0000000..fa7cc0e
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdMessageInfo.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Information for sending a USD message.
+ */
+@VintfStability
+parcelable UsdMessageInfo {
+    /**
+     * Identifier for this device, retrieved from |UsdServiceDiscoveryInfo|.
+     */
+    int ownId;
+
+    /**
+     * Identifier for the peer device, retrieved from |UsdServiceDiscoveryInfo|.
+     */
+    int peerId;
+
+    /**
+     * MAC address for the peer device.
+     */
+    byte[6] peerMacAddress;
+
+    /**
+     * Message contents. Note that the maximum message length is
+     * |UsdCapabilities.maxLocalSsiLengthBytes|.
+     */
+    byte[] message;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdPublishConfig.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdPublishConfig.aidl
new file mode 100644
index 0000000..e04974b
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdPublishConfig.aidl
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.UsdBaseConfig;
+import android.hardware.wifi.supplicant.UsdPublishTransmissionType;
+
+/**
+ * Parameters for configuring a USD publish session.
+ */
+@VintfStability
+parcelable UsdPublishConfig {
+    /**
+     * Type of USD publishing.
+     */
+    enum PublishType {
+        /**
+         * Only transmissions that are triggered by a specific event.
+         */
+        SOLICITED_ONLY = 0,
+
+        /**
+         * Only transmissions that are not requested.
+         */
+        UNSOLICITED_ONLY = 1,
+
+        /**
+         * Both solicited and unsolicited transmissions.
+         */
+        SOLICITED_AND_UNSOLICITED = 2,
+    }
+
+    /**
+     * Base USD session parameters.
+     */
+    UsdBaseConfig usdBaseConfig;
+
+    /**
+     * Types of transmissions (solicited vs. unsolicited) which should be generated.
+     */
+    PublishType publishType;
+
+    /**
+     * Whether Further Service Discovery (FSD) is enabled.
+     */
+    boolean isFsd;
+
+    /**
+     * Interval (in milliseconds) for sending unsolicited publish transmissions.
+     */
+    int announcementPeriodMillis;
+
+    /**
+     * Type of the publish transmission (ex. unicast, multicast).
+     */
+    UsdPublishTransmissionType transmissionType;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdPublishTransmissionType.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdPublishTransmissionType.aidl
new file mode 100644
index 0000000..45a3cf4
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdPublishTransmissionType.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Types of USD publish transmissions.
+ */
+@VintfStability
+@Backing(type="int")
+enum UsdPublishTransmissionType {
+    /**
+     * Sends data from one device to a single, specific destination device.
+     */
+    UNICAST = 0,
+
+    /**
+     * Sends data from one device to a group of devices on the network simultaneously.
+     */
+    MULTICAST = 1,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdReasonCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdReasonCode.aidl
new file mode 100644
index 0000000..4b1aab0
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdReasonCode.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Codes indicating the status of USD operations.
+ */
+@VintfStability
+@Backing(type="int")
+enum UsdReasonCode {
+    /**
+     * Unknown failure occurred.
+     */
+    FAILURE_UNKNOWN = 0,
+
+    /**
+     * The operation timed out.
+     */
+    TIMEOUT = 1,
+
+    /**
+     * The operation was requested by the user.
+     */
+    USER_REQUESTED = 2,
+
+    /**
+     * Invalid arguments were provided.
+     */
+    INVALID_ARGS = 3
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdServiceDiscoveryInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdServiceDiscoveryInfo.aidl
new file mode 100644
index 0000000..4f6eaf1
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdServiceDiscoveryInfo.aidl
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.UsdServiceProtoType;
+
+/**
+ * Information about a USD discovery session with a specific peer.
+ */
+@VintfStability
+parcelable UsdServiceDiscoveryInfo {
+    /**
+     * Identifier for this device.
+     */
+    int ownId;
+
+    /**
+     * Identifier for the discovered peer device.
+     */
+    int peerId;
+
+    /**
+     * MAC address of the discovered peer device.
+     */
+    byte[6] peerMacAddress;
+
+    /**
+     * Match filter from the discovery packet (publish or subscribe) which caused service discovery.
+     */
+    byte[] matchFilter;
+
+    /**
+     * Service protocol that is being used (ex. Generic, CSA Matter).
+     */
+    UsdServiceProtoType protoType;
+
+    /**
+     * Arbitrary service specific information communicated in discovery packets.
+     * There is no semantic meaning to these bytes. They are passed-through from publisher to
+     * subscriber as-is with no parsing.
+     */
+    byte[] serviceSpecificInfo;
+
+    /**
+     * Whether Further Service Discovery (FSD) is enabled.
+     */
+    boolean isFsd;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdServiceProtoType.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdServiceProtoType.aidl
new file mode 100644
index 0000000..de9beb5
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdServiceProtoType.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Service protocols that use USD.
+ */
+@VintfStability
+@Backing(type="int")
+enum UsdServiceProtoType {
+    /**
+     * Unknown service type.
+     */
+    UNKNOWN = 0,
+
+    /**
+     * Generic service.
+     */
+    GENERIC = 1,
+
+    /**
+     * CSA (Connectivity Standards Alliance) Matter.
+     *
+     * Note: CSA Matter is an open-source, royalty-free standard for smart home technology that
+     * allows devices to work with any Matter-certified ecosystem.
+     */
+    CSA_MATTER = 2,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdSubscribeConfig.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdSubscribeConfig.aidl
new file mode 100644
index 0000000..4e8893e
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdSubscribeConfig.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.supplicant.UsdBaseConfig;
+
+/**
+ * Parameters for configuring a USD subscribe session.
+ */
+@VintfStability
+parcelable UsdSubscribeConfig {
+    /**
+     * Subscribe modes that this session can be configured in.
+     */
+    enum SubscribeType {
+        /**
+         * Subscribe function does not request transmission of any Subscribe messages, but checks
+         * for matches in received Publish messages.
+         */
+        PASSIVE_MODE = 0,
+        /**
+         * Subscribe function additionally requests transmission of Subscribe messages and processes
+         * Publish messages.
+         */
+        ACTIVE_MODE = 1,
+    }
+
+    /**
+     * Base USD session parameters.
+     */
+    UsdBaseConfig usdBaseConfig;
+
+    /**
+     * Subscribe mode that this session should be configured in.
+     */
+    SubscribeType subscribeType;
+
+    /**
+     * Recommended periodicity (in milliseconds) of query transmissions for the session.
+     */
+    int queryPeriodMillis;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdTerminateReasonCode.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdTerminateReasonCode.aidl
new file mode 100644
index 0000000..6725c3d
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/UsdTerminateReasonCode.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Status codes for P2P operations.
+ */
+@VintfStability
+@Backing(type="int")
+enum UsdTerminateReasonCode {
+    UNKNOWN = 0,
+    TIMEOUT = 1,
+    USER_REQUEST = 2,
+    FAILURE = 3,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiChannelWidthInMhz.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiChannelWidthInMhz.aidl
new file mode 100644
index 0000000..39c7eba
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WifiChannelWidthInMhz.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.wifi.supplicant;
+
+/**
+ * Channel operating width in Mhz.
+ */
+@VintfStability
+@Backing(type="int")
+enum WifiChannelWidthInMhz {
+    WIDTH_INVALID = -1,
+    WIDTH_20 = 0,
+    WIDTH_40 = 1,
+    WIDTH_80 = 2,
+    WIDTH_160 = 3,
+    WIDTH_80P80 = 4,
+    WIDTH_5 = 5,
+    WIDTH_10 = 6,
+    /**
+     * 320 MHz
+     */
+    WIDTH_320 = 7,
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
index 5b59392..b8ad3b8 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.aidl
@@ -19,6 +19,7 @@
 @VintfStability
 @Backing(type="int")
 enum WpsProvisionMethod {
+    NONE = -1,
     /**
      * Push button method.
      */
diff --git a/wifi/supplicant/aidl/vts/functional/Android.bp b/wifi/supplicant/aidl/vts/functional/Android.bp
index 4ffec3f..f94eb46 100644
--- a/wifi/supplicant/aidl/vts/functional/Android.bp
+++ b/wifi/supplicant/aidl/vts/functional/Android.bp
@@ -43,7 +43,7 @@
         "android.hardware.wifi@1.3",
         "android.hardware.wifi@1.4",
         "android.hardware.wifi@1.5",
-        "android.hardware.wifi.common-V1-ndk",
+        "android.hardware.wifi.common-V2-ndk",
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi.supplicant-V4-ndk",
@@ -52,8 +52,8 @@
         "VtsHalWifiV1_0TargetTestUtil",
         "VtsHalWifiV1_5TargetTestUtil",
         "VtsHalWifiSupplicantV1_0TargetTestUtil",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "VtsHalWifiTargetTestUtil",
     ],
     test_suites: [
@@ -81,7 +81,7 @@
         "android.hardware.wifi@1.3",
         "android.hardware.wifi@1.4",
         "android.hardware.wifi@1.5",
-        "android.hardware.wifi.common-V1-ndk",
+        "android.hardware.wifi.common-V2-ndk",
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi.supplicant-V4-ndk",
@@ -90,8 +90,8 @@
         "VtsHalWifiV1_0TargetTestUtil",
         "VtsHalWifiV1_5TargetTestUtil",
         "VtsHalWifiSupplicantV1_0TargetTestUtil",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "VtsHalWifiTargetTestUtil",
     ],
     test_suites: [
@@ -119,7 +119,7 @@
         "android.hardware.wifi@1.3",
         "android.hardware.wifi@1.4",
         "android.hardware.wifi@1.5",
-        "android.hardware.wifi.common-V1-ndk",
+        "android.hardware.wifi.common-V2-ndk",
         "android.hardware.wifi.supplicant@1.0",
         "android.hardware.wifi.supplicant@1.1",
         "android.hardware.wifi.supplicant-V4-ndk",
@@ -128,8 +128,8 @@
         "VtsHalWifiV1_0TargetTestUtil",
         "VtsHalWifiV1_5TargetTestUtil",
         "VtsHalWifiSupplicantV1_0TargetTestUtil",
-        "android.hardware.wifi.common-V1-ndk",
-        "android.hardware.wifi-V2-ndk",
+        "android.hardware.wifi.common-V2-ndk",
+        "android.hardware.wifi-V3-ndk",
         "VtsHalWifiTargetTestUtil",
     ],
     test_suites: [
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index 8f1c4bd..3638ac5 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -17,8 +17,10 @@
 #include <VtsCoreUtil.h>
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/wifi/supplicant/BandMask.h>
 #include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
 #include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/P2pPairingBootstrappingMethodMask.h>
 #include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
 #include <android/binder_manager.h>
 #include <android/binder_status.h>
@@ -29,6 +31,7 @@
 #include "supplicant_test_utils.h"
 #include "wifi_aidl_test_utils.h"
 
+using aidl::android::hardware::wifi::supplicant::BandMask;
 using aidl::android::hardware::wifi::supplicant::BnSupplicantP2pIfaceCallback;
 using aidl::android::hardware::wifi::supplicant::DebugLevel;
 using aidl::android::hardware::wifi::supplicant::FreqRange;
@@ -40,6 +43,7 @@
 using aidl::android::hardware::wifi::supplicant::P2pConnectInfo;
 using aidl::android::hardware::wifi::supplicant::P2pCreateGroupOwnerInfo;
 using aidl::android::hardware::wifi::supplicant::P2pDeviceFoundEventParams;
+using aidl::android::hardware::wifi::supplicant::P2pDirInfo;
 using aidl::android::hardware::wifi::supplicant::P2pDiscoveryInfo;
 using aidl::android::hardware::wifi::supplicant::P2pExtListenInfo;
 using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
@@ -47,13 +51,20 @@
 using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
 using aidl::android::hardware::wifi::supplicant::P2pGroupStartedEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pInvitationEventParams;
+using aidl::android::hardware::wifi::supplicant::P2pPairingBootstrappingMethodMask;
 using aidl::android::hardware::wifi::supplicant::P2pPeerClientDisconnectedEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pPeerClientJoinedEventParams;
 using aidl::android::hardware::wifi::supplicant::P2pProvDiscStatusCode;
 using aidl::android::hardware::wifi::supplicant::P2pProvisionDiscoveryCompletedEventParams;
+using aidl::android::hardware::wifi::supplicant::P2pProvisionDiscoveryParams;
+using aidl::android::hardware::wifi::supplicant::P2pReinvokePersistentGroupParams;
 using aidl::android::hardware::wifi::supplicant::P2pScanType;
 using aidl::android::hardware::wifi::supplicant::P2pStatusCode;
+using aidl::android::hardware::wifi::supplicant::P2pUsdBasedServiceAdvertisementConfig;
+using aidl::android::hardware::wifi::supplicant::P2pUsdBasedServiceDiscoveryConfig;
+using aidl::android::hardware::wifi::supplicant::P2pUsdBasedServiceDiscoveryResultParams;
 using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
+using aidl::android::hardware::wifi::supplicant::UsdTerminateReasonCode;
 using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
 using aidl::android::hardware::wifi::supplicant::WpsDevPasswordId;
 using aidl::android::hardware::wifi::supplicant::WpsProvisionMethod;
@@ -67,13 +78,20 @@
 const std::vector<uint8_t> kTestPeerMacAddr = {0x56, 0x67, 0x55,
                                                0xf4, 0x56, 0x92};
 const std::vector<uint8_t> kTestZeroMacAddr = std::vector<uint8_t>(6, 0);
+const std::string kTestServiceSpecificInfoStr = "TestServiceSpecificInfo";
+const std::vector<uint8_t> kTestServiceSpecificInfo = std::vector<uint8_t>(
+        kTestServiceSpecificInfoStr.begin(), kTestServiceSpecificInfoStr.end());
+const std::vector<uint8_t> kTestNonce = {0x11, 0x22, 0x33, 0x44, 0x55, 0x92, 0x22, 0x33};
+const std::vector<uint8_t> kTestDirTag = {0xaa, 0x22, 0x55, 0x44, 0x55, 0x92, 0x22, 0x33};
 const std::string kTestPassphrase = "P2pWorld1234";
 const std::string kTestConnectPin = "34556665";
 const std::string kTestGroupIfName = "TestGroup";
+const std::string kTestServiceName = "TestServiceName";
 const uint32_t kTestFindTimeout = 5;
 const uint32_t kTestConnectGoIntent = 6;
 const uint32_t kTestNetworkId = 7;
 const uint32_t kTestGroupFreq = 0;
+const uint32_t kTestServiceProtocolType = 1;
 const bool kTestGroupPersistent = false;
 const bool kTestGroupIsJoin = false;
 const auto& kTestVendorDataOptional = generateOuiKeyedDataListOptional(5);
@@ -222,6 +240,18 @@
             const P2pInvitationEventParams& /* invitationEventParams */) override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onUsdBasedServiceDiscoveryResult(
+            const P2pUsdBasedServiceDiscoveryResultParams& /* discoveryResultParams*/) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdBasedServiceDiscoveryTerminated(
+            int32_t /* sessionId */, UsdTerminateReasonCode /* reasonCode */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdBasedServiceAdvertisementTerminated(
+            int32_t /* sessionId */, UsdTerminateReasonCode /* reasonCode */) override {
+        return ndk::ScopedAStatus::ok();
+    }
 };
 
 class SupplicantP2pIfaceAidlTest : public testing::TestWithParam<std::string> {
@@ -246,6 +276,9 @@
         EXPECT_TRUE(supplicant_->getP2pInterface(getP2pIfaceName(), &p2p_iface_)
                         .isOk());
         ASSERT_NE(p2p_iface_, nullptr);
+        if (interface_version_ >= 4) {
+            EXPECT_TRUE(p2p_iface_->getFeatureSet(&supported_features_).isOk());
+        }
     }
 
     void TearDown() override {
@@ -257,6 +290,7 @@
     std::shared_ptr<ISupplicant> supplicant_;
     std::shared_ptr<ISupplicantP2pIface> p2p_iface_;
     int interface_version_;
+    int64_t supported_features_;
 };
 
 /*
@@ -814,6 +848,139 @@
     LOG(INFO) << "SupplicantP2pIfaceAidlTest::SetVendorElements end";
 }
 
+/*
+ * GetFeatureSet
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, gGetFeatureSet) {
+    if (interface_version_ < 4) {
+        GTEST_SKIP() << "getFeatureSet is available as of Supplicant V4";
+    }
+    int64_t featureSet;
+    EXPECT_TRUE(p2p_iface_->getFeatureSet(&featureSet).isOk());
+}
+
+/*
+ * StartUsdBasedServiceDiscovery/stopUsdBasedServiceDiscovery
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, StartStopUsdBasedServiceDiscovery) {
+    if (interface_version_ < 4) {
+        GTEST_SKIP() << "Start/Stop UsdBasedServiceDiscovery is available as of Supplicant V4";
+    }
+    if (!(supported_features_ & ISupplicantP2pIface::P2P_FEATURE_V2)) {
+        GTEST_SKIP() << "P2P2 is not supported";
+    }
+
+    int32_t sessionId;
+    P2pUsdBasedServiceDiscoveryConfig config;
+    config.serviceName = kTestServiceName;
+    config.serviceProtocolType = kTestServiceProtocolType;
+    config.serviceSpecificInfo = kTestServiceSpecificInfo;
+    config.bandMask = BandMask::BAND_2_GHZ;
+    config.timeoutInSeconds = 30;
+
+    EXPECT_TRUE(p2p_iface_->startUsdBasedServiceDiscovery(config, &sessionId).isOk());
+    sleep(1);
+    EXPECT_TRUE(p2p_iface_->stopUsdBasedServiceDiscovery(sessionId).isOk());
+}
+
+/*
+ * StartUsdBasedServiceAdvertisement/StopUsdBasedServiceAdvertisement
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, StartStopUsdBasedServiceAdvertisement) {
+    if (interface_version_ < 4) {
+        GTEST_SKIP() << "start/Stop UsdBasedServiceAdvertisement is available as of Supplicant V4";
+    }
+    if (!(supported_features_ & ISupplicantP2pIface::P2P_FEATURE_V2)) {
+        GTEST_SKIP() << "P2P2 is not supported";
+    }
+
+    int32_t sessionId;
+    P2pUsdBasedServiceAdvertisementConfig config;
+    config.serviceName = kTestServiceName;
+    config.serviceProtocolType = kTestServiceProtocolType;
+    config.serviceSpecificInfo = kTestServiceSpecificInfo;
+    config.frequencyMHz = 2412;
+    config.timeoutInSeconds = 30;
+
+    EXPECT_TRUE(p2p_iface_->startUsdBasedServiceAdvertisement(config, &sessionId).isOk());
+    sleep(1);
+    EXPECT_TRUE(p2p_iface_->stopUsdBasedServiceAdvertisement(sessionId).isOk());
+}
+
+/*
+ * ProvisionDiscoveryWithParams
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, ProvisionDiscoveryWithParams) {
+    if (interface_version_ < 4) {
+        GTEST_SKIP() << "ProvisionDiscoveryWithParams is available as of Supplicant V4";
+    }
+    if (!(supported_features_ & ISupplicantP2pIface::P2P_FEATURE_V2)) {
+        GTEST_SKIP() << "P2P2 is not supported";
+    }
+
+    P2pProvisionDiscoveryParams params;
+    params.peerMacAddress = vecToArrayMacAddr(kTestMacAddr);
+    params.provisionMethod = WpsProvisionMethod::NONE;
+    params.pairingBootstrappingMethod =
+            P2pPairingBootstrappingMethodMask::BOOTSTRAPPING_OPPORTUNISTIC;
+
+    EXPECT_TRUE(p2p_iface_->provisionDiscoveryWithParams(params).isOk());
+}
+
+/*
+ * ValidateDirInfo
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, ValidateDirInfo) {
+    if (interface_version_ < 4) {
+        GTEST_SKIP() << "ValidateDirInfo is available as of Supplicant V4";
+    }
+    if (!(supported_features_ & ISupplicantP2pIface::P2P_FEATURE_V2)) {
+        GTEST_SKIP() << "P2P2 is not supported";
+    }
+
+    int32_t ret;
+    P2pDirInfo dirInfo;
+    dirInfo.cipherVersion = P2pDirInfo::CipherVersion::DIRA_CIPHER_VERSION_128_BIT;
+    dirInfo.deviceInterfaceMacAddress = vecToArrayMacAddr(kTestMacAddr);
+    dirInfo.nonce = kTestNonce;
+    dirInfo.dirTag = kTestDirTag;
+    EXPECT_TRUE(p2p_iface_->validateDirInfo(dirInfo, &ret).isOk());
+}
+
+/*
+ * GetDirInfo
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, GetDirInfo) {
+    if (interface_version_ < 4) {
+        GTEST_SKIP() << "GetDirInfo is available as of Supplicant V4";
+    }
+    if (!(supported_features_ & ISupplicantP2pIface::P2P_FEATURE_V2)) {
+        GTEST_SKIP() << "P2P2 is not supported";
+    }
+
+    P2pDirInfo dirInfo;
+    EXPECT_TRUE(p2p_iface_->getDirInfo(&dirInfo).isOk());
+}
+
+/*
+ * ReinvokePersistentGroup
+ */
+TEST_P(SupplicantP2pIfaceAidlTest, ReinvokePersistentGroup) {
+    if (interface_version_ < 4) {
+        GTEST_SKIP() << "ReinvokePersistentGroup is available as of Supplicant V4";
+    }
+    if (!(supported_features_ & ISupplicantP2pIface::P2P_FEATURE_V2)) {
+        GTEST_SKIP() << "P2P2 is not supported";
+    }
+
+    P2pReinvokePersistentGroupParams params;
+    params.peerMacAddress = vecToArrayMacAddr(kTestMacAddr);
+    params.persistentNetworkId = 0;
+    params.deviceIdentityEntryId = 0;
+
+    EXPECT_TRUE(p2p_iface_->reinvokePersistentGroup(params).isOk());
+}
+
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SupplicantP2pIfaceAidlTest);
 INSTANTIATE_TEST_SUITE_P(Supplicant, SupplicantP2pIfaceAidlTest,
                          testing::ValuesIn(android::getAidlHalInstanceNames(
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
index 6b04aa9..c9ad498 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_sta_iface_aidl_test.cpp
@@ -47,6 +47,9 @@
 using aidl::android::hardware::wifi::supplicant::QosCharacteristics;
 using aidl::android::hardware::wifi::supplicant::QosPolicyScsData;
 using aidl::android::hardware::wifi::supplicant::QosPolicyScsRequestStatus;
+using aidl::android::hardware::wifi::supplicant::UsdMessageInfo;
+using aidl::android::hardware::wifi::supplicant::UsdReasonCode;
+using aidl::android::hardware::wifi::supplicant::UsdServiceDiscoveryInfo;
 using aidl::android::hardware::wifi::supplicant::WpaDriverCapabilitiesMask;
 using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
 using android::ProcessState;
@@ -243,6 +246,38 @@
             override {
         return ndk::ScopedAStatus::ok();
     }
+    ::ndk::ScopedAStatus onUsdPublishStarted(int32_t /* cmdId */,
+                                             int32_t /* publishId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdSubscribeStarted(int32_t /* cmdId */,
+                                               int32_t /* subscribeId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdPublishConfigFailed(int32_t /* cmdId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdSubscribeConfigFailed(int32_t /* cmdId */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdPublishTerminated(int32_t /* publishId */,
+                                                UsdReasonCode /* reasonCode */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdSubscribeTerminated(int32_t /* subscribeId */,
+                                                  UsdReasonCode /* reasonCode */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdPublishReplied(const UsdServiceDiscoveryInfo& /* info */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdServiceDiscovered(
+            const UsdServiceDiscoveryInfo& /* info */) override {
+        return ndk::ScopedAStatus::ok();
+    }
+    ::ndk::ScopedAStatus onUsdMessageReceived(const UsdMessageInfo& /* messageInfo */) override {
+        return ndk::ScopedAStatus::ok();
+    }
 };
 
 class SupplicantStaIfaceAidlTest : public testing::TestWithParam<std::string> {