Merge "camera: Add boolean to HalStream for stream specific HAL buffer manager" into main
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 25246d8..92cafbd 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -11,6 +11,9 @@
     },
     {
       "name": "VtsHalTvInputV1_0TargetTest"
+    },
+    {
+      "name": "CtsStrictJavaPackagesTestCases"
     }
   ],
   "auto-presubmit": [
diff --git a/audio/aidl/TEST_MAPPING b/audio/aidl/TEST_MAPPING
index 81c99f7..2b6207e 100644
--- a/audio/aidl/TEST_MAPPING
+++ b/audio/aidl/TEST_MAPPING
@@ -51,5 +51,10 @@
     {
       "name": "VtsHalNSTargetTest"
     }
+  ],
+  "postsubmit": [
+    {
+      "name": "VtsHalSpatializerTargetTest"
+    }
   ]
 }
diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl
index 2d4d283..3c5f7f6 100644
--- a/audio/aidl/android/hardware/audio/core/IModule.aidl
+++ b/audio/aidl/android/hardware/audio/core/IModule.aidl
@@ -928,7 +928,10 @@
      * using 'connectExternalDevice' method. 'disconnectExternalDevice' method will be called
      * soon after this method with the same 'portId'.
      *
-     * @param portId The ID of the audio port that is about to disconnect
+     * Note: This method is called after the external device is disconnected. The system does
+     * not try to predict the disconnection event.
+     *
+     * @param portId The ID of the audio port corresponding to the disconnected device
      * @throws EX_ILLEGAL_ARGUMENT In the following cases:
      *                             - If the port can not be found by the ID.
      *                             - If this is not a connected device port.
diff --git a/audio/aidl/android/hardware/audio/effect/Spatializer.aidl b/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
index 6ebe0d5..71e3ffe 100644
--- a/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
+++ b/audio/aidl/android/hardware/audio/effect/Spatializer.aidl
@@ -67,7 +67,8 @@
     Spatialization.Mode spatializationMode;
 
     /**
-     * Head tracking sensor ID.
+     * Identifies the head tracking sensor using its unique sensor ID.
+     * The value corresponds to android.hardware.sensors.SensorInfo.sensorHandle.
      */
     int headTrackingSensorId;
 
diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp
index 7cd0545..7e06c2c 100644
--- a/audio/aidl/default/Android.bp
+++ b/audio/aidl/default/Android.bp
@@ -204,6 +204,7 @@
     vendor: true,
     shared_libs: [
         "libaudioaidlcommon",
+        "libaudioutils",
         "libbase",
         "libbinder_ndk",
         "libcutils",
diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp
index baaa55f..2a8e58f 100644
--- a/audio/aidl/default/Configuration.cpp
+++ b/audio/aidl/default/Configuration.cpp
@@ -32,7 +32,6 @@
 using aidl::android::media::audio::common::AudioFormatDescription;
 using aidl::android::media::audio::common::AudioFormatType;
 using aidl::android::media::audio::common::AudioGainConfig;
-using aidl::android::media::audio::common::AudioInputFlags;
 using aidl::android::media::audio::common::AudioIoFlags;
 using aidl::android::media::audio::common::AudioOutputFlags;
 using aidl::android::media::audio::common::AudioPort;
@@ -322,25 +321,20 @@
 //
 // Mix ports:
 //  * "r_submix output", maximum 10 opened streams, maximum 10 active streams
-//    - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
+//    - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
 //  * "r_submix input", maximum 10 opened streams, maximum 10 active streams
-//    - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
-//  * "r_submix output direct", DIRECT|IEC958_NONAUDIO, 1 max open, 1 max active
-//    - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
-//  * "r_submix input direct", DIRECT, 1 max open, 1 max active
-//    - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000, 192000
-
+//    - profile PCM 16-bit; STEREO; 8000, 11025, 16000, 32000, 44100, 48000
 //
 // Routes:
-//  "r_submix output", "r_submix output direct" -> "Remote Submix Out"
-//  "Remote Submix In" -> "r_submix input", "r_submix input direct"
+//  "r_submix output" -> "Remote Submix Out"
+//  "Remote Submix In" -> "r_submix input"
 //
 std::unique_ptr<Configuration> getRSubmixConfiguration() {
     static const Configuration configuration = []() {
         Configuration c;
         const std::vector<AudioProfile> remoteSubmixPcmAudioProfiles{
                 createProfile(PcmType::INT_16_BIT, {AudioChannelLayout::LAYOUT_STEREO},
-                              {8000, 11025, 16000, 32000, 44100, 48000, 192000})};
+                              {8000, 11025, 16000, 32000, 44100, 48000})};
 
         // Device ports
 
@@ -365,41 +359,13 @@
         rsubmixOutMix.profiles = remoteSubmixPcmAudioProfiles;
         c.ports.push_back(rsubmixOutMix);
 
-        // Adding a DIRECT flag to rsubmixInMix breaks the mixer paths, so we need separate
-        // non direct and direct paths. It is added because for IEC61937 encapsulated over PCM, we
-        // need the DIRECT and IEC958_NONAUDIO flags as AudioFlinger adds them.
-        AudioPort rsubmixOutDirectMix =
-                createPort(c.nextPortId++, "r_submix output direct",
-                                makeBitPositionFlagMask({
-                                        AudioOutputFlags::DIRECT,
-                                        AudioOutputFlags::IEC958_NONAUDIO}),
-                                false /* isInput */,
-                                createPortMixExt(1 /* maxOpenStreamCount */,
-                                                 1 /* maxActiveStreamCount */));
-        rsubmixOutDirectMix.profiles = remoteSubmixPcmAudioProfiles;
-        c.ports.push_back(rsubmixOutDirectMix);
-
         AudioPort rsubmixInMix =
                 createPort(c.nextPortId++, "r_submix input", 0, true, createPortMixExt(10, 10));
         rsubmixInMix.profiles = remoteSubmixPcmAudioProfiles;
         c.ports.push_back(rsubmixInMix);
 
-        // Adding a DIRECT flag to rsubmixInMix breaks the capture paths, so we need separate
-        // non direct and direct paths. It is added because for IEC61937 encapsulated over PCM, we
-        // need the DIRECT flag for the capability so AudioFlinger can find a DIRECT input match.
-        AudioPort rsubmixInDirectMix =
-                createPort(c.nextPortId++, "r_submix input direct",
-                                makeBitPositionFlagMask({AudioInputFlags::DIRECT}),
-                                true /* isInput */,
-                                createPortMixExt(1 /* maxOpenStreamCount */,
-                                                 1 /* maxActiveStreamCount */));
-        rsubmixInDirectMix.profiles = remoteSubmixPcmAudioProfiles;
-        c.ports.push_back(rsubmixInDirectMix);
-
-        c.routes.push_back(createRoute(
-                {rsubmixOutMix, rsubmixOutDirectMix}, rsubmixOutDevice));
+        c.routes.push_back(createRoute({rsubmixOutMix}, rsubmixOutDevice));
         c.routes.push_back(createRoute({rsubmixInDevice}, rsubmixInMix));
-        c.routes.push_back(createRoute({rsubmixInDevice}, rsubmixInDirectMix));
 
         return c;
     }();
diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp
index d0e8745..94aa4dc 100644
--- a/audio/aidl/default/Module.cpp
+++ b/audio/aidl/default/Module.cpp
@@ -93,32 +93,6 @@
     return std::all_of(profiles.begin(), profiles.end(), isDynamicProfile);
 }
 
-// Note: does not assign an ID to the config.
-bool generateDefaultPortConfig(const AudioPort& port, AudioPortConfig* config) {
-    const bool allowDynamicConfig = port.ext.getTag() == AudioPortExt::device;
-    *config = {};
-    config->portId = port.id;
-    for (const auto& profile : port.profiles) {
-        if (isDynamicProfile(profile)) continue;
-        config->format = profile.format;
-        config->channelMask = *profile.channelMasks.begin();
-        config->sampleRate = Int{.value = *profile.sampleRates.begin()};
-        config->flags = port.flags;
-        config->ext = port.ext;
-        return true;
-    }
-    if (allowDynamicConfig) {
-        config->format = AudioFormatDescription{};
-        config->channelMask = AudioChannelLayout{};
-        config->sampleRate = Int{.value = 0};
-        config->flags = port.flags;
-        config->ext = port.ext;
-        return true;
-    }
-    LOG(ERROR) << __func__ << ": port " << port.id << " only has dynamic profiles";
-    return false;
-}
-
 bool findAudioProfile(const AudioPort& port, const AudioFormatDescription& format,
                       AudioProfile* profile) {
     if (auto profilesIt =
@@ -204,10 +178,11 @@
     }
     auto& configs = getConfig().portConfigs;
     auto portConfigIt = findById<AudioPortConfig>(configs, in_portConfigId);
+    const int32_t nominalLatencyMs = getNominalLatencyMs(*portConfigIt);
     // Since this is a private method, it is assumed that
     // validity of the portConfigId has already been checked.
-    const int32_t minimumStreamBufferSizeFrames = calculateBufferSizeFrames(
-            getNominalLatencyMs(*portConfigIt), portConfigIt->sampleRate.value().value);
+    const int32_t minimumStreamBufferSizeFrames =
+            calculateBufferSizeFrames(nominalLatencyMs, portConfigIt->sampleRate.value().value);
     if (in_bufferSizeFrames < minimumStreamBufferSizeFrames) {
         LOG(ERROR) << __func__ << ": insufficient buffer size " << in_bufferSizeFrames
                    << ", must be at least " << minimumStreamBufferSizeFrames;
@@ -246,7 +221,7 @@
                 std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
                 std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
                 portConfigIt->format.value(), portConfigIt->channelMask.value(),
-                portConfigIt->sampleRate.value().value, flags, getNominalLatencyMs(*portConfigIt),
+                portConfigIt->sampleRate.value().value, flags, nominalLatencyMs,
                 portConfigIt->ext.get<AudioPortExt::mix>().handle,
                 std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
                 asyncCallback, outEventCallback, mSoundDose.getInstance(), params);
@@ -332,6 +307,29 @@
     return ndk::ScopedAStatus::ok();
 }
 
+bool Module::generateDefaultPortConfig(const AudioPort& port, AudioPortConfig* config) {
+    const bool allowDynamicConfig = port.ext.getTag() == AudioPortExt::device;
+    for (const auto& profile : port.profiles) {
+        if (isDynamicProfile(profile)) continue;
+        config->format = profile.format;
+        config->channelMask = *profile.channelMasks.begin();
+        config->sampleRate = Int{.value = *profile.sampleRates.begin()};
+        config->flags = port.flags;
+        config->ext = port.ext;
+        return true;
+    }
+    if (allowDynamicConfig) {
+        config->format = AudioFormatDescription{};
+        config->channelMask = AudioChannelLayout{};
+        config->sampleRate = Int{.value = 0};
+        config->flags = port.flags;
+        config->ext = port.ext;
+        return true;
+    }
+    LOG(ERROR) << __func__ << ": port " << port.id << " only has dynamic profiles";
+    return false;
+}
+
 void Module::populateConnectedProfiles() {
     Configuration& config = getConfig();
     for (const AudioPort& port : config.ports) {
@@ -621,10 +619,11 @@
 
     std::vector<AudioRoute*> routesToMixPorts = getAudioRoutesForAudioPortImpl(templateId);
     std::set<int32_t> routableMixPortIds = getRoutableAudioPortIds(templateId, &routesToMixPorts);
+    const int32_t nextPortId = getConfig().nextPortId++;
     if (!mDebug.simulateDeviceConnections) {
         // Even if the device port has static profiles, the HAL module might need to update
         // them, or abort the connection process.
-        RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort));
+        RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort, nextPortId));
     } else if (hasDynamicProfilesOnly(connectedPort.profiles)) {
         auto& connectedProfiles = getConfig().connectedProfiles;
         if (auto connectedProfilesIt = connectedProfiles.find(templateId);
@@ -648,7 +647,7 @@
         }
     }
 
-    connectedPort.id = getConfig().nextPortId++;
+    connectedPort.id = nextPortId;
     auto [connectedPortsIt, _] =
             mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::set<int32_t>()));
     LOG(DEBUG) << __func__ << ": template port " << templateId << " external device connected, "
@@ -1039,6 +1038,18 @@
 
 ndk::ScopedAStatus Module::setAudioPortConfig(const AudioPortConfig& in_requested,
                                               AudioPortConfig* out_suggested, bool* _aidl_return) {
+    auto generate = [this](const AudioPort& port, AudioPortConfig* config) {
+        return generateDefaultPortConfig(port, config);
+    };
+    return setAudioPortConfigImpl(in_requested, generate, out_suggested, _aidl_return);
+}
+
+ndk::ScopedAStatus Module::setAudioPortConfigImpl(
+        const AudioPortConfig& in_requested,
+        const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port,
+                                 ::aidl::android::media::audio::common::AudioPortConfig* config)>&
+                fillPortConfig,
+        AudioPortConfig* out_suggested, bool* applied) {
     LOG(DEBUG) << __func__ << ": requested " << in_requested.toString();
     auto& configs = getConfig().portConfigs;
     auto existing = configs.end();
@@ -1067,7 +1078,8 @@
         *out_suggested = *existing;
     } else {
         AudioPortConfig newConfig;
-        if (generateDefaultPortConfig(*portIt, &newConfig)) {
+        newConfig.portId = portIt->id;
+        if (fillPortConfig(*portIt, &newConfig)) {
             *out_suggested = newConfig;
         } else {
             LOG(ERROR) << __func__ << ": unable generate a default config for port " << portId;
@@ -1172,17 +1184,17 @@
     if (existing == configs.end() && requestedIsValid && requestedIsFullySpecified) {
         out_suggested->id = getConfig().nextPortId++;
         configs.push_back(*out_suggested);
-        *_aidl_return = true;
+        *applied = true;
         LOG(DEBUG) << __func__ << ": created new port config " << out_suggested->toString();
     } else if (existing != configs.end() && requestedIsValid) {
         *existing = *out_suggested;
-        *_aidl_return = true;
+        *applied = true;
         LOG(DEBUG) << __func__ << ": updated port config " << out_suggested->toString();
     } else {
         LOG(DEBUG) << __func__ << ": not applied; existing config ? " << (existing != configs.end())
                    << "; requested is valid? " << requestedIsValid << ", fully specified? "
                    << requestedIsFullySpecified;
-        *_aidl_return = false;
+        *applied = false;
     }
     return ndk::ScopedAStatus::ok();
 }
@@ -1534,7 +1546,7 @@
     return mIsMmapSupported.value();
 }
 
-ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort) {
+ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
     if (audioPort->ext.getTag() != AudioPortExt::device) {
         LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
diff --git a/audio/aidl/default/acousticEchoCanceler/Android.bp b/audio/aidl/default/acousticEchoCanceler/Android.bp
index bfb7212..35d4a56 100644
--- a/audio/aidl/default/acousticEchoCanceler/Android.bp
+++ b/audio/aidl/default/acousticEchoCanceler/Android.bp
@@ -27,8 +27,6 @@
     name: "libaecsw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "AcousticEchoCancelerSw.cpp",
diff --git a/audio/aidl/default/alsa/ModuleAlsa.cpp b/audio/aidl/default/alsa/ModuleAlsa.cpp
index 8512631..9a2cce7 100644
--- a/audio/aidl/default/alsa/ModuleAlsa.cpp
+++ b/audio/aidl/default/alsa/ModuleAlsa.cpp
@@ -34,7 +34,7 @@
 
 namespace aidl::android::hardware::audio::core {
 
-ndk::ScopedAStatus ModuleAlsa::populateConnectedDevicePort(AudioPort* audioPort) {
+ndk::ScopedAStatus ModuleAlsa::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
     auto deviceProfile = alsa::getDeviceProfile(*audioPort);
     if (!deviceProfile.has_value()) {
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 6f0af21..827ff80 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -47,6 +47,7 @@
         <library name="visualizer" path="libvisualizeraidl.so"/>
         <library name="volumesw" path="libvolumesw.so"/>
         <library name="extensioneffect" path="libextensioneffect.so"/>
+        <library name="spatializersw" path="libspatializersw.so"/>
     </libraries>
 
     <!-- list of effects to load.
@@ -98,6 +99,7 @@
         <effect name="extension_effect" library="extensioneffect" uuid="fa81dd00-588b-11ed-9b6a-0242ac120002" type="fa81de0e-588b-11ed-9b6a-0242ac120002"/>
         <effect name="acoustic_echo_canceler" library="pre_processing" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
         <effect name="noise_suppression" library="pre_processing" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
+        <effect name="spatializer" library="spatializersw" uuid="fa81a880-588b-11ed-9b6a-0242ac120002"/>
     </effects>
 
     <preprocess>
diff --git a/audio/aidl/default/automaticGainControlV1/Android.bp b/audio/aidl/default/automaticGainControlV1/Android.bp
index 4ae8e63..05c2c54 100644
--- a/audio/aidl/default/automaticGainControlV1/Android.bp
+++ b/audio/aidl/default/automaticGainControlV1/Android.bp
@@ -27,8 +27,6 @@
     name: "libagc1sw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "AutomaticGainControlV1Sw.cpp",
diff --git a/audio/aidl/default/automaticGainControlV2/Android.bp b/audio/aidl/default/automaticGainControlV2/Android.bp
index 631cf58..dedc555 100644
--- a/audio/aidl/default/automaticGainControlV2/Android.bp
+++ b/audio/aidl/default/automaticGainControlV2/Android.bp
@@ -27,8 +27,6 @@
     name: "libagc2sw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "AutomaticGainControlV2Sw.cpp",
diff --git a/audio/aidl/default/bassboost/Android.bp b/audio/aidl/default/bassboost/Android.bp
index 82b2f20..9f47770 100644
--- a/audio/aidl/default/bassboost/Android.bp
+++ b/audio/aidl/default/bassboost/Android.bp
@@ -27,8 +27,6 @@
     name: "libbassboostsw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "BassBoostSw.cpp",
diff --git a/audio/aidl/default/bluetooth/DevicePortProxy.cpp b/audio/aidl/default/bluetooth/DevicePortProxy.cpp
index 1be0875..d772c20 100644
--- a/audio/aidl/default/bluetooth/DevicePortProxy.cpp
+++ b/audio/aidl/default/bluetooth/DevicePortProxy.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "AHAL_BluetoothPortProxy"
+#define LOG_TAG "AHAL_BluetoothAudioPort"
 
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
@@ -254,12 +254,7 @@
     return (mCookie != ::aidl::android::hardware::bluetooth::audio::kObserversCookieUndefined);
 }
 
-bool BluetoothAudioPortAidl::getPreferredDataIntervalUs(size_t* interval_us) const {
-    if (!interval_us) {
-        LOG(ERROR) << __func__ << ": bad input arg";
-        return false;
-    }
-
+bool BluetoothAudioPortAidl::getPreferredDataIntervalUs(size_t& interval_us) const {
     if (!inUse()) {
         LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
         return false;
@@ -272,16 +267,11 @@
         return false;
     }
 
-    *interval_us = hal_audio_cfg.get<AudioConfiguration::pcmConfig>().dataIntervalUs;
+    interval_us = hal_audio_cfg.get<AudioConfiguration::pcmConfig>().dataIntervalUs;
     return true;
 }
 
-bool BluetoothAudioPortAidl::loadAudioConfig(PcmConfiguration* audio_cfg) const {
-    if (!audio_cfg) {
-        LOG(ERROR) << __func__ << ": bad input arg";
-        return false;
-    }
-
+bool BluetoothAudioPortAidl::loadAudioConfig(PcmConfiguration& audio_cfg) {
     if (!inUse()) {
         LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
         return false;
@@ -293,15 +283,26 @@
         LOG(ERROR) << __func__ << ": unsupported audio cfg tag";
         return false;
     }
-    *audio_cfg = hal_audio_cfg.get<AudioConfiguration::pcmConfig>();
+    audio_cfg = hal_audio_cfg.get<AudioConfiguration::pcmConfig>();
     LOG(VERBOSE) << __func__ << debugMessage() << ", state*=" << getState() << ", PcmConfig=["
-                 << audio_cfg->toString() << "]";
-    if (audio_cfg->channelMode == ChannelMode::UNKNOWN) {
+                 << audio_cfg.toString() << "]";
+    if (audio_cfg.channelMode == ChannelMode::UNKNOWN) {
         return false;
     }
     return true;
 }
 
+bool BluetoothAudioPortAidlOut::loadAudioConfig(PcmConfiguration& audio_cfg) {
+    if (!BluetoothAudioPortAidl::loadAudioConfig(audio_cfg)) return false;
+    // WAR to support Mono / 16 bits per sample as the Bluetooth stack requires
+    if (audio_cfg.channelMode == ChannelMode::MONO && audio_cfg.bitsPerSample == 16) {
+        mIsStereoToMono = true;
+        audio_cfg.channelMode = ChannelMode::STEREO;
+        LOG(INFO) << __func__ << ": force channels = to be AUDIO_CHANNEL_OUT_STEREO";
+    }
+    return true;
+}
+
 bool BluetoothAudioPortAidl::standby() {
     if (!inUse()) {
         LOG(ERROR) << __func__ << ": BluetoothAudioPortAidl is not in use";
@@ -435,7 +436,7 @@
                 retval = condWaitState(BluetoothStreamState::SUSPENDING);
             } else {
                 LOG(ERROR) << __func__ << debugMessage() << ", state=" << getState()
-                           << " Hal fails";
+                           << " failure to suspend stream";
             }
         }
     }
diff --git a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
index 8a1cbbf..9084b30 100644
--- a/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/ModuleBluetooth.cpp
@@ -24,13 +24,25 @@
 
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::hardware::bluetooth::audio::ChannelMode;
+using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioConfigBase;
 using aidl::android::media::audio::common::AudioDeviceDescription;
 using aidl::android::media::audio::common::AudioDeviceType;
+using aidl::android::media::audio::common::AudioFormatDescription;
+using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioIoFlags;
 using aidl::android::media::audio::common::AudioOffloadInfo;
 using aidl::android::media::audio::common::AudioPort;
+using aidl::android::media::audio::common::AudioPortConfig;
 using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::Int;
 using aidl::android::media::audio::common::MicrophoneInfo;
+using aidl::android::media::audio::common::PcmType;
 using android::bluetooth::audio::aidl::BluetoothAudioPortAidl;
+using android::bluetooth::audio::aidl::BluetoothAudioPortAidlIn;
 using android::bluetooth::audio::aidl::BluetoothAudioPortAidlOut;
 
 // TODO(b/312265159) bluetooth audio should be in its own process
@@ -39,6 +51,35 @@
 
 namespace aidl::android::hardware::audio::core {
 
+namespace {
+
+PcmType pcmTypeFromBitsPerSample(int8_t bitsPerSample) {
+    if (bitsPerSample == 8)
+        return PcmType::UINT_8_BIT;
+    else if (bitsPerSample == 16)
+        return PcmType::INT_16_BIT;
+    else if (bitsPerSample == 24)
+        return PcmType::INT_24_BIT;
+    else if (bitsPerSample == 32)
+        return PcmType::INT_32_BIT;
+    ALOGE("Unsupported bitsPerSample: %d", bitsPerSample);
+    return PcmType::DEFAULT;
+}
+
+AudioChannelLayout channelLayoutFromChannelMode(ChannelMode mode) {
+    if (mode == ChannelMode::MONO) {
+        return AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                AudioChannelLayout::LAYOUT_MONO);
+    } else if (mode == ChannelMode::STEREO || mode == ChannelMode::DUALMONO) {
+        return AudioChannelLayout::make<AudioChannelLayout::layoutMask>(
+                AudioChannelLayout::LAYOUT_STEREO);
+    }
+    ALOGE("Unsupported channel mode: %s", toString(mode).c_str());
+    return AudioChannelLayout{};
+}
+
+}  // namespace
+
 ModuleBluetooth::ModuleBluetooth(std::unique_ptr<Module::Configuration>&& config)
     : Module(Type::BLUETOOTH, std::move(config)) {
     // TODO(b/312265159) bluetooth audio should be in its own process
@@ -95,66 +136,130 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
+ndk::ScopedAStatus ModuleBluetooth::setAudioPortConfig(const AudioPortConfig& in_requested,
+                                                       AudioPortConfig* out_suggested,
+                                                       bool* _aidl_return) {
+    auto fillConfig = [this](const AudioPort& port, AudioPortConfig* config) {
+        if (port.ext.getTag() == AudioPortExt::device) {
+            CachedProxy proxy;
+            auto status = findOrCreateProxy(port, proxy);
+            if (status.isOk()) {
+                const auto& pcmConfig = proxy.pcmConfig;
+                LOG(DEBUG) << "setAudioPortConfig: suggesting port config from "
+                           << pcmConfig.toString();
+                const auto pcmType = pcmTypeFromBitsPerSample(pcmConfig.bitsPerSample);
+                const auto channelMask = channelLayoutFromChannelMode(pcmConfig.channelMode);
+                if (pcmType != PcmType::DEFAULT && channelMask != AudioChannelLayout{}) {
+                    config->format =
+                            AudioFormatDescription{.type = AudioFormatType::PCM, .pcm = pcmType};
+                    config->channelMask = channelMask;
+                    config->sampleRate = Int{.value = pcmConfig.sampleRateHz};
+                    config->flags = port.flags;
+                    config->ext = port.ext;
+                    return true;
+                }
+            }
+        }
+        return generateDefaultPortConfig(port, config);
+    };
+    return Module::setAudioPortConfigImpl(in_requested, fillConfig, out_suggested, _aidl_return);
+}
+
+ndk::ScopedAStatus ModuleBluetooth::checkAudioPatchEndpointsMatch(
+        const std::vector<AudioPortConfig*>& sources, const std::vector<AudioPortConfig*>& sinks) {
+    // Both sources and sinks must be non-empty, this is guaranteed by 'setAudioPatch'.
+    const bool isInput = sources[0]->ext.getTag() == AudioPortExt::device;
+    const int32_t devicePortId = isInput ? sources[0]->portId : sinks[0]->portId;
+    const auto proxyIt = mProxies.find(devicePortId);
+    if (proxyIt == mProxies.end()) return ndk::ScopedAStatus::ok();
+    const auto& pcmConfig = proxyIt->second.pcmConfig;
+    const AudioPortConfig* mixPortConfig = isInput ? sinks[0] : sources[0];
+    if (!StreamBluetooth::checkConfigParams(
+                pcmConfig, AudioConfigBase{.sampleRate = mixPortConfig->sampleRate->value,
+                                           .channelMask = *(mixPortConfig->channelMask),
+                                           .format = *(mixPortConfig->format)})) {
+        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    }
+    if (int32_t handle = mixPortConfig->ext.get<AudioPortExt::mix>().handle; handle > 0) {
+        mConnections.insert(std::pair(handle, devicePortId));
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+void ModuleBluetooth::onExternalDeviceConnectionChanged(const AudioPort& audioPort,
+                                                        bool connected) {
+    if (!connected) mProxies.erase(audioPort.id);
+}
+
 ndk::ScopedAStatus ModuleBluetooth::createInputStream(
         StreamContext&& context, const SinkMetadata& sinkMetadata,
         const std::vector<MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) {
+    CachedProxy proxy;
+    RETURN_STATUS_IF_ERROR(fetchAndCheckProxy(context, proxy));
     return createStreamInstance<StreamInBluetooth>(result, std::move(context), sinkMetadata,
-                                                   microphones, getBtProfileManagerHandles());
+                                                   microphones, getBtProfileManagerHandles(),
+                                                   proxy.ptr, proxy.pcmConfig);
 }
 
 ndk::ScopedAStatus ModuleBluetooth::createOutputStream(
         StreamContext&& context, const SourceMetadata& sourceMetadata,
         const std::optional<AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) {
+    CachedProxy proxy;
+    RETURN_STATUS_IF_ERROR(fetchAndCheckProxy(context, proxy));
     return createStreamInstance<StreamOutBluetooth>(result, std::move(context), sourceMetadata,
-                                                    offloadInfo, getBtProfileManagerHandles());
+                                                    offloadInfo, getBtProfileManagerHandles(),
+                                                    proxy.ptr, proxy.pcmConfig);
 }
 
-ndk::ScopedAStatus ModuleBluetooth::populateConnectedDevicePort(AudioPort* audioPort) {
+ndk::ScopedAStatus ModuleBluetooth::populateConnectedDevicePort(AudioPort* audioPort,
+                                                                int32_t nextPortId) {
     if (audioPort->ext.getTag() != AudioPortExt::device) {
         LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
+    if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::IsAidlAvailable()) {
+        LOG(ERROR) << __func__ << ": IBluetoothAudioProviderFactory AIDL service not available";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
     const auto& devicePort = audioPort->ext.get<AudioPortExt::device>();
     const auto& description = devicePort.device.type;
-    // Since the configuration of the BT module is static, there is nothing to populate here.
-    // However, this method must return an error when the device can not be connected,
-    // this is determined by the status of BT profiles.
+    // This method must return an error when the device can not be connected.
     if (description.connection == AudioDeviceDescription::CONNECTION_BT_A2DP) {
         bool isA2dpEnabled = false;
         if (!!mBluetoothA2dp) {
             RETURN_STATUS_IF_ERROR((*mBluetoothA2dp).isEnabled(&isA2dpEnabled));
         }
         LOG(DEBUG) << __func__ << ": isA2dpEnabled: " << isA2dpEnabled;
-        return isA2dpEnabled ? ndk::ScopedAStatus::ok()
-                             : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        if (!isA2dpEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     } else if (description.connection == AudioDeviceDescription::CONNECTION_BT_LE) {
         bool isLeEnabled = false;
         if (!!mBluetoothLe) {
             RETURN_STATUS_IF_ERROR((*mBluetoothLe).isEnabled(&isLeEnabled));
         }
         LOG(DEBUG) << __func__ << ": isLeEnabled: " << isLeEnabled;
-        return isLeEnabled ? ndk::ScopedAStatus::ok()
-                           : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        if (!isLeEnabled) return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
     } else if (description.connection == AudioDeviceDescription::CONNECTION_WIRELESS &&
                description.type == AudioDeviceType::OUT_HEARING_AID) {
-        // Hearing aids can use a number of profiles, thus the only way to check
-        // connectivity is to try to talk to the BT HAL.
-        if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::
-                    IsAidlAvailable()) {
-            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
-        }
-        std::shared_ptr<BluetoothAudioPortAidl> proxy = std::shared_ptr<BluetoothAudioPortAidl>(
-                std::make_shared<BluetoothAudioPortAidlOut>());
-        if (proxy->registerPort(description)) {
-            LOG(DEBUG) << __func__ << ": registered hearing aid port";
-            proxy->unregisterPort();
-            return ndk::ScopedAStatus::ok();
-        }
-        LOG(DEBUG) << __func__ << ": failed to register hearing aid port";
-        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        // Hearing aids can use a number of profiles, no single switch exists.
+    } else {
+        LOG(ERROR) << __func__ << ": unsupported device type: " << audioPort->toString();
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
-    LOG(ERROR) << __func__ << ": unsupported device type: " << audioPort->toString();
-    return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    CachedProxy proxy;
+    RETURN_STATUS_IF_ERROR(createProxy(*audioPort, nextPortId, proxy));
+    // Since the device is already connected and configured by the BT stack, provide
+    // the current configuration instead of all possible profiles.
+    const auto& pcmConfig = proxy.pcmConfig;
+    audioPort->profiles.clear();
+    audioPort->profiles.push_back(
+            AudioProfile{.format = AudioFormatDescription{.type = AudioFormatType::PCM,
+                                                          .pcm = pcmTypeFromBitsPerSample(
+                                                                  pcmConfig.bitsPerSample)},
+                         .channelMasks = std::vector<AudioChannelLayout>(
+                                 {channelLayoutFromChannelMode(pcmConfig.channelMode)}),
+                         .sampleRates = std::vector<int>({pcmConfig.sampleRateHz})});
+    LOG(DEBUG) << __func__ << ": " << audioPort->toString();
+    return ndk::ScopedAStatus::ok();
 }
 
 ndk::ScopedAStatus ModuleBluetooth::onMasterMuteChanged(bool) {
@@ -167,4 +272,77 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
+int32_t ModuleBluetooth::getNominalLatencyMs(const AudioPortConfig& portConfig) {
+    const auto connectionsIt = mConnections.find(portConfig.ext.get<AudioPortExt::mix>().handle);
+    if (connectionsIt != mConnections.end()) {
+        const auto proxyIt = mProxies.find(connectionsIt->second);
+        if (proxyIt != mProxies.end()) {
+            auto proxy = proxyIt->second.ptr;
+            size_t dataIntervalUs = 0;
+            if (!proxy->getPreferredDataIntervalUs(dataIntervalUs)) {
+                LOG(WARNING) << __func__ << ": could not fetch preferred data interval";
+            }
+            const bool isInput = portConfig.flags->getTag() == AudioIoFlags::input;
+            return isInput ? StreamInBluetooth::getNominalLatencyMs(dataIntervalUs)
+                           : StreamOutBluetooth::getNominalLatencyMs(dataIntervalUs);
+        }
+    }
+    LOG(ERROR) << __func__ << ": no connection or proxy found for " << portConfig.toString();
+    return Module::getNominalLatencyMs(portConfig);
+}
+
+ndk::ScopedAStatus ModuleBluetooth::createProxy(const AudioPort& audioPort, int32_t instancePortId,
+                                                CachedProxy& proxy) {
+    const bool isInput = audioPort.flags.getTag() == AudioIoFlags::input;
+    proxy.ptr = isInput ? std::shared_ptr<BluetoothAudioPortAidl>(
+                                  std::make_shared<BluetoothAudioPortAidlIn>())
+                        : std::shared_ptr<BluetoothAudioPortAidl>(
+                                  std::make_shared<BluetoothAudioPortAidlOut>());
+    const auto& devicePort = audioPort.ext.get<AudioPortExt::device>();
+    if (const auto device = devicePort.device.type; !proxy.ptr->registerPort(device)) {
+        LOG(ERROR) << __func__ << ": failed to register BT port for " << device.toString();
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    if (!proxy.ptr->loadAudioConfig(proxy.pcmConfig)) {
+        LOG(ERROR) << __func__ << ": state=" << proxy.ptr->getState()
+                   << ", failed to load audio config";
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+    }
+    mProxies.insert(std::pair(instancePortId, proxy));
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleBluetooth::fetchAndCheckProxy(const StreamContext& context,
+                                                       CachedProxy& proxy) {
+    const auto connectionsIt = mConnections.find(context.getMixPortHandle());
+    if (connectionsIt != mConnections.end()) {
+        const auto proxyIt = mProxies.find(connectionsIt->second);
+        if (proxyIt != mProxies.end()) {
+            proxy = proxyIt->second;
+            mProxies.erase(proxyIt);
+        }
+        mConnections.erase(connectionsIt);
+    }
+    if (proxy.ptr != nullptr) {
+        if (!StreamBluetooth::checkConfigParams(
+                    proxy.pcmConfig, AudioConfigBase{.sampleRate = context.getSampleRate(),
+                                                     .channelMask = context.getChannelLayout(),
+                                                     .format = context.getFormat()})) {
+            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
+        }
+    }
+    // Not having a proxy is OK, it may happen in VTS tests when streams are opened on unconnected
+    // mix ports.
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus ModuleBluetooth::findOrCreateProxy(const AudioPort& audioPort,
+                                                      CachedProxy& proxy) {
+    if (auto proxyIt = mProxies.find(audioPort.id); proxyIt != mProxies.end()) {
+        proxy = proxyIt->second;
+        return ndk::ScopedAStatus::ok();
+    }
+    return createProxy(audioPort, audioPort.id, proxy);
+}
+
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
index 0cee7f4..a73af1b 100644
--- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "AHAL_StreamBluetooth"
+#include <algorithm>
 
+#define LOG_TAG "AHAL_StreamBluetooth"
 #include <Utils.h>
 #include <android-base/logging.h>
 #include <audio_utils/clock.h>
@@ -31,6 +32,7 @@
 using aidl::android::hardware::bluetooth::audio::PcmConfiguration;
 using aidl::android::hardware::bluetooth::audio::PresentationPosition;
 using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioConfigBase;
 using aidl::android::media::audio::common::AudioDevice;
 using aidl::android::media::audio::common::AudioDeviceAddress;
 using aidl::android::media::audio::common::AudioFormatDescription;
@@ -48,51 +50,33 @@
 constexpr int kBluetoothDefaultInputBufferMs = 20;
 constexpr int kBluetoothDefaultOutputBufferMs = 10;
 // constexpr int kBluetoothSpatializerOutputBufferMs = 10;
+constexpr int kBluetoothDefaultRemoteDelayMs = 200;
 
-// pcm configuration params are not really used by the module
 StreamBluetooth::StreamBluetooth(StreamContext* context, const Metadata& metadata,
-                                 ModuleBluetooth::BtProfileHandles&& btHandles)
+                                 ModuleBluetooth::BtProfileHandles&& btHandles,
+                                 const std::shared_ptr<BluetoothAudioPortAidl>& btDeviceProxy,
+                                 const PcmConfiguration& pcmConfig)
     : StreamCommonImpl(context, metadata),
-      mSampleRate(getContext().getSampleRate()),
-      mChannelLayout(getContext().getChannelLayout()),
-      mFormat(getContext().getFormat()),
       mFrameSizeBytes(getContext().getFrameSize()),
       mIsInput(isInput(metadata)),
       mBluetoothA2dp(std::move(std::get<ModuleBluetooth::BtInterface::BTA2DP>(btHandles))),
-      mBluetoothLe(std::move(std::get<ModuleBluetooth::BtInterface::BTLE>(btHandles))) {
-    mPreferredDataIntervalUs =
-            (mIsInput ? kBluetoothDefaultInputBufferMs : kBluetoothDefaultOutputBufferMs) * 1000;
-    mPreferredFrameCount = frameCountFromDurationUs(mPreferredDataIntervalUs, mSampleRate);
-    mIsInitialized = false;
-    mIsReadyToClose = false;
-}
+      mBluetoothLe(std::move(std::get<ModuleBluetooth::BtInterface::BTLE>(btHandles))),
+      mPreferredDataIntervalUs(pcmConfig.dataIntervalUs != 0
+                                       ? pcmConfig.dataIntervalUs
+                                       : (mIsInput ? kBluetoothDefaultInputBufferMs
+                                                   : kBluetoothDefaultOutputBufferMs) *
+                                                 1000),
+      mPreferredFrameCount(
+              frameCountFromDurationUs(mPreferredDataIntervalUs, pcmConfig.sampleRateHz)),
+      mBtDeviceProxy(btDeviceProxy) {}
 
 ::android::status_t StreamBluetooth::init() {
-    return ::android::OK;  // defering this till we get AudioDeviceDescription
-}
-
-const StreamCommonInterface::ConnectedDevices& StreamBluetooth::getConnectedDevices() const {
     std::lock_guard guard(mLock);
-    return StreamCommonImpl::getConnectedDevices();
-}
-
-ndk::ScopedAStatus StreamBluetooth::setConnectedDevices(
-        const std::vector<AudioDevice>& connectedDevices) {
-    if (mIsInput && connectedDevices.size() > 1) {
-        LOG(ERROR) << __func__ << ": wrong device size(" << connectedDevices.size()
-                   << ") for input stream";
-        return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    if (mBtDeviceProxy == nullptr) {
+        // This is a normal situation in VTS tests.
+        LOG(INFO) << __func__ << ": no BT HAL proxy, stream is non-functional";
     }
-    for (const auto& connectedDevice : connectedDevices) {
-        if (connectedDevice.address.getTag() != AudioDeviceAddress::mac) {
-            LOG(ERROR) << __func__ << ": bad device address" << connectedDevice.address.toString();
-            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
-        }
-    }
-    std::lock_guard guard(mLock);
-    RETURN_STATUS_IF_ERROR(StreamCommonImpl::setConnectedDevices(connectedDevices));
-    mIsInitialized = false;  // updated connected device list, need initialization
-    return ndk::ScopedAStatus::ok();
+    return ::android::OK;
 }
 
 ::android::status_t StreamBluetooth::drain(StreamDescriptor::DrainMode) {
@@ -112,167 +96,111 @@
 ::android::status_t StreamBluetooth::transfer(void* buffer, size_t frameCount,
                                               size_t* actualFrameCount, int32_t* latencyMs) {
     std::lock_guard guard(mLock);
-    if (!mIsInitialized || mIsReadyToClose) {
-        // 'setConnectedDevices' has been called or stream is ready to close, so no transfers
+    if (mBtDeviceProxy == nullptr || mBtDeviceProxy->getState() == BluetoothStreamState::DISABLED) {
         *actualFrameCount = 0;
         *latencyMs = StreamDescriptor::LATENCY_UNKNOWN;
         return ::android::OK;
     }
     *actualFrameCount = 0;
     *latencyMs = 0;
-    for (auto proxy : mBtDeviceProxies) {
-        if (!proxy->start()) {
-            LOG(ERROR) << __func__ << ": state = " << proxy->getState() << " failed to start ";
-            return -EIO;
-        }
-        const size_t fc = std::min(frameCount, mPreferredFrameCount);
-        const size_t bytesToTransfer = fc * mFrameSizeBytes;
-        if (mIsInput) {
-            const size_t totalRead = proxy->readData(buffer, bytesToTransfer);
-            *actualFrameCount = std::max(*actualFrameCount, totalRead / mFrameSizeBytes);
-        } else {
-            const size_t totalWrite = proxy->writeData(buffer, bytesToTransfer);
-            *actualFrameCount = std::max(*actualFrameCount, totalWrite / mFrameSizeBytes);
-        }
-        PresentationPosition presentation_position;
-        if (!proxy->getPresentationPosition(presentation_position)) {
-            LOG(ERROR) << __func__ << ": getPresentationPosition returned error ";
-            return ::android::UNKNOWN_ERROR;
-        }
-        *latencyMs =
-                std::max(*latencyMs, (int32_t)(presentation_position.remoteDeviceAudioDelayNanos /
-                                               NANOS_PER_MILLISECOND));
+    if (!mBtDeviceProxy->start()) {
+        LOG(ERROR) << __func__ << ": state= " << mBtDeviceProxy->getState() << " failed to start";
+        return -EIO;
     }
+    const size_t fc = std::min(frameCount, mPreferredFrameCount);
+    const size_t bytesToTransfer = fc * mFrameSizeBytes;
+    if (mIsInput) {
+        const size_t totalRead = mBtDeviceProxy->readData(buffer, bytesToTransfer);
+        *actualFrameCount = std::max(*actualFrameCount, totalRead / mFrameSizeBytes);
+    } else {
+        const size_t totalWrite = mBtDeviceProxy->writeData(buffer, bytesToTransfer);
+        *actualFrameCount = std::max(*actualFrameCount, totalWrite / mFrameSizeBytes);
+    }
+    PresentationPosition presentation_position;
+    if (!mBtDeviceProxy->getPresentationPosition(presentation_position)) {
+        presentation_position.remoteDeviceAudioDelayNanos =
+                kBluetoothDefaultRemoteDelayMs * NANOS_PER_MILLISECOND;
+        LOG(WARNING) << __func__ << ": getPresentationPosition failed, latency info is unavailable";
+    }
+    // TODO(b/317117580): incorporate logic from
+    //                    packages/modules/Bluetooth/system/audio_bluetooth_hw/stream_apis.cc
+    //                    out_calculate_feeding_delay_ms / in_calculate_starving_delay_ms
+    *latencyMs = std::max(*latencyMs, (int32_t)(presentation_position.remoteDeviceAudioDelayNanos /
+                                                NANOS_PER_MILLISECOND));
     return ::android::OK;
 }
 
-::android::status_t StreamBluetooth::initialize() {
-    if (!::aidl::android::hardware::bluetooth::audio::BluetoothAudioSession::IsAidlAvailable()) {
-        LOG(ERROR) << __func__ << ": IBluetoothAudioProviderFactory service not available";
-        return ::android::UNKNOWN_ERROR;
-    }
-    if (StreamCommonImpl::getConnectedDevices().empty()) {
-        LOG(ERROR) << __func__ << ", has no connected devices";
-        return ::android::NO_INIT;
-    }
-    // unregister older proxies (if any)
-    for (auto proxy : mBtDeviceProxies) {
-        proxy->stop();
-        proxy->unregisterPort();
-    }
-    mBtDeviceProxies.clear();
-    for (auto it = StreamCommonImpl::getConnectedDevices().begin();
-         it != StreamCommonImpl::getConnectedDevices().end(); ++it) {
-        std::shared_ptr<BluetoothAudioPortAidl> proxy =
-                mIsInput ? std::shared_ptr<BluetoothAudioPortAidl>(
-                                   std::make_shared<BluetoothAudioPortAidlIn>())
-                         : std::shared_ptr<BluetoothAudioPortAidl>(
-                                   std::make_shared<BluetoothAudioPortAidlOut>());
-        if (proxy->registerPort(it->type)) {
-            LOG(ERROR) << __func__ << ": cannot init HAL";
-            return ::android::UNKNOWN_ERROR;
-        }
-        PcmConfiguration config;
-        if (!proxy->loadAudioConfig(&config)) {
-            LOG(ERROR) << __func__ << ": state=" << proxy->getState()
-                       << " failed to get audio config";
-            return ::android::UNKNOWN_ERROR;
-        }
-        // TODO: Ensure minimum duration for spatialized output?
-        // WAR to support Mono / 16 bits per sample as the Bluetooth stack required
-        if (!mIsInput && config.channelMode == ChannelMode::MONO && config.bitsPerSample == 16) {
-            proxy->forcePcmStereoToMono(true);
-            config.channelMode = ChannelMode::STEREO;
-            LOG(INFO) << __func__ << ": force channels = to be AUDIO_CHANNEL_OUT_STEREO";
-        }
-        if (!checkConfigParams(config)) {
-            LOG(ERROR) << __func__ << " checkConfigParams failed";
-            return ::android::UNKNOWN_ERROR;
-        }
-        mBtDeviceProxies.push_back(std::move(proxy));
-    }
-    mIsInitialized = true;
-    return ::android::OK;
-}
-
-bool StreamBluetooth::checkConfigParams(
-        ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& config) {
-    if ((int)mSampleRate != config.sampleRateHz) {
-        LOG(ERROR) << __func__ << ": Sample Rate mismatch, stream val = " << mSampleRate
-                   << " hal val = " << config.sampleRateHz;
+// static
+bool StreamBluetooth::checkConfigParams(const PcmConfiguration& pcmConfig,
+                                        const AudioConfigBase& config) {
+    if ((int)config.sampleRate != pcmConfig.sampleRateHz) {
+        LOG(ERROR) << __func__ << ": sample rate mismatch, stream value=" << config.sampleRate
+                   << ", BT HAL value=" << pcmConfig.sampleRateHz;
         return false;
     }
-    auto channelCount = aidl::android::hardware::audio::common::getChannelCount(mChannelLayout);
-    if ((config.channelMode == ChannelMode::MONO && channelCount != 1) ||
-        (config.channelMode == ChannelMode::STEREO && channelCount != 2)) {
-        LOG(ERROR) << __func__ << ": Channel count mismatch, stream val = " << channelCount
-                   << " hal val = " << toString(config.channelMode);
+    const auto channelCount =
+            aidl::android::hardware::audio::common::getChannelCount(config.channelMask);
+    if ((pcmConfig.channelMode == ChannelMode::MONO && channelCount != 1) ||
+        (pcmConfig.channelMode == ChannelMode::STEREO && channelCount != 2)) {
+        LOG(ERROR) << __func__ << ": Channel count mismatch, stream value=" << channelCount
+                   << ", BT HAL value=" << toString(pcmConfig.channelMode);
         return false;
     }
-    if (mFormat.type != AudioFormatType::PCM) {
-        LOG(ERROR) << __func__ << ": unexpected format type "
-                   << aidl::android::media::audio::common::toString(mFormat.type);
+    if (config.format.type != AudioFormatType::PCM) {
+        LOG(ERROR) << __func__
+                   << ": unexpected stream format type: " << toString(config.format.type);
         return false;
     }
-    int8_t bps = aidl::android::hardware::audio::common::getPcmSampleSizeInBytes(mFormat.pcm) * 8;
-    if (bps != config.bitsPerSample) {
-        LOG(ERROR) << __func__ << ": bits per sample mismatch, stream val = " << bps
-                   << " hal val = " << config.bitsPerSample;
+    const int8_t bitsPerSample =
+            aidl::android::hardware::audio::common::getPcmSampleSizeInBytes(config.format.pcm) * 8;
+    if (bitsPerSample != pcmConfig.bitsPerSample) {
+        LOG(ERROR) << __func__ << ": bits per sample mismatch, stream value=" << bitsPerSample
+                   << ", BT HAL value=" << pcmConfig.bitsPerSample;
         return false;
     }
-    if (config.dataIntervalUs > 0) {
-        mPreferredDataIntervalUs =
-                std::min((int32_t)mPreferredDataIntervalUs, config.dataIntervalUs);
-        mPreferredFrameCount = frameCountFromDurationUs(mPreferredDataIntervalUs, mSampleRate);
-    }
     return true;
 }
 
 ndk::ScopedAStatus StreamBluetooth::prepareToClose() {
     std::lock_guard guard(mLock);
-    mIsReadyToClose = true;
+    if (mBtDeviceProxy != nullptr) {
+        if (mBtDeviceProxy->getState() != BluetoothStreamState::DISABLED) {
+            mBtDeviceProxy->stop();
+        }
+    }
     return ndk::ScopedAStatus::ok();
 }
 
 ::android::status_t StreamBluetooth::standby() {
     std::lock_guard guard(mLock);
-    if (!mIsInitialized) {
-        if (auto status = initialize(); status != ::android::OK) return status;
-    }
-    for (auto proxy : mBtDeviceProxies) {
-        if (!proxy->suspend()) {
-            LOG(ERROR) << __func__ << ": state = " << proxy->getState() << " failed to stand by ";
-            return -EIO;
-        }
-    }
+    if (mBtDeviceProxy != nullptr) mBtDeviceProxy->suspend();
     return ::android::OK;
 }
 
 ::android::status_t StreamBluetooth::start() {
     std::lock_guard guard(mLock);
-    if (!mIsInitialized) return initialize();
+    if (mBtDeviceProxy != nullptr) mBtDeviceProxy->start();
     return ::android::OK;
 }
 
 void StreamBluetooth::shutdown() {
     std::lock_guard guard(mLock);
-    for (auto proxy : mBtDeviceProxies) {
-        proxy->stop();
-        proxy->unregisterPort();
+    if (mBtDeviceProxy != nullptr) {
+        mBtDeviceProxy->stop();
+        mBtDeviceProxy = nullptr;
     }
-    mBtDeviceProxies.clear();
 }
 
 ndk::ScopedAStatus StreamBluetooth::updateMetadataCommon(const Metadata& metadata) {
     std::lock_guard guard(mLock);
-    if (!mIsInitialized) return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+    if (mBtDeviceProxy == nullptr) {
+        return ndk::ScopedAStatus::ok();
+    }
     bool isOk = true;
     if (isInput(metadata)) {
-        isOk = mBtDeviceProxies[0]->updateSinkMetadata(std::get<SinkMetadata>(metadata));
+        isOk = mBtDeviceProxy->updateSinkMetadata(std::get<SinkMetadata>(metadata));
     } else {
-        for (auto proxy : mBtDeviceProxies) {
-            if (!proxy->updateSourceMetadata(std::get<SourceMetadata>(metadata))) isOk = false;
-        }
+        isOk = mBtDeviceProxy->updateSourceMetadata(std::get<SourceMetadata>(metadata));
     }
     return isOk ? ndk::ScopedAStatus::ok()
                 : ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -280,7 +208,6 @@
 
 ndk::ScopedAStatus StreamBluetooth::bluetoothParametersUpdated() {
     if (mIsInput) {
-        LOG(WARNING) << __func__ << ": not handled";
         return ndk::ScopedAStatus::ok();
     }
     auto applyParam = [](const std::shared_ptr<BluetoothAudioPortAidl>& proxy,
@@ -297,15 +224,10 @@
     bool hasLeParam, enableLe;
     auto btLe = mBluetoothLe.lock();
     hasLeParam = btLe != nullptr && btLe->isEnabled(&enableLe).isOk();
-    std::unique_lock lock(mLock);
-    ::android::base::ScopedLockAssertion lock_assertion(mLock);
-    if (!mIsInitialized) {
-        LOG(WARNING) << __func__ << ": init not done";
-        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
-    }
-    for (auto proxy : mBtDeviceProxies) {
-        if ((hasA2dpParam && proxy->isA2dp() && !applyParam(proxy, enableA2dp)) ||
-            (hasLeParam && proxy->isLeAudio() && !applyParam(proxy, enableLe))) {
+    std::lock_guard guard(mLock);
+    if (mBtDeviceProxy != nullptr) {
+        if ((hasA2dpParam && mBtDeviceProxy->isA2dp() && !applyParam(mBtDeviceProxy, enableA2dp)) ||
+            (hasLeParam && mBtDeviceProxy->isLeAudio() && !applyParam(mBtDeviceProxy, enableLe))) {
             LOG(DEBUG) << __func__ << ": applyParam failed";
             return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
         }
@@ -313,11 +235,20 @@
     return ndk::ScopedAStatus::ok();
 }
 
+// static
+int32_t StreamInBluetooth::getNominalLatencyMs(size_t dataIntervalUs) {
+    if (dataIntervalUs == 0) dataIntervalUs = kBluetoothDefaultInputBufferMs * 1000LL;
+    return dataIntervalUs / 1000LL;
+}
+
 StreamInBluetooth::StreamInBluetooth(StreamContext&& context, const SinkMetadata& sinkMetadata,
                                      const std::vector<MicrophoneInfo>& microphones,
-                                     ModuleBluetooth::BtProfileHandles&& btProfileHandles)
+                                     ModuleBluetooth::BtProfileHandles&& btProfileHandles,
+                                     const std::shared_ptr<BluetoothAudioPortAidl>& btDeviceProxy,
+                                     const PcmConfiguration& pcmConfig)
     : StreamIn(std::move(context), microphones),
-      StreamBluetooth(&mContextInstance, sinkMetadata, std::move(btProfileHandles)) {}
+      StreamBluetooth(&mContextInstance, sinkMetadata, std::move(btProfileHandles), btDeviceProxy,
+                      pcmConfig) {}
 
 ndk::ScopedAStatus StreamInBluetooth::getActiveMicrophones(
         std::vector<MicrophoneDynamicInfo>* _aidl_return __unused) {
@@ -325,11 +256,20 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
+// static
+int32_t StreamOutBluetooth::getNominalLatencyMs(size_t dataIntervalUs) {
+    if (dataIntervalUs == 0) dataIntervalUs = kBluetoothDefaultOutputBufferMs * 1000LL;
+    return dataIntervalUs / 1000LL;
+}
+
 StreamOutBluetooth::StreamOutBluetooth(StreamContext&& context,
                                        const SourceMetadata& sourceMetadata,
                                        const std::optional<AudioOffloadInfo>& offloadInfo,
-                                       ModuleBluetooth::BtProfileHandles&& btProfileHandles)
+                                       ModuleBluetooth::BtProfileHandles&& btProfileHandles,
+                                       const std::shared_ptr<BluetoothAudioPortAidl>& btDeviceProxy,
+                                       const PcmConfiguration& pcmConfig)
     : StreamOut(std::move(context), offloadInfo),
-      StreamBluetooth(&mContextInstance, sourceMetadata, std::move(btProfileHandles)) {}
+      StreamBluetooth(&mContextInstance, sourceMetadata, std::move(btProfileHandles), btDeviceProxy,
+                      pcmConfig) {}
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/downmix/Android.bp b/audio/aidl/default/downmix/Android.bp
index 6d15cdb..8657283 100644
--- a/audio/aidl/default/downmix/Android.bp
+++ b/audio/aidl/default/downmix/Android.bp
@@ -27,8 +27,6 @@
     name: "libdownmixsw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "DownmixSw.cpp",
diff --git a/audio/aidl/default/dynamicProcessing/Android.bp b/audio/aidl/default/dynamicProcessing/Android.bp
index 1c0312d..c0a648d 100644
--- a/audio/aidl/default/dynamicProcessing/Android.bp
+++ b/audio/aidl/default/dynamicProcessing/Android.bp
@@ -27,8 +27,6 @@
     name: "libdynamicsprocessingsw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "DynamicsProcessingSw.cpp",
diff --git a/audio/aidl/default/envReverb/Android.bp b/audio/aidl/default/envReverb/Android.bp
index dd4219a..2443c2a 100644
--- a/audio/aidl/default/envReverb/Android.bp
+++ b/audio/aidl/default/envReverb/Android.bp
@@ -27,8 +27,6 @@
     name: "libenvreverbsw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "EnvReverbSw.cpp",
diff --git a/audio/aidl/default/equalizer/Android.bp b/audio/aidl/default/equalizer/Android.bp
index 3610563..42708d1 100644
--- a/audio/aidl/default/equalizer/Android.bp
+++ b/audio/aidl/default/equalizer/Android.bp
@@ -27,8 +27,6 @@
     name: "libequalizersw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "EqualizerSw.cpp",
diff --git a/audio/aidl/default/extension/Android.bp b/audio/aidl/default/extension/Android.bp
index 4e5d352..5fee479 100644
--- a/audio/aidl/default/extension/Android.bp
+++ b/audio/aidl/default/extension/Android.bp
@@ -27,8 +27,6 @@
     name: "libextensioneffect",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "ExtensionEffect.cpp",
diff --git a/audio/aidl/default/hapticGenerator/Android.bp b/audio/aidl/default/hapticGenerator/Android.bp
index 0df9a94..8fb9a3d 100644
--- a/audio/aidl/default/hapticGenerator/Android.bp
+++ b/audio/aidl/default/hapticGenerator/Android.bp
@@ -27,8 +27,6 @@
     name: "libhapticgeneratorsw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "HapticGeneratorSw.cpp",
diff --git a/audio/aidl/default/include/core-impl/DevicePortProxy.h b/audio/aidl/default/include/core-impl/DevicePortProxy.h
index 17a8cf3..ccb23bb 100644
--- a/audio/aidl/default/include/core-impl/DevicePortProxy.h
+++ b/audio/aidl/default/include/core-impl/DevicePortProxy.h
@@ -73,12 +73,7 @@
      * Bluetooth stack
      */
     virtual bool loadAudioConfig(
-            ::aidl::android::hardware::bluetooth::audio::PcmConfiguration*) const = 0;
-
-    /**
-     * WAR to support Mono mode / 16 bits per sample
-     */
-    virtual void forcePcmStereoToMono(bool) = 0;
+            ::aidl::android::hardware::bluetooth::audio::PcmConfiguration&) = 0;
 
     /**
      * When the Audio framework / HAL wants to change the stream state, it invokes
@@ -145,7 +140,7 @@
 
     virtual bool isLeAudio() const = 0;
 
-    virtual bool getPreferredDataIntervalUs(size_t*) const = 0;
+    virtual bool getPreferredDataIntervalUs(size_t&) const = 0;
 
     virtual size_t writeData(const void*, size_t) const { return 0; }
 
@@ -162,10 +157,8 @@
 
     void unregisterPort() override;
 
-    bool loadAudioConfig(::aidl::android::hardware::bluetooth::audio::PcmConfiguration* audio_cfg)
-            const override;
-
-    void forcePcmStereoToMono(bool force) override { mIsStereoToMono = force; }
+    bool loadAudioConfig(
+            ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override;
 
     bool standby() override;
     bool start() override;
@@ -193,7 +186,7 @@
 
     bool isLeAudio() const override;
 
-    bool getPreferredDataIntervalUs(size_t* interval_us) const override;
+    bool getPreferredDataIntervalUs(size_t& interval_us) const override;
 
   protected:
     uint16_t mCookie;
@@ -228,6 +221,9 @@
 
 class BluetoothAudioPortAidlOut : public BluetoothAudioPortAidl {
   public:
+    bool loadAudioConfig(
+            ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& audio_cfg) override;
+
     // The audio data path to the Bluetooth stack (Software encoding)
     size_t writeData(const void* buffer, size_t bytes) const override;
 };
diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h
index 572b597..ce71d70 100644
--- a/audio/aidl/default/include/core-impl/Module.h
+++ b/audio/aidl/default/include/core-impl/Module.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include <functional>
 #include <iostream>
 #include <map>
 #include <memory>
@@ -188,7 +189,7 @@
     // If the module is unable to populate the connected device port correctly, the returned error
     // code must correspond to the errors of `IModule.connectedExternalDevice` method.
     virtual ndk::ScopedAStatus populateConnectedDevicePort(
-            ::aidl::android::media::audio::common::AudioPort* audioPort);
+            ::aidl::android::media::audio::common::AudioPort* audioPort, int32_t nextPortId);
     // If the module finds that the patch endpoints configurations are not matched, the returned
     // error code must correspond to the errors of `IModule.setAudioPatch` method.
     virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
@@ -210,6 +211,7 @@
         const int32_t rawSizeFrames =
                 aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs,
                                                                                  sampleRateHz);
+        if (latencyMs >= 5) return rawSizeFrames;
         int32_t powerOf2 = 1;
         while (powerOf2 < rawSizeFrames) powerOf2 <<= 1;
         return powerOf2;
@@ -227,12 +229,16 @@
     std::set<int32_t> findConnectedPortConfigIds(int32_t portConfigId);
     ndk::ScopedAStatus findPortIdForNewStream(
             int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port);
+    // Note: does not assign an ID to the config.
+    bool generateDefaultPortConfig(const ::aidl::android::media::audio::common::AudioPort& port,
+                                   ::aidl::android::media::audio::common::AudioPortConfig* config);
     std::vector<AudioRoute*> getAudioRoutesForAudioPortImpl(int32_t portId);
     Configuration& getConfig();
     const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; }
     bool getMasterMute() const { return mMasterMute; }
     bool getMasterVolume() const { return mMasterVolume; }
     bool getMicMute() const { return mMicMute; }
+    const ModuleDebug& getModuleDebug() const { return mDebug; }
     const Patches& getPatches() const { return mPatches; }
     std::set<int32_t> getRoutableAudioPortIds(int32_t portId,
                                               std::vector<AudioRoute*>* routes = nullptr);
@@ -243,6 +249,12 @@
     template <typename C>
     std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds);
     void registerPatch(const AudioPatch& patch);
+    ndk::ScopedAStatus setAudioPortConfigImpl(
+            const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
+            const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port,
+                                     ::aidl::android::media::audio::common::AudioPortConfig*
+                                             config)>& fillPortConfig,
+            ::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied);
     ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch,
                                                    const AudioPatch& newPatch);
 };
diff --git a/audio/aidl/default/include/core-impl/ModuleAlsa.h b/audio/aidl/default/include/core-impl/ModuleAlsa.h
index 2774fe5..3392b41 100644
--- a/audio/aidl/default/include/core-impl/ModuleAlsa.h
+++ b/audio/aidl/default/include/core-impl/ModuleAlsa.h
@@ -33,7 +33,8 @@
   protected:
     // Extension methods of 'Module'.
     ndk::ScopedAStatus populateConnectedDevicePort(
-            ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+            ::aidl::android::media::audio::common::AudioPort* audioPort,
+            int32_t nextPortId) override;
 };
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/ModuleBluetooth.h b/audio/aidl/default/include/core-impl/ModuleBluetooth.h
index 631b088..9451411 100644
--- a/audio/aidl/default/include/core-impl/ModuleBluetooth.h
+++ b/audio/aidl/default/include/core-impl/ModuleBluetooth.h
@@ -16,7 +16,10 @@
 
 #pragma once
 
+#include <map>
+
 #include "core-impl/Bluetooth.h"
+#include "core-impl/DevicePortProxy.h"
 #include "core-impl/Module.h"
 
 namespace aidl::android::hardware::audio::core {
@@ -31,6 +34,11 @@
     ModuleBluetooth(std::unique_ptr<Configuration>&& config);
 
   private:
+    struct CachedProxy {
+        std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl> ptr;
+        ::aidl::android::hardware::bluetooth::audio::PcmConfiguration pcmConfig;
+    };
+
     ChildInterface<BluetoothA2dp>& getBtA2dp();
     ChildInterface<BluetoothLe>& getBtLe();
     BtProfileHandles getBtProfileManagerHandles();
@@ -40,6 +48,17 @@
     ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
     ndk::ScopedAStatus setMicMute(bool in_mute) override;
 
+    ndk::ScopedAStatus setAudioPortConfig(
+            const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
+            ::aidl::android::media::audio::common::AudioPortConfig* out_suggested,
+            bool* _aidl_return) override;
+
+    ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
+            const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
+            const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
+            override;
+    void onExternalDeviceConnectionChanged(
+            const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected);
     ndk::ScopedAStatus createInputStream(
             StreamContext&& context,
             const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
@@ -52,12 +71,24 @@
                     offloadInfo,
             std::shared_ptr<StreamOut>* result) override;
     ndk::ScopedAStatus populateConnectedDevicePort(
-            ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+            ::aidl::android::media::audio::common::AudioPort* audioPort,
+            int32_t nextPortId) override;
     ndk::ScopedAStatus onMasterMuteChanged(bool mute) override;
     ndk::ScopedAStatus onMasterVolumeChanged(float volume) override;
+    int32_t getNominalLatencyMs(
+            const ::aidl::android::media::audio::common::AudioPortConfig& portConfig) override;
+
+    ndk::ScopedAStatus createProxy(
+            const ::aidl::android::media::audio::common::AudioPort& audioPort,
+            int32_t instancePortId, CachedProxy& proxy);
+    ndk::ScopedAStatus fetchAndCheckProxy(const StreamContext& context, CachedProxy& proxy);
+    ndk::ScopedAStatus findOrCreateProxy(
+            const ::aidl::android::media::audio::common::AudioPort& audioPort, CachedProxy& proxy);
 
     ChildInterface<BluetoothA2dp> mBluetoothA2dp;
     ChildInterface<BluetoothLe> mBluetoothLe;
+    std::map<int32_t /*instantiated device port ID*/, CachedProxy> mProxies;
+    std::map<int32_t /*mix port handle*/, int32_t /*instantiated device port ID*/> mConnections;
 };
 
 }  // namespace aidl::android::hardware::audio::core
diff --git a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h
index 9f8acc9..613ac62 100644
--- a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h
@@ -29,6 +29,10 @@
     // IModule interfaces
     ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
     ndk::ScopedAStatus setMicMute(bool in_mute) override;
+    ndk::ScopedAStatus setAudioPortConfig(
+            const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
+            ::aidl::android::media::audio::common::AudioPortConfig* out_suggested,
+            bool* _aidl_return) override;
 
     // Module interfaces
     ndk::ScopedAStatus createInputStream(
@@ -43,7 +47,8 @@
                     offloadInfo,
             std::shared_ptr<StreamOut>* result) override;
     ndk::ScopedAStatus populateConnectedDevicePort(
-            ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+            ::aidl::android::media::audio::common::AudioPort* audioPort,
+            int32_t nextPortId) override;
     ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
             const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
             const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
diff --git a/audio/aidl/default/include/core-impl/ModuleUsb.h b/audio/aidl/default/include/core-impl/ModuleUsb.h
index 6ee8f8a..d9ac4f0 100644
--- a/audio/aidl/default/include/core-impl/ModuleUsb.h
+++ b/audio/aidl/default/include/core-impl/ModuleUsb.h
@@ -44,7 +44,8 @@
                     offloadInfo,
             std::shared_ptr<StreamOut>* result) override;
     ndk::ScopedAStatus populateConnectedDevicePort(
-            ::aidl::android::media::audio::common::AudioPort* audioPort) override;
+            ::aidl::android::media::audio::common::AudioPort* audioPort,
+            int32_t nextPortId) override;
     ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
             const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
             const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
diff --git a/audio/aidl/default/include/core-impl/StreamBluetooth.h b/audio/aidl/default/include/core-impl/StreamBluetooth.h
index 1258d38..35c3183 100644
--- a/audio/aidl/default/include/core-impl/StreamBluetooth.h
+++ b/audio/aidl/default/include/core-impl/StreamBluetooth.h
@@ -31,8 +31,16 @@
 
 class StreamBluetooth : public StreamCommonImpl {
   public:
-    StreamBluetooth(StreamContext* context, const Metadata& metadata,
-                    ModuleBluetooth::BtProfileHandles&& btHandles);
+    static bool checkConfigParams(
+            const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig,
+            const ::aidl::android::media::audio::common::AudioConfigBase& config);
+
+    StreamBluetooth(
+            StreamContext* context, const Metadata& metadata,
+            ModuleBluetooth::BtProfileHandles&& btHandles,
+            const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
+                    btDeviceProxy,
+            const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
     // Methods of 'DriverInterface'.
     ::android::status_t init() override;
     ::android::status_t drain(StreamDescriptor::DrainMode) override;
@@ -47,40 +55,35 @@
     // Overridden methods of 'StreamCommonImpl', called on a Binder thread.
     ndk::ScopedAStatus updateMetadataCommon(const Metadata& metadata) override;
     ndk::ScopedAStatus prepareToClose() override;
-    const ConnectedDevices& getConnectedDevices() const override;
-    ndk::ScopedAStatus setConnectedDevices(const ConnectedDevices& devices) override;
     ndk::ScopedAStatus bluetoothParametersUpdated() override;
 
   private:
-    // Audio Pcm Config
-    const uint32_t mSampleRate;
-    const ::aidl::android::media::audio::common::AudioChannelLayout mChannelLayout;
-    const ::aidl::android::media::audio::common::AudioFormatDescription mFormat;
     const size_t mFrameSizeBytes;
     const bool mIsInput;
     const std::weak_ptr<IBluetoothA2dp> mBluetoothA2dp;
     const std::weak_ptr<IBluetoothLe> mBluetoothLe;
-    size_t mPreferredDataIntervalUs;
-    size_t mPreferredFrameCount;
-
+    const size_t mPreferredDataIntervalUs;
+    const size_t mPreferredFrameCount;
     mutable std::mutex mLock;
-    bool mIsInitialized GUARDED_BY(mLock);
-    bool mIsReadyToClose GUARDED_BY(mLock);
-    std::vector<std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>>
-            mBtDeviceProxies GUARDED_BY(mLock);
-
-    ::android::status_t initialize() REQUIRES(mLock);
-    bool checkConfigParams(::aidl::android::hardware::bluetooth::audio::PcmConfiguration& config);
+    // The lock is also used to serialize calls to the proxy.
+    std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl> mBtDeviceProxy
+            GUARDED_BY(mLock);  // proxy may be null if the stream is not connected to a device
 };
 
 class StreamInBluetooth final : public StreamIn, public StreamBluetooth {
   public:
     friend class ndk::SharedRefBase;
+
+    static int32_t getNominalLatencyMs(size_t dataIntervalUs);
+
     StreamInBluetooth(
             StreamContext&& context,
             const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
             const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
-            ModuleBluetooth::BtProfileHandles&& btHandles);
+            ModuleBluetooth::BtProfileHandles&& btHandles,
+            const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
+                    btDeviceProxy,
+            const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
 
   private:
     void onClose(StreamDescriptor::State) override { defaultOnClose(); }
@@ -92,12 +95,18 @@
 class StreamOutBluetooth final : public StreamOut, public StreamBluetooth {
   public:
     friend class ndk::SharedRefBase;
+
+    static int32_t getNominalLatencyMs(size_t dataIntervalUs);
+
     StreamOutBluetooth(
             StreamContext&& context,
             const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
             const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
                     offloadInfo,
-            ModuleBluetooth::BtProfileHandles&& btHandles);
+            ModuleBluetooth::BtProfileHandles&& btHandles,
+            const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
+                    btDeviceProxy,
+            const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
 
   private:
     void onClose(StreamDescriptor::State) override { defaultOnClose(); }
diff --git a/audio/aidl/default/include/core-impl/StreamPrimary.h b/audio/aidl/default/include/core-impl/StreamPrimary.h
index 145c3c4..8d5c57d 100644
--- a/audio/aidl/default/include/core-impl/StreamPrimary.h
+++ b/audio/aidl/default/include/core-impl/StreamPrimary.h
@@ -36,7 +36,7 @@
     std::vector<alsa::DeviceProfile> getDeviceProfiles() override;
 
     const bool mIsAsynchronous;
-    long mStartTimeNs = 0;
+    int64_t mStartTimeNs = 0;
     long mFramesSinceStart = 0;
     bool mSkipNextTransfer = false;
 };
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index ee10abf..477c30e 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -16,7 +16,6 @@
 
 #pragma once
 
-#include <mutex>
 #include <vector>
 
 #include "core-impl/Stream.h"
@@ -56,13 +55,6 @@
     r_submix::AudioConfig mStreamConfig;
     std::shared_ptr<r_submix::SubmixRoute> mCurrentRoute = nullptr;
 
-    // Mutex lock to protect vector of submix routes, each of these submix routes have their mutex
-    // locks and none of the mutex locks should be taken together.
-    static std::mutex sSubmixRoutesLock;
-    static std::map<::aidl::android::media::audio::common::AudioDeviceAddress,
-                    std::shared_ptr<r_submix::SubmixRoute>>
-            sSubmixRoutes GUARDED_BY(sSubmixRoutesLock);
-
     // limit for number of read error log entries to avoid spamming the logs
     static constexpr int kMaxReadErrorLogs = 5;
     // The duration of kMaxReadFailureAttempts * READ_ATTEMPT_SLEEP_MS must be strictly inferior
@@ -72,7 +64,7 @@
     // 5ms between two read attempts when pipe is empty
     static constexpr int kReadAttemptSleepUs = 5000;
 
-    long mStartTimeNs = 0;
+    int64_t mStartTimeNs = 0;
     long mFramesSinceStart = 0;
     int mReadErrorCount = 0;
 };
diff --git a/audio/aidl/default/loudnessEnhancer/Android.bp b/audio/aidl/default/loudnessEnhancer/Android.bp
index 89a72fe..cd44b50 100644
--- a/audio/aidl/default/loudnessEnhancer/Android.bp
+++ b/audio/aidl/default/loudnessEnhancer/Android.bp
@@ -27,8 +27,6 @@
     name: "libloudnessenhancersw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "LoudnessEnhancerSw.cpp",
diff --git a/audio/aidl/default/noiseSuppression/Android.bp b/audio/aidl/default/noiseSuppression/Android.bp
index dad3d49..f24ded6 100644
--- a/audio/aidl/default/noiseSuppression/Android.bp
+++ b/audio/aidl/default/noiseSuppression/Android.bp
@@ -27,8 +27,6 @@
     name: "libnssw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "NoiseSuppressionSw.cpp",
diff --git a/audio/aidl/default/presetReverb/Android.bp b/audio/aidl/default/presetReverb/Android.bp
index 18bdd17..d600141 100644
--- a/audio/aidl/default/presetReverb/Android.bp
+++ b/audio/aidl/default/presetReverb/Android.bp
@@ -27,8 +27,6 @@
     name: "libpresetreverbsw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "PresetReverbSw.cpp",
diff --git a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
index f3965ba..7bc783c 100644
--- a/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/ModuleRemoteSubmix.cpp
@@ -27,14 +27,36 @@
 
 using aidl::android::hardware::audio::common::SinkMetadata;
 using aidl::android::hardware::audio::common::SourceMetadata;
+using aidl::android::media::audio::common::AudioDeviceAddress;
 using aidl::android::media::audio::common::AudioFormatType;
+using aidl::android::media::audio::common::AudioIoFlags;
 using aidl::android::media::audio::common::AudioOffloadInfo;
 using aidl::android::media::audio::common::AudioPort;
 using aidl::android::media::audio::common::AudioPortConfig;
+using aidl::android::media::audio::common::AudioPortExt;
+using aidl::android::media::audio::common::AudioProfile;
+using aidl::android::media::audio::common::Int;
 using aidl::android::media::audio::common::MicrophoneInfo;
 
 namespace aidl::android::hardware::audio::core {
 
+namespace {
+
+std::optional<r_submix::AudioConfig> getRemoteEndConfig(const AudioPort& audioPort) {
+    const auto& deviceAddress = audioPort.ext.get<AudioPortExt::device>().device.address;
+    const bool isInput = audioPort.flags.getTag() == AudioIoFlags::input;
+    if (auto submixRoute = r_submix::SubmixRoute::findRoute(deviceAddress);
+        submixRoute != nullptr) {
+        if ((isInput && submixRoute->isStreamOutOpen()) ||
+            (!isInput && submixRoute->isStreamInOpen())) {
+            return submixRoute->getPipeConfig();
+        }
+    }
+    return {};
+}
+
+}  // namespace
+
 ndk::ScopedAStatus ModuleRemoteSubmix::getMicMute(bool* _aidl_return __unused) {
     LOG(DEBUG) << __func__ << ": is not supported";
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
@@ -45,13 +67,29 @@
     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
 
+ndk::ScopedAStatus ModuleRemoteSubmix::setAudioPortConfig(const AudioPortConfig& in_requested,
+                                                          AudioPortConfig* out_suggested,
+                                                          bool* _aidl_return) {
+    auto fillConfig = [this](const AudioPort& port, AudioPortConfig* config) {
+        if (port.ext.getTag() == AudioPortExt::device) {
+            if (auto pipeConfig = getRemoteEndConfig(port); pipeConfig.has_value()) {
+                LOG(DEBUG) << "setAudioPortConfig: suggesting port config from the remote end.";
+                config->format = pipeConfig->format;
+                config->channelMask = pipeConfig->channelLayout;
+                config->sampleRate = Int{.value = pipeConfig->sampleRate};
+                config->flags = port.flags;
+                config->ext = port.ext;
+                return true;
+            }
+        }
+        return generateDefaultPortConfig(port, config);
+    };
+    return Module::setAudioPortConfigImpl(in_requested, fillConfig, out_suggested, _aidl_return);
+}
+
 ndk::ScopedAStatus ModuleRemoteSubmix::createInputStream(
         StreamContext&& context, const SinkMetadata& sinkMetadata,
         const std::vector<MicrophoneInfo>& microphones, std::shared_ptr<StreamIn>* result) {
-    if (context.getFormat().type != AudioFormatType::PCM) {
-        LOG(DEBUG) << __func__ << ": not supported for format " << context.getFormat().toString();
-        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
-    }
     return createStreamInstance<StreamInRemoteSubmix>(result, std::move(context), sinkMetadata,
                                                       microphones);
 }
@@ -59,16 +97,27 @@
 ndk::ScopedAStatus ModuleRemoteSubmix::createOutputStream(
         StreamContext&& context, const SourceMetadata& sourceMetadata,
         const std::optional<AudioOffloadInfo>& offloadInfo, std::shared_ptr<StreamOut>* result) {
-    if (context.getFormat().type != AudioFormatType::PCM) {
-        LOG(DEBUG) << __func__ << ": not supported for format " << context.getFormat().toString();
-        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
-    }
     return createStreamInstance<StreamOutRemoteSubmix>(result, std::move(context), sourceMetadata,
                                                        offloadInfo);
 }
 
-ndk::ScopedAStatus ModuleRemoteSubmix::populateConnectedDevicePort(AudioPort* audioPort) {
-    // Find the corresponding mix port and copy its profiles.
+ndk::ScopedAStatus ModuleRemoteSubmix::populateConnectedDevicePort(AudioPort* audioPort, int32_t) {
+    if (audioPort->ext.getTag() != AudioPortExt::device) {
+        LOG(ERROR) << __func__ << ": not a device port: " << audioPort->toString();
+        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+    }
+    // If there is already a pipe with a stream for the port address, provide its configuration as
+    // the only option. Otherwise, find the corresponding mix port and copy its profiles.
+    if (auto pipeConfig = getRemoteEndConfig(*audioPort); pipeConfig.has_value()) {
+        audioPort->profiles.clear();
+        audioPort->profiles.push_back(AudioProfile{
+                .format = pipeConfig->format,
+                .channelMasks = std::vector<AudioChannelLayout>({pipeConfig->channelLayout}),
+                .sampleRates = std::vector<int>({pipeConfig->sampleRate})});
+        LOG(DEBUG) << __func__ << ": populated from remote end as: " << audioPort->toString();
+        return ndk::ScopedAStatus::ok();
+    }
+
     // At this moment, the port has the same ID as the template port, see connectExternalDevice.
     std::vector<AudioRoute*> routes = getAudioRoutesForAudioPortImpl(audioPort->id);
     if (routes.empty()) {
@@ -87,6 +136,7 @@
         RETURN_STATUS_IF_ERROR(getAudioPort(route->sinkPortId, &mixPort));
     }
     audioPort->profiles = mixPort.profiles;
+    LOG(DEBUG) << __func__ << ": populated from the mix port as: " << audioPort->toString();
     return ndk::ScopedAStatus::ok();
 }
 
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index d238aa4..3ee354b 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -43,26 +43,10 @@
     mStreamConfig.sampleRate = context->getSampleRate();
 }
 
-std::mutex StreamRemoteSubmix::sSubmixRoutesLock;
-std::map<AudioDeviceAddress, std::shared_ptr<SubmixRoute>> StreamRemoteSubmix::sSubmixRoutes;
-
 ::android::status_t StreamRemoteSubmix::init() {
-    {
-        std::lock_guard guard(sSubmixRoutesLock);
-        auto routeItr = sSubmixRoutes.find(mDeviceAddress);
-        if (routeItr != sSubmixRoutes.end()) {
-            mCurrentRoute = routeItr->second;
-        }
-        // If route is not available for this port, add it.
-        if (mCurrentRoute == nullptr) {
-            // Initialize the pipe.
-            mCurrentRoute = std::make_shared<SubmixRoute>();
-            if (::android::OK != mCurrentRoute->createPipe(mStreamConfig)) {
-                LOG(ERROR) << __func__ << ": create pipe failed";
-                return ::android::NO_INIT;
-            }
-            sSubmixRoutes.emplace(mDeviceAddress, mCurrentRoute);
-        }
+    mCurrentRoute = SubmixRoute::findOrCreateRoute(mDeviceAddress, mStreamConfig);
+    if (mCurrentRoute == nullptr) {
+        return ::android::NO_INIT;
     }
     if (!mCurrentRoute->isStreamConfigValid(mIsInput, mStreamConfig)) {
         LOG(ERROR) << __func__ << ": invalid stream config";
@@ -80,7 +64,6 @@
             return ::android::NO_INIT;
         }
     }
-
     mCurrentRoute->openStream(mIsInput);
     return ::android::OK;
 }
@@ -114,14 +97,7 @@
 
 ndk::ScopedAStatus StreamRemoteSubmix::prepareToClose() {
     if (!mIsInput) {
-        std::shared_ptr<SubmixRoute> route = nullptr;
-        {
-            std::lock_guard guard(sSubmixRoutesLock);
-            auto routeItr = sSubmixRoutes.find(mDeviceAddress);
-            if (routeItr != sSubmixRoutes.end()) {
-                route = routeItr->second;
-            }
-        }
+        std::shared_ptr<SubmixRoute> route = SubmixRoute::findRoute(mDeviceAddress);
         if (route != nullptr) {
             sp<MonoPipe> sink = route->getSink();
             if (sink == nullptr) {
@@ -148,9 +124,7 @@
     if (!mCurrentRoute->hasAtleastOneStreamOpen()) {
         mCurrentRoute->releasePipe();
         LOG(DEBUG) << __func__ << ": pipe destroyed";
-
-        std::lock_guard guard(sSubmixRoutesLock);
-        sSubmixRoutes.erase(mDeviceAddress);
+        SubmixRoute::removeRoute(mDeviceAddress);
     }
     mCurrentRoute.reset();
 }
@@ -164,7 +138,7 @@
                                     : outWrite(buffer, frameCount, actualFrameCount));
     const long bufferDurationUs =
             (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
-    const long totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+    const auto totalDurationUs = (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
     mFramesSinceStart += *actualFrameCount;
     const long totalOffsetUs =
             mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
@@ -201,7 +175,7 @@
 
 // Calculate the maximum size of the pipe buffer in frames for the specified stream.
 size_t StreamRemoteSubmix::getStreamPipeSizeInFrames() {
-    auto pipeConfig = mCurrentRoute->mPipeConfig;
+    auto pipeConfig = mCurrentRoute->getPipeConfig();
     const size_t maxFrameSize = std::max(mStreamConfig.frameSize, pipeConfig.frameSize);
     return (pipeConfig.frameCount * pipeConfig.frameSize) / maxFrameSize;
 }
@@ -300,8 +274,8 @@
     char* buff = (char*)buffer;
     size_t actuallyRead = 0;
     long remainingFrames = frameCount;
-    const long deadlineTimeNs = ::android::uptimeNanos() +
-                                getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND;
+    const int64_t deadlineTimeNs = ::android::uptimeNanos() +
+                                   getDelayInUsForFrameCount(frameCount) * NANOS_PER_MICROSECOND;
     while (remainingFrames > 0) {
         ssize_t framesRead = source->read(buff, remainingFrames);
         LOG(VERBOSE) << __func__ << ": frames read " << framesRead;
diff --git a/audio/aidl/default/r_submix/SubmixRoute.cpp b/audio/aidl/default/r_submix/SubmixRoute.cpp
index 235c9a3..7d706c2 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.cpp
+++ b/audio/aidl/default/r_submix/SubmixRoute.cpp
@@ -23,9 +23,49 @@
 #include "SubmixRoute.h"
 
 using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::media::audio::common::AudioDeviceAddress;
 
 namespace aidl::android::hardware::audio::core::r_submix {
 
+// static
+SubmixRoute::RoutesMonitor SubmixRoute::getRoutes() {
+    static std::mutex submixRoutesLock;
+    static RoutesMap submixRoutes;
+    return RoutesMonitor(submixRoutesLock, submixRoutes);
+}
+
+// static
+std::shared_ptr<SubmixRoute> SubmixRoute::findOrCreateRoute(const AudioDeviceAddress& deviceAddress,
+                                                            const AudioConfig& pipeConfig) {
+    auto routes = getRoutes();
+    auto routeItr = routes->find(deviceAddress);
+    if (routeItr != routes->end()) {
+        return routeItr->second;
+    }
+    auto route = std::make_shared<SubmixRoute>();
+    if (::android::OK != route->createPipe(pipeConfig)) {
+        LOG(ERROR) << __func__ << ": create pipe failed";
+        return nullptr;
+    }
+    routes->emplace(deviceAddress, route);
+    return route;
+}
+
+// static
+std::shared_ptr<SubmixRoute> SubmixRoute::findRoute(const AudioDeviceAddress& deviceAddress) {
+    auto routes = getRoutes();
+    auto routeItr = routes->find(deviceAddress);
+    if (routeItr != routes->end()) {
+        return routeItr->second;
+    }
+    return nullptr;
+}
+
+// static
+void SubmixRoute::removeRoute(const AudioDeviceAddress& deviceAddress) {
+    getRoutes()->erase(deviceAddress);
+}
+
 // Verify a submix input or output stream can be opened.
 bool SubmixRoute::isStreamConfigValid(bool isInput, const AudioConfig& streamConfig) {
     // If the stream is already open, don't open it again.
@@ -44,6 +84,7 @@
 // Compare this stream config with existing pipe config, returning false if they do *not*
 // match, true otherwise.
 bool SubmixRoute::isStreamConfigCompatible(const AudioConfig& streamConfig) {
+    std::lock_guard guard(mLock);
     if (streamConfig.channelLayout != mPipeConfig.channelLayout) {
         LOG(ERROR) << __func__ << ": channel count mismatch, stream channels = "
                    << streamConfig.channelLayout.toString()
@@ -162,17 +203,14 @@
         LOG(FATAL) << __func__ << ": Negotiation for the source failed, index = " << index;
         return ::android::BAD_INDEX;
     }
-    LOG(VERBOSE) << __func__ << ": created pipe";
-
-    mPipeConfig = streamConfig;
-    mPipeConfig.frameCount = sink->maxFrames();
-
-    LOG(VERBOSE) << __func__ << ": Pipe frame size : " << mPipeConfig.frameSize
-                 << ", pipe frames : " << mPipeConfig.frameCount;
+    LOG(VERBOSE) << __func__ << ": Pipe frame size : " << streamConfig.frameSize
+                 << ", pipe frames : " << sink->maxFrames();
 
     // Save references to the source and sink.
     {
         std::lock_guard guard(mLock);
+        mPipeConfig = streamConfig;
+        mPipeConfig.frameCount = sink->maxFrames();
         mSink = std::move(sink);
         mSource = std::move(source);
     }
@@ -181,15 +219,15 @@
 }
 
 // Release references to the sink and source.
-void SubmixRoute::releasePipe() {
+AudioConfig SubmixRoute::releasePipe() {
     std::lock_guard guard(mLock);
     mSink.clear();
     mSource.clear();
+    return mPipeConfig;
 }
 
 ::android::status_t SubmixRoute::resetPipe() {
-    releasePipe();
-    return createPipe(mPipeConfig);
+    return createPipe(releasePipe());
 }
 
 void SubmixRoute::standby(bool isInput) {
diff --git a/audio/aidl/default/r_submix/SubmixRoute.h b/audio/aidl/default/r_submix/SubmixRoute.h
index 252b1c9..160df41 100644
--- a/audio/aidl/default/r_submix/SubmixRoute.h
+++ b/audio/aidl/default/r_submix/SubmixRoute.h
@@ -25,6 +25,7 @@
 #include <media/nbaio/MonoPipeReader.h>
 
 #include <aidl/android/media/audio/common/AudioChannelLayout.h>
+#include <aidl/android/media/audio/common/AudioDeviceAddress.h>
 #include <aidl/android/media/audio/common/AudioFormatDescription.h>
 
 using aidl::android::media::audio::common::AudioChannelLayout;
@@ -60,7 +61,13 @@
 
 class SubmixRoute {
   public:
-    AudioConfig mPipeConfig;
+    static std::shared_ptr<SubmixRoute> findOrCreateRoute(
+            const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress,
+            const AudioConfig& pipeConfig);
+    static std::shared_ptr<SubmixRoute> findRoute(
+            const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
+    static void removeRoute(
+            const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
 
     bool isStreamInOpen() {
         std::lock_guard guard(mLock);
@@ -90,6 +97,10 @@
         std::lock_guard guard(mLock);
         return mSource;
     }
+    AudioConfig getPipeConfig() {
+        std::lock_guard guard(mLock);
+        return mPipeConfig;
+    }
 
     bool isStreamConfigValid(bool isInput, const AudioConfig& streamConfig);
     void closeStream(bool isInput);
@@ -98,17 +109,31 @@
     bool hasAtleastOneStreamOpen();
     int notifyReadError();
     void openStream(bool isInput);
-    void releasePipe();
+    AudioConfig releasePipe();
     ::android::status_t resetPipe();
     bool shouldBlockWrite();
     void standby(bool isInput);
     long updateReadCounterFrames(size_t frameCount);
 
   private:
+    using RoutesMap = std::map<::aidl::android::media::audio::common::AudioDeviceAddress,
+                               std::shared_ptr<r_submix::SubmixRoute>>;
+    class RoutesMonitor {
+      public:
+        RoutesMonitor(std::mutex& mutex, RoutesMap& routes) : mLock(mutex), mRoutes(routes) {}
+        RoutesMap* operator->() { return &mRoutes; }
+
+      private:
+        std::lock_guard<std::mutex> mLock;
+        RoutesMap& mRoutes;
+    };
+
+    static RoutesMonitor getRoutes();
+
     bool isStreamConfigCompatible(const AudioConfig& streamConfig);
 
     std::mutex mLock;
-
+    AudioConfig mPipeConfig GUARDED_BY(mLock);
     bool mStreamInOpen GUARDED_BY(mLock) = false;
     int mInputRefCount GUARDED_BY(mLock) = 0;
     bool mStreamInStandby GUARDED_BY(mLock) = true;
diff --git a/audio/aidl/default/spatializer/Android.bp b/audio/aidl/default/spatializer/Android.bp
new file mode 100644
index 0000000..05ed365
--- /dev/null
+++ b/audio/aidl/default/spatializer/Android.bp
@@ -0,0 +1,39 @@
+/*
+ * 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 {
+    // 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_shared {
+    name: "libspatializersw",
+    defaults: [
+        "aidlaudioeffectservice_defaults",
+    ],
+    srcs: [
+        "SpatializerSw.cpp",
+        ":effectCommonFile",
+    ],
+    relative_install_path: "soundfx",
+    visibility: [
+        "//hardware/interfaces/audio/aidl/default",
+    ],
+}
diff --git a/audio/aidl/default/spatializer/SpatializerSw.cpp b/audio/aidl/default/spatializer/SpatializerSw.cpp
new file mode 100644
index 0000000..434ed5a
--- /dev/null
+++ b/audio/aidl/default/spatializer/SpatializerSw.cpp
@@ -0,0 +1,211 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "AHAL_SpatializerSw"
+
+#include "SpatializerSw.h"
+
+#include <android-base/logging.h>
+#include <system/audio_effects/effect_uuid.h>
+
+#include <optional>
+
+using aidl::android::hardware::audio::common::getChannelCount;
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectImplUuidSpatializerSw;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::SpatializerSw;
+using aidl::android::hardware::audio::effect::State;
+using aidl::android::media::audio::common::AudioChannelLayout;
+using aidl::android::media::audio::common::AudioUuid;
+using aidl::android::media::audio::common::HeadTracking;
+using aidl::android::media::audio::common::Spatialization;
+
+extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
+                                           std::shared_ptr<IEffect>* instanceSpp) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidSpatializerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    if (!instanceSpp) {
+        LOG(ERROR) << __func__ << " invalid input parameter!";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+
+    *instanceSpp = ndk::SharedRefBase::make<SpatializerSw>();
+    LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
+    return EX_NONE;
+}
+
+extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
+    if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidSpatializerSw()) {
+        LOG(ERROR) << __func__ << "uuid not supported";
+        return EX_ILLEGAL_ARGUMENT;
+    }
+    *_aidl_return = SpatializerSw::kDescriptor;
+    return EX_NONE;
+}
+
+namespace aidl::android::hardware::audio::effect {
+
+const std::string SpatializerSw::kEffectName = "SpatializerSw";
+
+const std::vector<Range::SpatializerRange> SpatializerSw::kRanges = {
+        MAKE_RANGE(Spatializer, supportedChannelLayout, std::vector<AudioChannelLayout>{},
+                   std::vector<AudioChannelLayout>{}),
+        MAKE_RANGE(Spatializer, spatializationLevel, Spatialization::Level::NONE,
+                   Spatialization::Level::BED_PLUS_OBJECTS),
+        MAKE_RANGE(Spatializer, spatializationMode, Spatialization::Mode::BINAURAL,
+                   Spatialization::Mode::TRANSAURAL),
+        MAKE_RANGE(Spatializer, headTrackingSensorId, std::numeric_limits<int>::min(),
+                   std::numeric_limits<int>::max()),
+        MAKE_RANGE(Spatializer, headTrackingMode, HeadTracking::Mode::OTHER,
+                   HeadTracking::Mode::RELATIVE_SCREEN),
+        MAKE_RANGE(Spatializer, headTrackingConnectionMode,
+                   HeadTracking::ConnectionMode::FRAMEWORK_PROCESSED,
+                   HeadTracking::ConnectionMode::DIRECT_TO_SENSOR_TUNNEL)};
+const Capability SpatializerSw::kCapability = {.range = {SpatializerSw::kRanges}};
+const Descriptor SpatializerSw::kDescriptor = {
+        .common = {.id = {.type = getEffectTypeUuidSpatializer(),
+                          .uuid = getEffectImplUuidSpatializerSw()},
+                   .flags = {.type = Flags::Type::INSERT,
+                             .insert = Flags::Insert::FIRST,
+                             .hwAcceleratorMode = Flags::HardwareAccelerator::NONE},
+                   .name = SpatializerSw::kEffectName,
+                   .implementor = "The Android Open Source Project"},
+        .capability = SpatializerSw::kCapability};
+
+ndk::ScopedAStatus SpatializerSw::getDescriptor(Descriptor* _aidl_return) {
+    LOG(DEBUG) << __func__ << kDescriptor.toString();
+    *_aidl_return = kDescriptor;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SpatializerSw::setParameterSpecific(const Parameter::Specific& specific) {
+    RETURN_IF(Parameter::Specific::spatializer != specific.getTag(), EX_ILLEGAL_ARGUMENT,
+              "EffectNotSupported");
+    RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
+
+    auto& param = specific.get<Parameter::Specific::spatializer>();
+    RETURN_IF(!inRange(param, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
+
+    return mContext->setParam(param.getTag(), param);
+}
+
+ndk::ScopedAStatus SpatializerSw::getParameterSpecific(const Parameter::Id& id,
+                                                       Parameter::Specific* specific) {
+    auto tag = id.getTag();
+    RETURN_IF(Parameter::Id::spatializerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
+    auto spatializerId = id.get<Parameter::Id::spatializerTag>();
+    auto spatializerTag = spatializerId.getTag();
+    switch (spatializerTag) {
+        case Spatializer::Id::commonTag: {
+            auto specificTag = spatializerId.get<Spatializer::Id::commonTag>();
+            std::optional<Spatializer> param = mContext->getParam(specificTag);
+            if (!param.has_value()) {
+                return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
+                        EX_ILLEGAL_ARGUMENT, "SpatializerTagNotSupported");
+            }
+            specific->set<Parameter::Specific::spatializer>(param.value());
+            break;
+        }
+        default: {
+            LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "SpatializerTagNotSupported");
+        }
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+std::shared_ptr<EffectContext> SpatializerSw::createContext(const Parameter::Common& common) {
+    if (mContext) {
+        LOG(DEBUG) << __func__ << " context already exist";
+    } else {
+        mContext = std::make_shared<SpatializerSwContext>(1 /* statusFmqDepth */, common);
+    }
+    return mContext;
+}
+
+std::shared_ptr<EffectContext> SpatializerSw::getContext() {
+    return mContext;
+}
+
+RetCode SpatializerSw::releaseContext() {
+    if (mContext) {
+        mContext.reset();
+    }
+    return RetCode::SUCCESS;
+}
+
+SpatializerSw::~SpatializerSw() {
+    cleanUp();
+    LOG(DEBUG) << __func__;
+}
+
+// Processing method running in EffectWorker thread.
+IEffect::Status SpatializerSw::effectProcessImpl(float* in, float* out, int samples) {
+    RETURN_VALUE_IF(!mContext, (IEffect::Status{EX_NULL_POINTER, 0, 0}), "nullContext");
+    return mContext->process(in, out, samples);
+}
+
+SpatializerSwContext::SpatializerSwContext(int statusDepth, const Parameter::Common& common)
+    : EffectContext(statusDepth, common) {
+    LOG(DEBUG) << __func__;
+}
+
+SpatializerSwContext::~SpatializerSwContext() {
+    LOG(DEBUG) << __func__;
+}
+
+template <typename TAG>
+std::optional<Spatializer> SpatializerSwContext::getParam(TAG tag) {
+    if (mParamsMap.find(tag) != mParamsMap.end()) {
+        return mParamsMap.at(tag);
+    }
+    return std::nullopt;
+}
+
+template <typename TAG>
+ndk::ScopedAStatus SpatializerSwContext::setParam(TAG tag, Spatializer spatializer) {
+    mParamsMap[tag] = spatializer;
+    return ndk::ScopedAStatus::ok();
+}
+
+IEffect::Status SpatializerSwContext::process(float* in, float* out, int samples) {
+    LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
+    IEffect::Status status = {EX_ILLEGAL_ARGUMENT, 0, 0};
+
+    const auto inputChannelCount = getChannelCount(mCommon.input.base.channelMask);
+    const auto outputChannelCount = getChannelCount(mCommon.output.base.channelMask);
+    if (outputChannelCount < 2 || inputChannelCount < outputChannelCount) {
+        LOG(ERROR) << __func__ << " invalid channel count, in: " << inputChannelCount
+                   << " out: " << outputChannelCount;
+        return status;
+    }
+
+    int iFrames = samples / inputChannelCount;
+    for (int i = 0; i < iFrames; i++) {
+        std::memcpy(out, in, outputChannelCount);
+        in += inputChannelCount;
+        out += outputChannelCount;
+    }
+    return {STATUS_OK, static_cast<int32_t>(iFrames * inputChannelCount),
+            static_cast<int32_t>(iFrames * outputChannelCount)};
+}
+
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/spatializer/SpatializerSw.h b/audio/aidl/default/spatializer/SpatializerSw.h
new file mode 100644
index 0000000..b205704
--- /dev/null
+++ b/audio/aidl/default/spatializer/SpatializerSw.h
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "effect-impl/EffectContext.h"
+#include "effect-impl/EffectImpl.h"
+
+#include <fmq/AidlMessageQueue.h>
+
+#include <unordered_map>
+#include <vector>
+
+namespace aidl::android::hardware::audio::effect {
+
+class SpatializerSwContext final : public EffectContext {
+  public:
+    SpatializerSwContext(int statusDepth, const Parameter::Common& common);
+    ~SpatializerSwContext();
+
+    template <typename TAG>
+    std::optional<Spatializer> getParam(TAG tag);
+    template <typename TAG>
+    ndk::ScopedAStatus setParam(TAG tag, Spatializer spatializer);
+
+    IEffect::Status process(float* in, float* out, int samples);
+
+  private:
+    std::unordered_map<Spatializer::Tag, Spatializer> mParamsMap;
+};
+
+class SpatializerSw final : public EffectImpl {
+  public:
+    static const std::string kEffectName;
+    static const Capability kCapability;
+    static const Descriptor kDescriptor;
+    ~SpatializerSw();
+
+    ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
+    ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
+    ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
+                                            Parameter::Specific* specific) override;
+
+    std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
+    std::shared_ptr<EffectContext> getContext() override;
+    RetCode releaseContext() override;
+
+    std::string getEffectName() override { return kEffectName; };
+    IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
+
+  private:
+    static const std::vector<Range::SpatializerRange> kRanges;
+    std::shared_ptr<SpatializerSwContext> mContext = nullptr;
+};
+}  // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/usb/ModuleUsb.cpp b/audio/aidl/default/usb/ModuleUsb.cpp
index f926e09..1d97bc4 100644
--- a/audio/aidl/default/usb/ModuleUsb.cpp
+++ b/audio/aidl/default/usb/ModuleUsb.cpp
@@ -87,12 +87,13 @@
                                               offloadInfo);
 }
 
-ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort) {
+ndk::ScopedAStatus ModuleUsb::populateConnectedDevicePort(AudioPort* audioPort,
+                                                          int32_t nextPortId) {
     if (!isUsbDevicePort(*audioPort)) {
         LOG(ERROR) << __func__ << ": port id " << audioPort->id << " is not a usb device port";
         return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
     }
-    return ModuleAlsa::populateConnectedDevicePort(audioPort);
+    return ModuleAlsa::populateConnectedDevicePort(audioPort, nextPortId);
 }
 
 ndk::ScopedAStatus ModuleUsb::checkAudioPatchEndpointsMatch(
diff --git a/audio/aidl/default/virtualizer/Android.bp b/audio/aidl/default/virtualizer/Android.bp
index ed0199d..1c41bb5 100644
--- a/audio/aidl/default/virtualizer/Android.bp
+++ b/audio/aidl/default/virtualizer/Android.bp
@@ -27,8 +27,6 @@
     name: "libvirtualizersw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "VirtualizerSw.cpp",
diff --git a/audio/aidl/default/visualizer/Android.bp b/audio/aidl/default/visualizer/Android.bp
index 091daa2..68f7177 100644
--- a/audio/aidl/default/visualizer/Android.bp
+++ b/audio/aidl/default/visualizer/Android.bp
@@ -27,8 +27,6 @@
     name: "libvisualizersw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "VisualizerSw.cpp",
diff --git a/audio/aidl/default/volume/Android.bp b/audio/aidl/default/volume/Android.bp
index 418bb8d..f1a051f 100644
--- a/audio/aidl/default/volume/Android.bp
+++ b/audio/aidl/default/volume/Android.bp
@@ -27,8 +27,6 @@
     name: "libvolumesw",
     defaults: [
         "aidlaudioeffectservice_defaults",
-        "latest_android_media_audio_common_types_ndk_shared",
-        "latest_android_hardware_audio_effect_ndk_shared",
     ],
     srcs: [
         "VolumeSw.cpp",
diff --git a/audio/aidl/vts/Android.bp b/audio/aidl/vts/Android.bp
index 191f928..85319ec 100644
--- a/audio/aidl/vts/Android.bp
+++ b/audio/aidl/vts/Android.bp
@@ -36,16 +36,27 @@
         "-Werror",
         "-Wthread-safety",
     ],
+    test_config_template: "VtsHalAudioTargetTestTemplate.xml",
     test_suites: [
         "general-tests",
         "vts",
     ],
     srcs: [
-        ":effectCommonFile",
         "TestUtils.cpp",
     ],
 }
 
+cc_defaults {
+    name: "VtsHalAudioEffectTargetTestDefaults",
+    defaults: [
+        "latest_android_hardware_audio_effect_ndk_static",
+        "VtsHalAudioTargetTestDefaults",
+    ],
+    srcs: [
+        ":effectCommonFile",
+    ],
+}
+
 cc_test {
     name: "VtsHalAudioCoreTargetTest",
     defaults: [
@@ -61,30 +72,29 @@
         "VtsHalAudioCoreConfigTargetTest.cpp",
         "VtsHalAudioCoreModuleTargetTest.cpp",
     ],
-    test_config: "VtsHalAudioCoreTargetTest.xml",
 }
 
 cc_test {
     name: "VtsHalAudioEffectFactoryTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalAudioEffectFactoryTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalAudioEffectTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalAudioEffectTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalBassBoostTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalBassBoostTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalDownmixTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalDownmixTargetTest.cpp"],
     shared_libs: [
         "libaudioutils",
@@ -93,79 +103,85 @@
 
 cc_test {
     name: "VtsHalDynamicsProcessingTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     static_libs: ["libaudioaidlranges"],
     srcs: ["VtsHalDynamicsProcessingTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalEnvironmentalReverbTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalEnvironmentalReverbTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalEqualizerTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalEqualizerTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalHapticGeneratorTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalHapticGeneratorTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalLoudnessEnhancerTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalLoudnessEnhancerTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalPresetReverbTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalPresetReverbTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalVirtualizerTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalVirtualizerTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalVisualizerTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalVisualizerTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalVolumeTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalVolumeTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalAECTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalAECTargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalAGC1TargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalAGC1TargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalAGC2TargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalAGC2TargetTest.cpp"],
 }
 
 cc_test {
     name: "VtsHalNSTargetTest",
-    defaults: ["VtsHalAudioTargetTestDefaults"],
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
     srcs: ["VtsHalNSTargetTest.cpp"],
 }
+
+cc_test {
+    name: "VtsHalSpatializerTargetTest",
+    defaults: ["VtsHalAudioEffectTargetTestDefaults"],
+    srcs: ["VtsHalSpatializerTargetTest.cpp"],
+}
diff --git a/audio/aidl/vts/EffectFactoryHelper.h b/audio/aidl/vts/EffectFactoryHelper.h
index a2499fd..ca36655 100644
--- a/audio/aidl/vts/EffectFactoryHelper.h
+++ b/audio/aidl/vts/EffectFactoryHelper.h
@@ -21,6 +21,7 @@
 #include <unordered_map>
 #include <vector>
 
+#include <aidl/Vintf.h>
 #include <android/binder_auto_utils.h>
 
 #include "TestUtils.h"
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index d813554..4a5c537 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -21,6 +21,7 @@
 #include <string>
 #include <type_traits>
 #include <unordered_map>
+#include <utility>
 #include <vector>
 
 #include <Utils.h>
@@ -263,12 +264,11 @@
         return s;
     }
 
-    template <typename T, typename S, Range::Tag R, typename T::Tag tag, typename Functor>
+    template <typename T, typename S, Range::Tag R, typename T::Tag tag>
     static std::set<S> getTestValueSet(
-            std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList,
-            Functor functor) {
+            std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> descList) {
         std::set<S> result;
-        for (const auto& [_, desc] : kFactoryDescList) {
+        for (const auto& [_, desc] : descList) {
             if (desc.capability.range.getTag() == R) {
                 const auto& ranges = desc.capability.range.get<R>();
                 for (const auto& range : ranges) {
@@ -281,6 +281,14 @@
                 }
             }
         }
+        return result;
+    }
+
+    template <typename T, typename S, Range::Tag R, typename T::Tag tag, typename Functor>
+    static std::set<S> getTestValueSet(
+            std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> descList,
+            Functor functor) {
+        auto result = getTestValueSet<T, S, R, tag>(descList);
         return functor(result);
     }
 
diff --git a/audio/aidl/vts/VtsHalAECTargetTest.cpp b/audio/aidl/vts/VtsHalAECTargetTest.cpp
index 39168b1..f972b84 100644
--- a/audio/aidl/vts/VtsHalAECTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAECTargetTest.cpp
@@ -18,7 +18,6 @@
 #include <string>
 #include <unordered_set>
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalAECParamTest"
 #include <android-base/logging.h>
 
diff --git a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
index 6066025..75da589 100644
--- a/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC1TargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalAGC1ParamTest"
 #include <android-base/logging.h>
 
diff --git a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
index 8793e4c..5f57a88 100644
--- a/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAGC2TargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalAGC2ParamTest"
 #include <android-base/logging.h>
 #include <android/binder_enums.h>
diff --git a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
index aaf9ad4..418fedb 100644
--- a/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalAudioEffectTargetTest.cpp
@@ -16,13 +16,11 @@
 
 #define LOG_TAG "VtsHalAudioEffectTargetTest"
 
-#include <chrono>
 #include <memory>
 #include <string>
 #include <vector>
 
 #include <aidl/Gtest.h>
-#include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/effect/IEffect.h>
 #include <aidl/android/hardware/audio/effect/IFactory.h>
 #include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml b/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
similarity index 86%
rename from audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
rename to audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
index 9d3adc1..c92e852 100644
--- a/audio/aidl/vts/VtsHalAudioCoreTargetTest.xml
+++ b/audio/aidl/vts/VtsHalAudioTargetTestTemplate.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Runs VtsHalAudioCoreTargetTest.">
+<configuration description="Runs {MODULE}.">
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-native" />
 
@@ -27,12 +27,12 @@
 
     <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
         <option name="cleanup" value="true" />
-        <option name="push" value="VtsHalAudioCoreTargetTest->/data/local/tmp/VtsHalAudioCoreTargetTest" />
+        <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}" />
     </target_preparer>
 
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
-        <option name="module-name" value="VtsHalAudioCoreTargetTest" />
+        <option name="module-name" value="{MODULE}" />
         <option name="native-test-timeout" value="10m" />
     </test>
 </configuration>
diff --git a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
index 2d9a233..135940d 100644
--- a/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalBassBoostTargetTest.cpp
@@ -14,9 +14,6 @@
  * limitations under the License.
  */
 
-#include <limits.h>
-
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalBassBoostTest"
 #include <android-base/logging.h>
 
diff --git a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
index d7db567..b82bde1 100644
--- a/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalDownmixTargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalDownmixTargetTest"
 #include <android-base/logging.h>
 
@@ -33,6 +32,9 @@
 using android::audio_utils::channels::ChannelMix;
 using android::hardware::audio::common::testing::detail::TestExecutionTracer;
 
+// minimal HAL interface version to run downmix data path test
+constexpr int32_t kMinDataTestHalVersion = 2;
+
 // Testing for enum values
 static const std::vector<Downmix::Type> kTypeValues = {ndk::enum_range<Downmix::Type>().begin(),
                                                        ndk::enum_range<Downmix::Type>().end()};
@@ -229,6 +231,10 @@
 
     void SetUp() override {
         SetUpDownmix(mInputChannelLayout);
+        if (int32_t version;
+            mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
+            GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
+        }
         if (!isLayoutValid(mInputChannelLayout)) {
             GTEST_SKIP() << "Layout not supported \n";
         }
@@ -376,6 +382,10 @@
 
     void SetUp() override {
         SetUpDownmix(mInputChannelLayout);
+        if (int32_t version;
+            mEffect->getInterfaceVersion(&version).isOk() && version < kMinDataTestHalVersion) {
+            GTEST_SKIP() << "Skipping the data test for version: " << version << "\n";
+        }
         if (!isLayoutValid(mInputChannelLayout)) {
             GTEST_SKIP() << "Layout not supported \n";
         }
@@ -419,7 +429,7 @@
         [](const testing::TestParamInfo<DownmixParamTest::ParamType>& info) {
             auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
             std::string type = std::to_string(static_cast<int>(std::get<PARAM_TYPE>(info.param)));
-            std::string name = getPrefix(descriptor) + "_type" + type;
+            std::string name = getPrefix(descriptor) + "_type_" + type;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -435,7 +445,7 @@
         [](const testing::TestParamInfo<DownmixFoldDataTest::ParamType>& info) {
             auto descriptor = std::get<FOLD_INSTANCE_NAME>(info.param).second;
             std::string layout = std::to_string(std::get<FOLD_INPUT_LAYOUT>(info.param));
-            std::string name = getPrefix(descriptor) + "_fold" + "_layout" + layout;
+            std::string name = getPrefix(descriptor) + "_fold_layout_" + layout;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -452,7 +462,7 @@
             auto descriptor = std::get<STRIP_INSTANCE_NAME>(info.param).second;
             std::string layout =
                     std::to_string(static_cast<int>(std::get<STRIP_INPUT_LAYOUT>(info.param)));
-            std::string name = getPrefix(descriptor) + "_strip" + "_layout" + layout;
+            std::string name = getPrefix(descriptor) + "_strip_layout_" + layout;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index 2650f49..3f7a76d 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -18,7 +18,6 @@
 #include <string>
 #include <unordered_set>
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalDynamicsProcessingTest"
 #include <android-base/logging.h>
 
diff --git a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
index 474b361..765c377 100644
--- a/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEnvironmentalReverbTargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalEnvironmentalReverbTest"
 #include <android-base/logging.h>
 
diff --git a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
index 09396d1..76838cef 100644
--- a/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalEqualizerTargetTest.cpp
@@ -15,15 +15,10 @@
  */
 
 #include <algorithm>
-#include <limits>
-#include <map>
-#include <memory>
-#include <optional>
 #include <string>
 #include <vector>
 
 #include <aidl/Gtest.h>
-#include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/effect/IEffect.h>
 #include <aidl/android/hardware/audio/effect/IFactory.h>
 #define LOG_TAG "VtsHalEqualizerTest"
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index 5a32398..d312111 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -18,7 +18,6 @@
 #include <utility>
 #include <vector>
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalHapticGeneratorTargetTest"
 #include <android-base/logging.h>
 #include <android/binder_enums.h>
diff --git a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
index 925f9ec..7f0091f 100644
--- a/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalLoudnessEnhancerTargetTest.cpp
@@ -16,7 +16,6 @@
 
 #include <string>
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalLoudnessEnhancerTest"
 #include <android-base/logging.h>
 
diff --git a/audio/aidl/vts/VtsHalNSTargetTest.cpp b/audio/aidl/vts/VtsHalNSTargetTest.cpp
index 12d56b0..5c13512 100644
--- a/audio/aidl/vts/VtsHalNSTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalNSTargetTest.cpp
@@ -16,7 +16,6 @@
 
 #include <unordered_set>
 
-#include <aidl/Vintf.h>
 #include <aidl/android/hardware/audio/effect/NoiseSuppression.h>
 #define LOG_TAG "VtsHalNSParamTest"
 #include <android-base/logging.h>
diff --git a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
index 57eda09..1453495 100644
--- a/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalPresetReverbTargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalPresetReverbTargetTest"
 #include <android-base/logging.h>
 #include <android/binder_enums.h>
diff --git a/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp b/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp
new file mode 100644
index 0000000..f0b51b9
--- /dev/null
+++ b/audio/aidl/vts/VtsHalSpatializerTargetTest.cpp
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "VtsHalSpatializerTest"
+#include <android-base/logging.h>
+
+#include "EffectHelper.h"
+
+using namespace android;
+
+using aidl::android::hardware::audio::effect::Descriptor;
+using aidl::android::hardware::audio::effect::getEffectTypeUuidSpatializer;
+using aidl::android::hardware::audio::effect::IEffect;
+using aidl::android::hardware::audio::effect::IFactory;
+using aidl::android::hardware::audio::effect::Parameter;
+using aidl::android::hardware::audio::effect::Range;
+using aidl::android::hardware::audio::effect::Spatializer;
+using aidl::android::media::audio::common::HeadTracking;
+using aidl::android::media::audio::common::Spatialization;
+using android::hardware::audio::common::testing::detail::TestExecutionTracer;
+using ::android::internal::ToString;
+
+enum ParamName {
+    PARAM_INSTANCE_NAME,
+    PARAM_SPATIALIZATION_LEVEL,
+    PARAM_SPATIALIZATION_MODE,
+    PARAM_HEADTRACK_SENSORID,
+    PARAM_HEADTRACK_MODE,
+    PARAM_HEADTRACK_CONNECTION_MODE
+};
+
+using SpatializerParamTestParam =
+        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, Spatialization::Level,
+                   Spatialization::Mode, int /* sensor ID */, HeadTracking::Mode,
+                   HeadTracking::ConnectionMode>;
+
+class SpatializerParamTest : public ::testing::TestWithParam<SpatializerParamTestParam>,
+                             public EffectHelper {
+  public:
+    SpatializerParamTest()
+        : mSpatializerParams([&]() {
+              Spatialization::Level level = std::get<PARAM_SPATIALIZATION_LEVEL>(GetParam());
+              Spatialization::Mode mode = std::get<PARAM_SPATIALIZATION_MODE>(GetParam());
+              int sensorId = std::get<PARAM_HEADTRACK_SENSORID>(GetParam());
+              HeadTracking::Mode htMode = std::get<PARAM_HEADTRACK_MODE>(GetParam());
+              HeadTracking::ConnectionMode htConnectMode =
+                      std::get<PARAM_HEADTRACK_CONNECTION_MODE>(GetParam());
+              std::map<Spatializer::Tag, Spatializer> params;
+              params[Spatializer::spatializationLevel] =
+                      Spatializer::make<Spatializer::spatializationLevel>(level);
+              params[Spatializer::spatializationMode] =
+                      Spatializer::make<Spatializer::spatializationMode>(mode);
+              params[Spatializer::headTrackingSensorId] =
+                      Spatializer::make<Spatializer::headTrackingSensorId>(sensorId);
+              params[Spatializer::headTrackingMode] =
+                      Spatializer::make<Spatializer::headTrackingMode>(htMode);
+              params[Spatializer::headTrackingConnectionMode] =
+                      Spatializer::make<Spatializer::headTrackingConnectionMode>(htConnectMode);
+              return params;
+          }()) {
+        std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
+    }
+
+    void SetUp() override {
+        ASSERT_NE(nullptr, mFactory);
+        ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
+
+        Parameter::Specific specific = getDefaultParamSpecific();
+        Parameter::Common common = EffectHelper::createParamCommon(
+                0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
+                kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
+        IEffect::OpenEffectReturn ret;
+        ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
+        ASSERT_NE(nullptr, mEffect);
+    }
+
+    void TearDown() override {
+        ASSERT_NO_FATAL_FAILURE(close(mEffect));
+        ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
+    }
+
+    Parameter::Specific getDefaultParamSpecific() {
+        Spatializer spatializer = Spatializer::make<Spatializer::headTrackingSensorId>(0);
+        Parameter::Specific specific =
+                Parameter::Specific::make<Parameter::Specific::spatializer>(spatializer);
+        return specific;
+    }
+
+    static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
+    std::shared_ptr<IFactory> mFactory;
+    std::shared_ptr<IEffect> mEffect;
+    Descriptor mDescriptor;
+    const std::map<Spatializer::Tag, Spatializer> mSpatializerParams;
+};
+
+TEST_P(SpatializerParamTest, SetAndGetParam) {
+    for (const auto& it : mSpatializerParams) {
+        auto& tag = it.first;
+        auto& spatializer = it.second;
+
+        // validate parameter
+        Descriptor desc;
+        ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
+        const bool valid = isParameterValid<Spatializer, Range::spatializer>(it.second, desc);
+        const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
+
+        // set parameter
+        Parameter expectParam;
+        Parameter::Specific specific;
+        specific.set<Parameter::Specific::spatializer>(spatializer);
+        expectParam.set<Parameter::specific>(specific);
+        EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
+
+        // only get if parameter in range and set success
+        if (expected == EX_NONE) {
+            Parameter getParam;
+            Parameter::Id id;
+            Spatializer::Id spatializerId;
+            spatializerId.set<Spatializer::Id::commonTag>(tag);
+            id.set<Parameter::Id::spatializerTag>(spatializerId);
+            // if set success, then get should match
+            EXPECT_STATUS(expected, mEffect->getParameter(id, &getParam));
+            EXPECT_EQ(expectParam, getParam);
+        }
+    }
+}
+
+std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kDescPair;
+INSTANTIATE_TEST_SUITE_P(
+        SpatializerTest, SpatializerParamTest,
+        ::testing::Combine(
+                testing::ValuesIn(kDescPair = EffectFactoryHelper::getAllEffectDescriptors(
+                                          IFactory::descriptor, getEffectTypeUuidSpatializer())),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  Spatializer, Spatialization::Level, Range::spatializer,
+                                  Spatializer::spatializationLevel>(kDescPair)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  Spatializer, Spatialization::Mode, Range::spatializer,
+                                  Spatializer::spatializationMode>(kDescPair)),
+                testing::ValuesIn(
+                        EffectHelper::getTestValueSet<Spatializer, int, Range::spatializer,
+                                                      Spatializer::headTrackingSensorId>(
+                                kDescPair, EffectHelper::expandTestValueBasic<int>)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  Spatializer, HeadTracking::Mode, Range::spatializer,
+                                  Spatializer::headTrackingMode>(kDescPair)),
+                testing::ValuesIn(EffectHelper::getTestValueSet<
+                                  Spatializer, HeadTracking::ConnectionMode, Range::spatializer,
+                                  Spatializer::headTrackingConnectionMode>(kDescPair))),
+        [](const testing::TestParamInfo<SpatializerParamTest::ParamType>& info) {
+            auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
+            std::string level = ToString(std::get<PARAM_SPATIALIZATION_LEVEL>(info.param));
+            std::string mode = ToString(std::get<PARAM_SPATIALIZATION_MODE>(info.param));
+            std::string sensorId = ToString(std::get<PARAM_HEADTRACK_SENSORID>(info.param));
+            std::string htMode = ToString(std::get<PARAM_HEADTRACK_MODE>(info.param));
+            std::string htConnectMode =
+                    ToString(std::get<PARAM_HEADTRACK_CONNECTION_MODE>(info.param));
+            std::string name = getPrefix(descriptor) + "_sensorID_" + level + "_mode_" + mode +
+                               "_sensorID_" + sensorId + "_HTMode_" + htMode +
+                               "_HTConnectionMode_" + htConnectMode;
+            std::replace_if(
+                    name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
+            return name;
+        });
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SpatializerParamTest);
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    ::testing::UnitTest::GetInstance()->listeners().Append(new TestExecutionTracer());
+    ABinderProcess_setThreadPoolMaxThreadCount(1);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
index 3e39d3a..0c24f90 100644
--- a/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVirtualizerTargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalVirtualizerTest"
 #include <android-base/logging.h>
 
diff --git a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
index 1b8352b..db83715 100644
--- a/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVisualizerTargetTest.cpp
@@ -16,7 +16,6 @@
 
 #include <unordered_set>
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalVisualizerTest"
 #include <android-base/logging.h>
 #include <android/binder_enums.h>
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 257100b..aa2c05f 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-#include <aidl/Vintf.h>
 #define LOG_TAG "VtsHalVolumeTest"
 #include <android-base/logging.h>
 
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index 435c2d6..a48d228 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -27,11 +27,13 @@
     init_rc: ["audiocontrol-default.rc"],
     vintf_fragments: ["audiocontrol-default.xml"],
     vendor: true,
+    defaults: [
+        "latest_android_hardware_audio_common_ndk_shared",
+        "latest_android_hardware_automotive_audiocontrol_ndk_shared",
+    ],
     shared_libs: [
         "android.hardware.audio.common@7.0-enums",
-        "android.hardware.audio.common-V1-ndk",
         "android.frameworks.automotive.powerpolicy-V2-ndk",
-        "android.hardware.automotive.audiocontrol-V3-ndk",
         "libbase",
         "libbinder_ndk",
         "libcutils",
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index e6f4808..5c5917b 100644
--- a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -46,5 +46,5 @@
   void unscheduleTask(String clientId, String scheduleId);
   void unscheduleAllTasks(String clientId);
   boolean isTaskScheduled(String clientId, String scheduleId);
-  List<android.hardware.automotive.remoteaccess.ScheduleInfo> getAllScheduledTasks(String clientId);
+  List<android.hardware.automotive.remoteaccess.ScheduleInfo> getAllPendingScheduledTasks(String clientId);
 }
diff --git a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
index a5d81cf..ec8733a 100644
--- a/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
+++ b/automotive/remoteaccess/aidl_api/android.hardware.automotive.remoteaccess/current/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
@@ -41,4 +41,5 @@
   int count;
   long startTimeInEpochSeconds;
   long periodicInSeconds;
+  const int MAX_TASK_DATA_SIZE_IN_BYTES = 10240;
 }
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
index 9863ed7..f0468c4 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/IRemoteAccess.aidl
@@ -167,6 +167,9 @@
      * {@code scheduleId} for this client exists.
      *
      * <p>Must return {@code EX_ILLEGAL_ARGUMENT} if the task type is not supported.
+     *
+     * <p>Must return {@code EX_ILLEGLA_ARGUMENT} if the scheduleInfo is not valid (e.g. count is
+     * a negative number).
      */
     void scheduleTask(in ScheduleInfo scheduleInfo);
 
@@ -201,5 +204,5 @@
      *
      * <p>The finished scheduled tasks will not be included.
      */
-    List<ScheduleInfo> getAllScheduledTasks(String clientId);
+    List<ScheduleInfo> getAllPendingScheduledTasks(String clientId);
 }
diff --git a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
index 40fba6f..4f2537c 100644
--- a/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
+++ b/automotive/remoteaccess/android/hardware/automotive/remoteaccess/ScheduleInfo.aidl
@@ -21,6 +21,7 @@
 @VintfStability
 @JavaDerive(equals=true, toString=true)
 parcelable ScheduleInfo {
+    const int MAX_TASK_DATA_SIZE_IN_BYTES = 10240;
     /**
      * The ID used to identify the client this schedule is for. This must be one of the
      * preconfigured remote access serverless client ID defined in car service resource
@@ -41,6 +42,8 @@
      * executed. It is not interpreted/parsed by the Android system.
      *
      * <p>This is only used for {@code TaskType.CUSTOM}.
+     *
+     * <p>The data size must be less than {@link MAX_TASK_DATA_SIZE_IN_BYTES}.
      */
     byte[] taskData;
     /**
diff --git a/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
index 9224ebc..7707ee6 100644
--- a/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
+++ b/automotive/remoteaccess/hal/default/fuzzer/fuzzer.cpp
@@ -75,8 +75,9 @@
         return Status::OK;
     }
 
-    Status GetAllScheduledTasks(ClientContext* context, const GetAllScheduledTasksRequest& request,
-                                GetAllScheduledTasksResponse* response) {
+    Status GetAllPendingScheduledTasks(ClientContext* context,
+                                       const GetAllPendingScheduledTasksRequest& request,
+                                       GetAllPendingScheduledTasksResponse* response) {
         return Status::OK;
     }
 
@@ -165,17 +166,19 @@
         return nullptr;
     }
 
-    ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>* AsyncGetAllScheduledTasksRaw(
+    ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*
+    AsyncGetAllPendingScheduledTasksRaw(
             [[maybe_unused]] ClientContext* context,
-            [[maybe_unused]] const GetAllScheduledTasksRequest& request,
+            [[maybe_unused]] const GetAllPendingScheduledTasksRequest& request,
             [[maybe_unused]] CompletionQueue* cq) {
         return nullptr;
     }
 
-    ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*
-    PrepareAsyncGetAllScheduledTasksRaw([[maybe_unused]] ClientContext* context,
-                                        [[maybe_unused]] const GetAllScheduledTasksRequest& request,
-                                        [[maybe_unused]] CompletionQueue* c) {
+    ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*
+    PrepareAsyncGetAllPendingScheduledTasksRaw(
+            [[maybe_unused]] ClientContext* context,
+            [[maybe_unused]] const GetAllPendingScheduledTasksRequest& request,
+            [[maybe_unused]] CompletionQueue* c) {
         return nullptr;
     }
 };
diff --git a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
index 23b4ebe..6266de8 100644
--- a/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
+++ b/automotive/remoteaccess/hal/default/include/RemoteAccessService.h
@@ -96,7 +96,7 @@
     ndk::ScopedAStatus isTaskScheduled(const std::string& clientId, const std::string& scheduleId,
                                        bool* out) override;
 
-    ndk::ScopedAStatus getAllScheduledTasks(
+    ndk::ScopedAStatus getAllPendingScheduledTasks(
             const std::string& clientId,
             std::vector<aidl::android::hardware::automotive::remoteaccess::ScheduleInfo>* out)
             override;
diff --git a/automotive/remoteaccess/hal/default/proto/wakeup_client.proto b/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
index e061016..14ba0a5 100644
--- a/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
+++ b/automotive/remoteaccess/hal/default/proto/wakeup_client.proto
@@ -99,7 +99,8 @@
      *
      * <p>The finished scheduled tasks will not be included.
      */
-    rpc GetAllScheduledTasks(GetAllScheduledTasksRequest) returns (GetAllScheduledTasksResponse) {}
+    rpc GetAllPendingScheduledTasks(GetAllPendingScheduledTasksRequest)
+            returns (GetAllPendingScheduledTasksResponse) {}
 }
 
 message GetRemoteTasksRequest {}
@@ -154,10 +155,10 @@
     bool isTaskScheduled = 1;
 }
 
-message GetAllScheduledTasksRequest {
+message GetAllPendingScheduledTasksRequest {
     string clientId = 1;
 }
 
-message GetAllScheduledTasksResponse {
+message GetAllPendingScheduledTasksResponse {
     repeated GrpcScheduleInfo allScheduledTasks = 1;
 }
diff --git a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
index 5521134..1b42a1f 100644
--- a/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
+++ b/automotive/remoteaccess/hal/default/src/RemoteAccessService.cpp
@@ -331,6 +331,24 @@
     ClientContext context;
     ScheduleTaskRequest request = {};
     ScheduleTaskResponse response = {};
+
+    if (scheduleInfo.count < 0) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                           "count must be >= 0");
+    }
+    if (scheduleInfo.startTimeInEpochSeconds < 0) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                           "startTimeInEpochSeconds must be >= 0");
+    }
+    if (scheduleInfo.periodicInSeconds < 0) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                           "periodicInSeconds must be >= 0");
+    }
+    if (scheduleInfo.taskData.size() > scheduleInfo.MAX_TASK_DATA_SIZE_IN_BYTES) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                           "task data too big");
+    }
+
     request.mutable_scheduleinfo()->set_clientid(scheduleInfo.clientId);
     request.mutable_scheduleinfo()->set_scheduleid(scheduleInfo.scheduleId);
     request.mutable_scheduleinfo()->set_data(scheduleInfo.taskData.data(),
@@ -348,7 +366,8 @@
         case ErrorCode::OK:
             return ScopedAStatus::ok();
         case ErrorCode::INVALID_ARG:
-            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+            return ScopedAStatus::fromExceptionCodeWithMessage(
+                    EX_ILLEGAL_ARGUMENT, "received invalid_arg from grpc server");
         default:
             // Should not happen.
             return ScopedAStatus::fromServiceSpecificErrorWithMessage(
@@ -399,13 +418,13 @@
     return ScopedAStatus::ok();
 }
 
-ScopedAStatus RemoteAccessService::getAllScheduledTasks(const std::string& clientId,
-                                                        std::vector<ScheduleInfo>* out) {
+ScopedAStatus RemoteAccessService::getAllPendingScheduledTasks(const std::string& clientId,
+                                                               std::vector<ScheduleInfo>* out) {
     ClientContext context;
-    GetAllScheduledTasksRequest request = {};
-    GetAllScheduledTasksResponse response = {};
+    GetAllPendingScheduledTasksRequest request = {};
+    GetAllPendingScheduledTasksResponse response = {};
     request.set_clientid(clientId);
-    Status status = mGrpcStub->GetAllScheduledTasks(&context, request, &response);
+    Status status = mGrpcStub->GetAllPendingScheduledTasks(&context, request, &response);
     if (!status.ok()) {
         return rpcStatusToScopedAStatus(status, "Failed to call isTaskScheduled");
     }
diff --git a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
index 4af0003..7992a50 100644
--- a/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
+++ b/automotive/remoteaccess/hal/default/test/RemoteAccessServiceUnitTest.cpp
@@ -95,9 +95,9 @@
     MOCK_METHOD(Status, IsTaskScheduled,
                 (ClientContext * context, const IsTaskScheduledRequest& request,
                  IsTaskScheduledResponse* response));
-    MOCK_METHOD(Status, GetAllScheduledTasks,
-                (ClientContext * context, const GetAllScheduledTasksRequest& request,
-                 GetAllScheduledTasksResponse* response));
+    MOCK_METHOD(Status, GetAllPendingScheduledTasks,
+                (ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
+                 GetAllPendingScheduledTasksResponse* response));
     // Async methods which we do not care.
     MOCK_METHOD(ClientAsyncReaderInterface<GetRemoteTasksResponse>*, AsyncGetRemoteTasksRaw,
                 (ClientContext * context, const GetRemoteTasksRequest& request, CompletionQueue* cq,
@@ -141,13 +141,13 @@
                 PrepareAsyncIsTaskScheduledRaw,
                 (ClientContext * context, const IsTaskScheduledRequest& request,
                  CompletionQueue* cq));
-    MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*,
-                AsyncGetAllScheduledTasksRaw,
-                (ClientContext * context, const GetAllScheduledTasksRequest& request,
+    MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*,
+                AsyncGetAllPendingScheduledTasksRaw,
+                (ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
                  CompletionQueue* cq));
-    MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllScheduledTasksResponse>*,
-                PrepareAsyncGetAllScheduledTasksRaw,
-                (ClientContext * context, const GetAllScheduledTasksRequest& request,
+    MOCK_METHOD(ClientAsyncResponseReaderInterface<GetAllPendingScheduledTasksResponse>*,
+                PrepareAsyncGetAllPendingScheduledTasksRaw,
+                (ClientContext * context, const GetAllPendingScheduledTasksRequest& request,
                  CompletionQueue* cq));
 };
 
@@ -473,7 +473,71 @@
     EXPECT_EQ(grpcRequest.scheduleinfo().periodicinseconds(), kTestPeriodicInSeconds);
 }
 
-TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidArg) {
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidCount) {
+    ScheduleInfo scheduleInfo = {
+            .clientId = kTestClientId,
+            .scheduleId = kTestScheduleId,
+            .taskData = kTestData,
+            .count = -1,
+            .startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
+            .periodicInSeconds = kTestPeriodicInSeconds,
+    };
+
+    ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
+
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidStartTimeInEpochSeconds) {
+    ScheduleInfo scheduleInfo = {
+            .clientId = kTestClientId,
+            .scheduleId = kTestScheduleId,
+            .taskData = kTestData,
+            .count = kTestCount,
+            .startTimeInEpochSeconds = -1,
+            .periodicInSeconds = kTestPeriodicInSeconds,
+    };
+
+    ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
+
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidPeriodicInSeconds) {
+    ScheduleInfo scheduleInfo = {
+            .clientId = kTestClientId,
+            .scheduleId = kTestScheduleId,
+            .taskData = kTestData,
+            .count = kTestCount,
+            .startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
+            .periodicInSeconds = -1,
+    };
+
+    ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
+
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_TaskDataTooLarge) {
+    ScheduleInfo scheduleInfo = {
+            .clientId = kTestClientId,
+            .scheduleId = kTestScheduleId,
+            .taskData = std::vector<uint8_t>(ScheduleInfo::MAX_TASK_DATA_SIZE_IN_BYTES + 1),
+            .count = kTestCount,
+            .startTimeInEpochSeconds = kTestStartTimeInEpochSeconds,
+            .periodicInSeconds = kTestPeriodicInSeconds,
+    };
+
+    ScopedAStatus status = getService()->scheduleTask(scheduleInfo);
+
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(status.getExceptionCode(), EX_ILLEGAL_ARGUMENT);
+}
+
+TEST_F(RemoteAccessServiceUnitTest, TestScheduleTask_InvalidArgFromGrpcServer) {
     EXPECT_CALL(*getGrpcWakeupClientStub(), ScheduleTask)
             .WillOnce([]([[maybe_unused]] ClientContext* context,
                          [[maybe_unused]] const ScheduleTaskRequest& request,
@@ -573,13 +637,13 @@
     EXPECT_EQ(grpcRequest.scheduleid(), kTestScheduleId);
 }
 
-TEST_F(RemoteAccessServiceUnitTest, testGetAllScheduledTasks) {
+TEST_F(RemoteAccessServiceUnitTest, testGetAllPendingScheduledTasks) {
     std::vector<ScheduleInfo> result;
-    GetAllScheduledTasksRequest grpcRequest = {};
-    EXPECT_CALL(*getGrpcWakeupClientStub(), GetAllScheduledTasks)
+    GetAllPendingScheduledTasksRequest grpcRequest = {};
+    EXPECT_CALL(*getGrpcWakeupClientStub(), GetAllPendingScheduledTasks)
             .WillOnce([&grpcRequest]([[maybe_unused]] ClientContext* context,
-                                     const GetAllScheduledTasksRequest& request,
-                                     GetAllScheduledTasksResponse* response) {
+                                     const GetAllPendingScheduledTasksRequest& request,
+                                     GetAllPendingScheduledTasksResponse* response) {
                 grpcRequest = request;
                 GrpcScheduleInfo* newInfo = response->add_allscheduledtasks();
                 newInfo->set_clientid(kTestClientId);
@@ -591,7 +655,7 @@
                 return Status();
             });
 
-    ScopedAStatus status = getService()->getAllScheduledTasks(kTestClientId, &result);
+    ScopedAStatus status = getService()->getAllPendingScheduledTasks(kTestClientId, &result);
 
     ASSERT_TRUE(status.isOk());
     EXPECT_EQ(grpcRequest.clientid(), kTestClientId);
diff --git a/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h b/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
index 2aab904..41cc5d0 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
+++ b/automotive/remoteaccess/test_grpc_server/impl/include/TestWakeupClientServiceImpl.h
@@ -78,6 +78,7 @@
     void waitForTask();
     void stopWait();
     bool isEmpty();
+    bool isStopped();
 
   private:
     friend class TaskTimeoutMessageHandler;
@@ -87,7 +88,7 @@
             GUARDED_BY(mLock);
     // A variable to notify mTasks is not empty.
     std::condition_variable mTasksNotEmptyCv;
-    std::atomic<bool> mStopped;
+    std::atomic<bool> mStopped = false;
     android::sp<Looper> mLooper;
     android::sp<TaskTimeoutMessageHandler> mTaskTimeoutMessageHandler;
     std::atomic<int> mTaskIdCounter = 0;
@@ -138,9 +139,9 @@
                                  const IsTaskScheduledRequest* request,
                                  IsTaskScheduledResponse* response) override;
 
-    grpc::Status GetAllScheduledTasks(grpc::ServerContext* context,
-                                      const GetAllScheduledTasksRequest* request,
-                                      GetAllScheduledTasksResponse* response) override;
+    grpc::Status GetAllPendingScheduledTasks(
+            grpc::ServerContext* context, const GetAllPendingScheduledTasksRequest* request,
+            GetAllPendingScheduledTasksResponse* response) override;
 
     /**
      * Starts generating fake tasks for the specific client repeatedly.
@@ -214,7 +215,7 @@
     std::atomic<bool> mRemoteTaskConnectionAlive = false;
     std::mutex mLock;
     bool mGeneratingFakeTask GUARDED_BY(mLock);
-    std::atomic<bool> mServerStopped;
+    std::atomic<bool> mServerStopped = false;
     std::unordered_map<std::string, std::unordered_map<std::string, ScheduleInfo>>
             mInfoByScheduleIdByClientId GUARDED_BY(mLock);
 
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
index 1db991c..eed3495 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
@@ -105,6 +105,10 @@
     });
 }
 
+bool TaskQueue::isStopped() {
+    return mStopped;
+}
+
 void TaskQueue::stopWait() {
     mStopped = true;
     {
@@ -241,7 +245,7 @@
     while (true) {
         mTaskQueue->waitForTask();
 
-        if (mServerStopped) {
+        if (mTaskQueue->isStopped()) {
             // Server stopped, exit the loop.
             printf("Server stopped exit loop\n");
             break;
@@ -250,11 +254,13 @@
         while (true) {
             auto maybeTask = mTaskQueue->maybePopOne();
             if (!maybeTask.has_value()) {
+                printf("no task left\n");
                 // No task left, loop again and wait for another task(s).
                 break;
             }
             // Loop through all the task in the queue but obtain lock for each element so we don't
             // hold lock while writing the response.
+            printf("Sending one remote task\n");
             const GetRemoteTasksResponse& response = maybeTask.value();
             if (!writer->Write(response)) {
                 // Broken stream, maybe the client is shutting down.
@@ -469,11 +475,11 @@
     return Status::OK;
 }
 
-Status TestWakeupClientServiceImpl::GetAllScheduledTasks(ServerContext* context,
-                                                         const GetAllScheduledTasksRequest* request,
-                                                         GetAllScheduledTasksResponse* response) {
+Status TestWakeupClientServiceImpl::GetAllPendingScheduledTasks(
+        ServerContext* context, const GetAllPendingScheduledTasksRequest* request,
+        GetAllPendingScheduledTasksResponse* response) {
     const std::string& clientId = request->clientid();
-    printf("GetAllScheduledTasks called with client Id: %s\n", clientId.c_str());
+    printf("GetAllPendingScheduledTasks called with client Id: %s\n", clientId.c_str());
     response->clear_allscheduledtasks();
     {
         std::unique_lock lk(mLock);
diff --git a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
index 960020d..63458ae 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
@@ -280,7 +280,7 @@
     EXPECT_EQ(getRemoteTaskResponses().size(), 0);
 }
 
-TEST_F(TestWakeupClientServiceImplUnitTest, TestGetAllScheduledTasks) {
+TEST_F(TestWakeupClientServiceImplUnitTest, TestGetAllPendingScheduledTasks) {
     std::string scheduleId1 = "scheduleId1";
     std::string scheduleId2 = "scheduleId2";
     int64_t time1 = getNow();
@@ -296,19 +296,19 @@
     ASSERT_TRUE(status.ok());
 
     ClientContext context;
-    GetAllScheduledTasksRequest request;
-    GetAllScheduledTasksResponse response;
+    GetAllPendingScheduledTasksRequest request;
+    GetAllPendingScheduledTasksResponse response;
     request.set_clientid("invalid client Id");
-    status = getStub()->GetAllScheduledTasks(&context, request, &response);
+    status = getStub()->GetAllPendingScheduledTasks(&context, request, &response);
 
     ASSERT_TRUE(status.ok());
     EXPECT_EQ(response.allscheduledtasks_size(), 0);
 
     ClientContext context2;
-    GetAllScheduledTasksRequest request2;
-    GetAllScheduledTasksResponse response2;
+    GetAllPendingScheduledTasksRequest request2;
+    GetAllPendingScheduledTasksResponse response2;
     request2.set_clientid(kTestClientId);
-    status = getStub()->GetAllScheduledTasks(&context2, request2, &response2);
+    status = getStub()->GetAllPendingScheduledTasks(&context2, request2, &response2);
 
     ASSERT_TRUE(status.ok());
     ASSERT_EQ(response2.allscheduledtasks_size(), 2);
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
index 69f6190..14469b5 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/SubscribeOptions.aidl
@@ -45,8 +45,8 @@
      *
      * This value indicates the resolution at which continuous property updates should be sent to
      * the platform. For example, if resolution is 0.01, the subscribed property value should be
-     * rounded to two decimal places. If the incoming resolution value is not an integer multiple of
-     * 10, VHAL should return a StatusCode::INVALID_ARG.
+     * rounded to two decimal places. If the incoming resolution value is not an integer power of
+     * 10 (i.e. 10^-2, 10^-1, 10^2, etc.), VHAL should return a StatusCode::INVALID_ARG.
      */
     float resolution = 0.0f;
 
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 e312a3a..6d856a8 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
@@ -1,34 +1,22 @@
 [
   {
-    "name": "VehicleApPowerStateReqIndex",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleOilLevel",
     "values": [
       {
-        "name": "STATE",
+        "name": "CRITICALLY_LOW",
         "value": 0
       },
       {
-        "name": "ADDITIONAL",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "EvChargeState",
-    "values": [
-      {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "CHARGING",
+        "name": "LOW",
         "value": 1
       },
       {
-        "name": "FULLY_CHARGED",
+        "name": "NORMAL",
         "value": 2
       },
       {
-        "name": "NOT_CHARGING",
+        "name": "HIGH",
         "value": 3
       },
       {
@@ -38,220 +26,123 @@
     ]
   },
   {
-    "name": "TrailerState",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "LocationCharacterization",
     "values": [
       {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "NOT_PRESENT",
+        "name": "PRIOR_LOCATIONS",
         "value": 1
       },
       {
-        "name": "PRESENT",
+        "name": "GYROSCOPE_FUSION",
         "value": 2
       },
       {
-        "name": "ERROR",
-        "value": 3
-      }
-    ]
-  },
-  {
-    "name": "ProcessTerminationReason",
-    "values": [
-      {
-        "name": "NOT_RESPONDING",
-        "value": 1
-      },
-      {
-        "name": "IO_OVERUSE",
-        "value": 2
-      },
-      {
-        "name": "MEMORY_OVERUSE",
-        "value": 3
-      }
-    ]
-  },
-  {
-    "name": "VehicleApPowerStateConfigFlag",
-    "values": [
-      {
-        "name": "ENABLE_DEEP_SLEEP_FLAG",
-        "value": 1
-      },
-      {
-        "name": "CONFIG_SUPPORT_TIMER_POWER_ON_FLAG",
-        "value": 2
-      },
-      {
-        "name": "ENABLE_HIBERNATION_FLAG",
-        "value": 3
-      }
-    ]
-  },
-  {
-    "name": "Obd2FuelType",
-    "values": [
-      {
-        "name": "NOT_AVAILABLE",
-        "value": 0
-      },
-      {
-        "name": "GASOLINE",
-        "value": 1
-      },
-      {
-        "name": "METHANOL",
-        "value": 2
-      },
-      {
-        "name": "ETHANOL",
-        "value": 3
-      },
-      {
-        "name": "DIESEL",
+        "name": "ACCELEROMETER_FUSION",
         "value": 4
       },
       {
-        "name": "LPG",
-        "value": 5
-      },
-      {
-        "name": "CNG",
-        "value": 6
-      },
-      {
-        "name": "PROPANE",
-        "value": 7
-      },
-      {
-        "name": "ELECTRIC",
+        "name": "COMPASS_FUSION",
         "value": 8
       },
       {
-        "name": "BIFUEL_RUNNING_GASOLINE",
-        "value": 9
-      },
-      {
-        "name": "BIFUEL_RUNNING_METHANOL",
-        "value": 10
-      },
-      {
-        "name": "BIFUEL_RUNNING_ETHANOL",
-        "value": 11
-      },
-      {
-        "name": "BIFUEL_RUNNING_LPG",
-        "value": 12
-      },
-      {
-        "name": "BIFUEL_RUNNING_CNG",
-        "value": 13
-      },
-      {
-        "name": "BIFUEL_RUNNING_PROPANE",
-        "value": 14
-      },
-      {
-        "name": "BIFUEL_RUNNING_ELECTRIC",
-        "value": 15
-      },
-      {
-        "name": "BIFUEL_RUNNING_ELECTRIC_AND_COMBUSTION",
+        "name": "WHEEL_SPEED_FUSION",
         "value": 16
       },
       {
-        "name": "HYBRID_GASOLINE",
-        "value": 17
+        "name": "STEERING_ANGLE_FUSION",
+        "value": 32
       },
       {
-        "name": "HYBRID_ETHANOL",
-        "value": 18
+        "name": "CAR_SPEED_FUSION",
+        "value": 64
       },
       {
-        "name": "HYBRID_DIESEL",
-        "value": 19
+        "name": "DEAD_RECKONED",
+        "value": 128
       },
       {
-        "name": "HYBRID_ELECTRIC",
-        "value": 20
-      },
-      {
-        "name": "HYBRID_RUNNING_ELECTRIC_AND_COMBUSTION",
-        "value": 21
-      },
-      {
-        "name": "HYBRID_REGENERATIVE",
-        "value": 22
-      },
-      {
-        "name": "BIFUEL_RUNNING_DIESEL",
-        "value": 23
+        "name": "RAW_GNSS_ONLY",
+        "value": 256
       }
     ]
   },
   {
-    "name": "VmsSubscriptionsStateIntegerValuesIndex",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleDisplay",
     "values": [
       {
-        "name": "MESSAGE_TYPE",
+        "name": "MAIN",
         "value": 0
       },
       {
-        "name": "SEQUENCE_NUMBER",
+        "name": "INSTRUMENT_CLUSTER",
         "value": 1
       },
       {
-        "name": "NUMBER_OF_LAYERS",
+        "name": "HUD",
         "value": 2
       },
       {
-        "name": "NUMBER_OF_ASSOCIATED_LAYERS",
+        "name": "INPUT",
         "value": 3
       },
       {
-        "name": "SUBSCRIPTIONS_START",
+        "name": "AUXILIARY",
         "value": 4
       }
     ]
   },
   {
-    "name": "VehicleArea",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "CruiseControlState",
     "values": [
       {
-        "name": "GLOBAL",
-        "value": 16777216
+        "name": "OTHER",
+        "value": 0
       },
       {
-        "name": "WINDOW",
-        "value": 50331648
+        "name": "ENABLED",
+        "value": 1
       },
       {
-        "name": "MIRROR",
-        "value": 67108864
+        "name": "ACTIVATED",
+        "value": 2
       },
       {
-        "name": "SEAT",
-        "value": 83886080
+        "name": "USER_OVERRIDE",
+        "value": 3
       },
       {
-        "name": "DOOR",
-        "value": 100663296
+        "name": "SUSPENDED",
+        "value": 4
       },
       {
-        "name": "WHEEL",
-        "value": 117440512
-      },
-      {
-        "name": "MASK",
-        "value": 251658240
+        "name": "FORCED_DEACTIVATION_WARNING",
+        "value": 5
       }
     ]
   },
   {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "HandsOnDetectionWarning",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "NO_WARNING",
+        "value": 1
+      },
+      {
+        "name": "WARNING",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "VehicleAreaWindow",
     "values": [
       {
@@ -297,27 +188,99 @@
     ]
   },
   {
-    "name": "ElectronicTollCollectionCardStatus",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VmsAvailabilityStateIntegerValuesIndex",
     "values": [
       {
-        "name": "UNKNOWN",
+        "name": "MESSAGE_TYPE",
         "value": 0
       },
       {
-        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_VALID",
+        "name": "SEQUENCE_NUMBER",
         "value": 1
       },
       {
-        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_INVALID",
+        "name": "NUMBER_OF_ASSOCIATED_LAYERS",
         "value": 2
       },
       {
-        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_NOT_INSERTED",
+        "name": "LAYERS_START",
         "value": 3
       }
     ]
   },
   {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleLightSwitch",
+    "values": [
+      {
+        "name": "OFF",
+        "value": 0
+      },
+      {
+        "name": "ON",
+        "value": 1
+      },
+      {
+        "name": "DAYTIME_RUNNING",
+        "value": 2
+      },
+      {
+        "name": "AUTOMATIC",
+        "value": 256
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "Obd2IgnitionMonitorKind",
+    "values": [
+      {
+        "name": "SPARK",
+        "value": 0
+      },
+      {
+        "name": "COMPRESSION",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleHwMotionButtonStateFlag",
+    "values": [
+      {
+        "name": "BUTTON_PRIMARY",
+        "value": 1
+      },
+      {
+        "name": "BUTTON_SECONDARY",
+        "value": 2
+      },
+      {
+        "name": "BUTTON_TERTIARY",
+        "value": 4
+      },
+      {
+        "name": "BUTTON_BACK",
+        "value": 8
+      },
+      {
+        "name": "BUTTON_FORWARD",
+        "value": 16
+      },
+      {
+        "name": "BUTTON_STYLUS_PRIMARY",
+        "value": 32
+      },
+      {
+        "name": "BUTTON_STYLUS_SECONDARY",
+        "value": 64
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "VehiclePropertyType",
     "values": [
       {
@@ -367,1694 +330,7 @@
     ]
   },
   {
-    "name": "StatusCode",
-    "values": [
-      {
-        "name": "OK",
-        "value": 0
-      },
-      {
-        "name": "TRY_AGAIN",
-        "value": 1
-      },
-      {
-        "name": "INVALID_ARG",
-        "value": 2
-      },
-      {
-        "name": "NOT_AVAILABLE",
-        "value": 3
-      },
-      {
-        "name": "ACCESS_DENIED",
-        "value": 4
-      },
-      {
-        "name": "INTERNAL_ERROR",
-        "value": 5
-      }
-    ]
-  },
-  {
-    "name": "CreateUserStatus",
-    "values": [
-      {
-        "name": "SUCCESS",
-        "value": 1
-      },
-      {
-        "name": "FAILURE",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "ElectronicTollCollectionCardType",
-    "values": [
-      {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD",
-        "value": 1
-      },
-      {
-        "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "VehicleAreaMirror",
-    "values": [
-      {
-        "name": "DRIVER_LEFT",
-        "value": 1
-      },
-      {
-        "name": "DRIVER_RIGHT",
-        "value": 2
-      },
-      {
-        "name": "DRIVER_CENTER",
-        "value": 4
-      }
-    ]
-  },
-  {
-    "name": "InitialUserInfoResponseAction",
-    "values": [
-      {
-        "name": "DEFAULT",
-        "value": 0
-      },
-      {
-        "name": "SWITCH",
-        "value": 1
-      },
-      {
-        "name": "CREATE",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "VehicleHvacFanDirection",
-    "values": [
-      {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "FACE",
-        "value": 1
-      },
-      {
-        "name": "FLOOR",
-        "value": 2
-      },
-      {
-        "name": "FACE_AND_FLOOR",
-        "value": 3
-      },
-      {
-        "name": "DEFROST",
-        "value": 4
-      },
-      {
-        "name": "DEFROST_AND_FLOOR",
-        "value": 6
-      }
-    ]
-  },
-  {
-    "name": "Obd2SecondaryAirStatus",
-    "values": [
-      {
-        "name": "UPSTREAM",
-        "value": 1
-      },
-      {
-        "name": "DOWNSTREAM_OF_CATALYCIC_CONVERTER",
-        "value": 2
-      },
-      {
-        "name": "FROM_OUTSIDE_OR_OFF",
-        "value": 4
-      },
-      {
-        "name": "PUMP_ON_FOR_DIAGNOSTICS",
-        "value": 8
-      }
-    ]
-  },
-  {
-    "name": "VmsStartSessionMessageIntegerValuesIndex",
-    "values": [
-      {
-        "name": "MESSAGE_TYPE",
-        "value": 0
-      },
-      {
-        "name": "SERVICE_ID",
-        "value": 1
-      },
-      {
-        "name": "CLIENT_ID",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "VehicleOilLevel",
-    "values": [
-      {
-        "name": "CRITICALLY_LOW",
-        "value": 0
-      },
-      {
-        "name": "LOW",
-        "value": 1
-      },
-      {
-        "name": "NORMAL",
-        "value": 2
-      },
-      {
-        "name": "HIGH",
-        "value": 3
-      },
-      {
-        "name": "ERROR",
-        "value": 4
-      }
-    ]
-  },
-  {
-    "name": "VehicleUnit",
-    "values": [
-      {
-        "name": "SHOULD_NOT_USE",
-        "value": 0
-      },
-      {
-        "name": "METER_PER_SEC",
-        "value": 1
-      },
-      {
-        "name": "RPM",
-        "value": 2
-      },
-      {
-        "name": "HERTZ",
-        "value": 3
-      },
-      {
-        "name": "PERCENTILE",
-        "value": 16
-      },
-      {
-        "name": "MILLIMETER",
-        "value": 32
-      },
-      {
-        "name": "METER",
-        "value": 33
-      },
-      {
-        "name": "KILOMETER",
-        "value": 35
-      },
-      {
-        "name": "MILE",
-        "value": 36
-      },
-      {
-        "name": "CELSIUS",
-        "value": 48
-      },
-      {
-        "name": "FAHRENHEIT",
-        "value": 49
-      },
-      {
-        "name": "KELVIN",
-        "value": 50
-      },
-      {
-        "name": "MILLILITER",
-        "value": 64
-      },
-      {
-        "name": "LITER",
-        "value": 65
-      },
-      {
-        "name": "GALLON",
-        "value": 66
-      },
-      {
-        "name": "US_GALLON",
-        "value": 66
-      },
-      {
-        "name": "IMPERIAL_GALLON",
-        "value": 67
-      },
-      {
-        "name": "NANO_SECS",
-        "value": 80
-      },
-      {
-        "name": "SECS",
-        "value": 83
-      },
-      {
-        "name": "YEAR",
-        "value": 89
-      },
-      {
-        "name": "WATT_HOUR",
-        "value": 96
-      },
-      {
-        "name": "MILLIAMPERE",
-        "value": 97
-      },
-      {
-        "name": "MILLIVOLT",
-        "value": 98
-      },
-      {
-        "name": "MILLIWATTS",
-        "value": 99
-      },
-      {
-        "name": "AMPERE_HOURS",
-        "value": 100
-      },
-      {
-        "name": "KILOWATT_HOUR",
-        "value": 101
-      },
-      {
-        "name": "AMPERE",
-        "value": 102
-      },
-      {
-        "name": "KILOPASCAL",
-        "value": 112
-      },
-      {
-        "name": "PSI",
-        "value": 113
-      },
-      {
-        "name": "BAR",
-        "value": 114
-      },
-      {
-        "name": "DEGREES",
-        "value": 128
-      },
-      {
-        "name": "MILES_PER_HOUR",
-        "value": 144
-      },
-      {
-        "name": "KILOMETERS_PER_HOUR",
-        "value": 145
-      }
-    ]
-  },
-  {
-    "name": "VehicleAreaWheel",
-    "values": [
-      {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "LEFT_FRONT",
-        "value": 1
-      },
-      {
-        "name": "RIGHT_FRONT",
-        "value": 2
-      },
-      {
-        "name": "LEFT_REAR",
-        "value": 4
-      },
-      {
-        "name": "RIGHT_REAR",
-        "value": 8
-      }
-    ]
-  },
-  {
-    "name": "EvsServiceState",
-    "values": [
-      {
-        "name": "OFF",
-        "value": 0
-      },
-      {
-        "name": "ON",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "EvsServiceRequestIndex",
-    "values": [
-      {
-        "name": "TYPE",
-        "value": 0
-      },
-      {
-        "name": "STATE",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "VehicleSeatOccupancyState",
-    "values": [
-      {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "VACANT",
-        "value": 1
-      },
-      {
-        "name": "OCCUPIED",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "VehicleProperty",
-    "values": [
-      {
-        "name": "Undefined property.",
-        "value": 0
-      },
-      {
-        "name": "VIN of vehicle",
-        "value": 286261504,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Manufacturer of vehicle",
-        "value": 286261505,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Model of vehicle",
-        "value": 286261506,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Model year of vehicle.",
-        "value": 289407235,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:YEAR"
-      },
-      {
-        "name": "Fuel capacity of the vehicle in milliliters",
-        "value": 291504388,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:MILLILITER"
-      },
-      {
-        "name": "List of fuels the vehicle may use",
-        "value": 289472773,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "FuelType"
-      },
-      {
-        "name": "INFO_EV_BATTERY_CAPACITY",
-        "value": 291504390,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:WH"
-      },
-      {
-        "name": "List of connectors this EV may use",
-        "value": 289472775,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "data_enum": "EvConnectorType",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Fuel door location",
-        "value": 289407240,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "data_enum": "PortLocationType",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "EV port location",
-        "value": 289407241,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "PortLocationType"
-      },
-      {
-        "name": "INFO_DRIVER_SEAT",
-        "value": 356516106,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "data_enum": "VehicleAreaSeat",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Exterior dimensions of vehicle.",
-        "value": 289472779,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:MILLIMETER"
-      },
-      {
-        "name": "Multiple EV port locations",
-        "value": 289472780,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "PortLocationType"
-      },
-      {
-        "name": "Current odometer value of the vehicle",
-        "value": 291504644,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:KILOMETER"
-      },
-      {
-        "name": "Speed of the vehicle",
-        "value": 291504647,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:METER_PER_SEC"
-      },
-      {
-        "name": "Speed of the vehicle for displays",
-        "value": 291504648,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:METER_PER_SEC"
-      },
-      {
-        "name": "Front bicycle model steering angle for vehicle",
-        "value": 291504649,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:DEGREES"
-      },
-      {
-        "name": "Rear bicycle model steering angle for vehicle",
-        "value": 291504656,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:DEGREES"
-      },
-      {
-        "name": "Temperature of engine coolant",
-        "value": 291504897,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:CELSIUS"
-      },
-      {
-        "name": "Engine oil level",
-        "value": 289407747,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleOilLevel"
-      },
-      {
-        "name": "Temperature of engine oil",
-        "value": 291504900,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:CELSIUS"
-      },
-      {
-        "name": "Engine rpm",
-        "value": 291504901,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:RPM"
-      },
-      {
-        "name": "Reports wheel ticks",
-        "value": 290521862,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "FUEL_LEVEL",
-        "value": 291504903,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:MILLILITER"
-      },
-      {
-        "name": "Fuel door open",
-        "value": 287310600,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "EV_BATTERY_LEVEL",
-        "value": 291504905,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:WH"
-      },
-      {
-        "name": "EV charge port open",
-        "value": 287310602,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "EV charge port connected",
-        "value": 287310603,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "EV instantaneous charge rate in milliwatts",
-        "value": 291504908,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:MW"
-      },
-      {
-        "name": "Range remaining",
-        "value": 291504904,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "unit": "VehicleUnit:METER"
-      },
-      {
-        "name": "Tire pressure",
-        "value": 392168201,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:KILOPASCAL"
-      },
-      {
-        "name": "Critically low tire pressure",
-        "value": 392168202,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:KILOPASCAL"
-      },
-      {
-        "name": "Currently selected gear",
-        "value": 289408000,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleGear"
-      },
-      {
-        "name": "CURRENT_GEAR",
-        "value": 289408001,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleGear"
-      },
-      {
-        "name": "Parking brake state.",
-        "value": 287310850,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "PARKING_BRAKE_AUTO_APPLY",
-        "value": 287310851,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Warning for fuel low level.",
-        "value": 287310853,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Night mode",
-        "value": 287310855,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "State of the vehicles turn signals",
-        "value": 289408008,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleTurnSignal"
-      },
-      {
-        "name": "Represents ignition state",
-        "value": 289408009,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleIgnitionState"
-      },
-      {
-        "name": "ABS is active",
-        "value": 287310858,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Traction Control is active",
-        "value": 287310859,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "HVAC_FAN_SPEED",
-        "value": 356517120
-      },
-      {
-        "name": "Fan direction setting",
-        "value": 356517121,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleHvacFanDirection"
-      },
-      {
-        "name": "HVAC current temperature.",
-        "value": 358614274,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:CELSIUS"
-      },
-      {
-        "name": "HVAC_TEMPERATURE_SET",
-        "value": 358614275,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "unit": "VehicleUnit:CELSIUS"
-      },
-      {
-        "name": "HVAC_DEFROSTER",
-        "value": 320865540,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "HVAC_AC_ON",
-        "value": 354419973,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "config_flags": "Supported"
-      },
-      {
-        "name": "HVAC_MAX_AC_ON",
-        "value": 354419974,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "HVAC_MAX_DEFROST_ON",
-        "value": 354419975,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "HVAC_RECIRC_ON",
-        "value": 354419976,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Enable temperature coupling between areas.",
-        "value": 354419977,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "HVAC_AUTO_ON",
-        "value": 354419978,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "HVAC_SEAT_TEMPERATURE",
-        "value": 356517131,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Side Mirror Heat",
-        "value": 339739916,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "HVAC_STEERING_WHEEL_HEAT",
-        "value": 289408269,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Temperature units for display",
-        "value": 289408270,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleUnit"
-      },
-      {
-        "name": "Actual fan speed",
-        "value": 356517135,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "HVAC_POWER_ON",
-        "value": 354419984,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Fan Positions Available",
-        "value": 356582673,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleHvacFanDirection"
-      },
-      {
-        "name": "HVAC_AUTO_RECIRC_ON",
-        "value": 354419986,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat ventilation",
-        "value": 356517139,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "HVAC_ELECTRIC_DEFROSTER_ON",
-        "value": 320865556,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Suggested values for setting HVAC temperature.",
-        "value": 291570965,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Distance units for display",
-        "value": 289408512,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleUnit"
-      },
-      {
-        "name": "Fuel volume units for display",
-        "value": 289408513,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleUnit"
-      },
-      {
-        "name": "Tire pressure units for display",
-        "value": 289408514,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleUnit"
-      },
-      {
-        "name": "EV battery units for display",
-        "value": 289408515,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleUnit"
-      },
-      {
-        "name": "Fuel consumption units for display",
-        "value": 287311364,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Speed units for display",
-        "value": 289408517,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "ANDROID_EPOCH_TIME",
-        "value": 290457094,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE_ONLY",
-        "unit": "VehicleUnit:MILLI_SECS"
-      },
-      {
-        "name": "External encryption binding seed.",
-        "value": 292554247,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Outside temperature",
-        "value": 291505923,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:CELSIUS"
-      },
-      {
-        "name": "Property to control power state of application processor",
-        "value": 289475072,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Property to report power state of application processor",
-        "value": 289475073,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "AP_POWER_BOOTUP_REASON",
-        "value": 289409538,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "DISPLAY_BRIGHTNESS",
-        "value": 289409539,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "HW_KEY_INPUT",
-        "value": 289475088,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "config_flags": ""
-      },
-      {
-        "name": "HW_ROTARY_INPUT",
-        "value": 289475104,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "data_enum": "RotaryInputType",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Defines a custom OEM partner input event.",
-        "value": 289475120,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "data_enum": "CustomInputType",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "DOOR_POS",
-        "value": 373295872,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Door move",
-        "value": 373295873,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Door lock",
-        "value": 371198722,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Mirror Z Position",
-        "value": 339741504,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Mirror Z Move",
-        "value": 339741505,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Mirror Y Position",
-        "value": 339741506,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Mirror Y Move",
-        "value": 339741507,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Mirror Lock",
-        "value": 287312708,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Mirror Fold",
-        "value": 287312709,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat memory select",
-        "value": 356518784,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "Seat memory set",
-        "value": 356518785,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "Seatbelt buckled",
-        "value": 354421634,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seatbelt height position",
-        "value": 356518787,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seatbelt height move",
-        "value": 356518788,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "SEAT_FORE_AFT_POS",
-        "value": 356518789,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "SEAT_FORE_AFT_MOVE",
-        "value": 356518790,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat backrest angle 1 position",
-        "value": 356518791,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat backrest angle 1 move",
-        "value": 356518792,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat backrest angle 2 position",
-        "value": 356518793,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat backrest angle 2 move",
-        "value": 356518794,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat height position",
-        "value": 356518795,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat height move",
-        "value": 356518796,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat depth position",
-        "value": 356518797,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat depth move",
-        "value": 356518798,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat tilt position",
-        "value": 356518799,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat tilt move",
-        "value": 356518800,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "SEAT_LUMBAR_FORE_AFT_POS",
-        "value": 356518801,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "SEAT_LUMBAR_FORE_AFT_MOVE",
-        "value": 356518802,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Lumbar side support position",
-        "value": 356518803,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Lumbar side support move",
-        "value": 356518804,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Headrest height position",
-        "value": 289409941,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Headrest height move",
-        "value": 356518806,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Headrest angle position",
-        "value": 356518807,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Headrest angle move",
-        "value": 356518808,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "SEAT_HEADREST_FORE_AFT_POS",
-        "value": 356518809,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "SEAT_HEADREST_FORE_AFT_MOVE",
-        "value": 356518810,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Seat Occupancy",
-        "value": 356518832,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleSeatOccupancyState"
-      },
-      {
-        "name": "Window Position",
-        "value": 322964416,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Window Move",
-        "value": 322964417,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Window Lock",
-        "value": 320867268,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "VEHICLE_MAP_SERVICE",
-        "value": 299895808,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "OBD2 Live Sensor Data",
-        "value": 299896064,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "OBD2 Freeze Frame Sensor Data",
-        "value": 299896065,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "OBD2 Freeze Frame Information",
-        "value": 299896066,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "OBD2 Freeze Frame Clear",
-        "value": 299896067,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "Headlights State",
-        "value": 289410560,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleLightState"
-      },
-      {
-        "name": "High beam lights state",
-        "value": 289410561,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleLightState"
-      },
-      {
-        "name": "Fog light state",
-        "value": 289410562,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleLightState"
-      },
-      {
-        "name": "Hazard light status",
-        "value": 289410563,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleLightState"
-      },
-      {
-        "name": "Headlight switch",
-        "value": 289410576,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleLightSwitch"
-      },
-      {
-        "name": "High beam light switch",
-        "value": 289410577,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleLightSwitch"
-      },
-      {
-        "name": "Fog light switch",
-        "value": 289410578,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleLightSwitch"
-      },
-      {
-        "name": "Hazard light switch",
-        "value": 289410579,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleLightSwitch"
-      },
-      {
-        "name": "Cabin lights",
-        "value": 289410817,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleLightState"
-      },
-      {
-        "name": "Cabin lights switch",
-        "value": 289410818,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleLightSwitch"
-      },
-      {
-        "name": "Reading lights",
-        "value": 356519683,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleLightState"
-      },
-      {
-        "name": "Reading lights switch",
-        "value": 356519684,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleLightSwitch"
-      },
-      {
-        "name": "Support customize permissions for vendor properties",
-        "value": 287313669,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Allow disabling optional featurs from vhal.",
-        "value": 286265094,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Defines the initial Android user to be used during initialization.",
-        "value": 299896583,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Defines a request to switch the foreground Android user.",
-        "value": 299896584,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Called by the Android System after an Android user was created.",
-        "value": 299896585,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Called by the Android System after an Android user was removed.",
-        "value": 299896586,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "USER_IDENTIFICATION_ASSOCIATION",
-        "value": 299896587,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "EVS_SERVICE_REQUEST",
-        "value": 289476368,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Defines a request to apply power policy.",
-        "value": 286265121,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "POWER_POLICY_GROUP_REQ",
-        "value": 286265122,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Notifies the current power policy to VHAL layer.",
-        "value": 286265123,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "WATCHDOG_ALIVE",
-        "value": 290459441,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "Defines a process terminated by car watchdog and the reason of termination.",
-        "value": 299896626,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "Defines an event that VHAL signals to car watchdog as a heartbeat.",
-        "value": 290459443,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Starts the ClusterUI in cluster display.",
-        "value": 289410868,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Changes the state of the cluster display.",
-        "value": 289476405,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ"
-      },
-      {
-        "name": "Reports the current display state and ClusterUI state.",
-        "value": 299896630,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "Requests to change the cluster display state to show some ClusterUI.",
-        "value": 289410871,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "Informs the current navigation state.",
-        "value": 292556600,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:WRITE"
-      },
-      {
-        "name": "Electronic Toll Collection card type.",
-        "value": 289410873,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "ElectronicTollCollectionCardType"
-      },
-      {
-        "name": "Electronic Toll Collection card status.",
-        "value": 289410874,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "ElectronicTollCollectionCardStatus"
-      },
-      {
-        "name": "Front fog lights state",
-        "value": 289410875,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleLightState"
-      },
-      {
-        "name": "Front fog lights switch",
-        "value": 289410876,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleLightSwitch"
-      },
-      {
-        "name": "Rear fog lights state",
-        "value": 289410877,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "VehicleLightState"
-      },
-      {
-        "name": "Rear fog lights switch",
-        "value": 289410878,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "data_enum": "VehicleLightSwitch"
-      },
-      {
-        "name": "Indicates the maximum current draw threshold for charging set by the user",
-        "value": 291508031,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE",
-        "unit": "VehicleUnit:AMPERE"
-      },
-      {
-        "name": "Indicates the maximum charge percent threshold set by the user",
-        "value": 291508032,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Charging state of the car",
-        "value": 289410881,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "EvChargeState"
-      },
-      {
-        "name": "Start or stop charging the EV battery",
-        "value": 287313730,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ_WRITE"
-      },
-      {
-        "name": "Estimated charge time remaining in seconds",
-        "value": 289410883,
-        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:SECS"
-      },
-      {
-        "name": "EV_REGENERATIVE_BRAKING_STATE",
-        "value": 289410884,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "EvRegenerativeBrakingState"
-      },
-      {
-        "name": "Indicates if there is a trailer present or not.",
-        "value": 289410885,
-        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
-        "access": "VehiclePropertyAccess:READ",
-        "data_enum": "TrailerState"
-      },
-      {
-        "name": "VEHICLE_CURB_WEIGHT",
-        "value": 289410886,
-        "change_mode": "VehiclePropertyChangeMode:STATIC",
-        "access": "VehiclePropertyAccess:READ",
-        "unit": "VehicleUnit:KILOGRAM"
-      }
-    ]
-  },
-  {
-    "name": "EvsServiceType",
-    "values": [
-      {
-        "name": "REARVIEW",
-        "value": 0
-      },
-      {
-        "name": "SURROUNDVIEW",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "VehiclePropertyChangeMode",
-    "values": [
-      {
-        "name": "STATIC",
-        "value": 0
-      },
-      {
-        "name": "ON_CHANGE",
-        "value": 1
-      },
-      {
-        "name": "CONTINUOUS",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "Obd2CompressionIgnitionMonitors",
-    "values": []
-  },
-  {
-    "name": "VehicleLightState",
-    "values": [
-      {
-        "name": "OFF",
-        "value": 0
-      },
-      {
-        "name": "ON",
-        "value": 1
-      },
-      {
-        "name": "DAYTIME_RUNNING",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "SwitchUserMessageType",
-    "values": [
-      {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "LEGACY_ANDROID_SWITCH",
-        "value": 1
-      },
-      {
-        "name": "ANDROID_SWITCH",
-        "value": 2
-      },
-      {
-        "name": "VEHICLE_RESPONSE",
-        "value": 3
-      },
-      {
-        "name": "VEHICLE_REQUEST",
-        "value": 4
-      },
-      {
-        "name": "ANDROID_POST_SWITCH",
-        "value": 5
-      }
-    ]
-  },
-  {
-    "name": "PortLocationType",
-    "values": [
-      {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "FRONT_LEFT",
-        "value": 1
-      },
-      {
-        "name": "FRONT_RIGHT",
-        "value": 2
-      },
-      {
-        "name": "REAR_RIGHT",
-        "value": 3
-      },
-      {
-        "name": "REAR_LEFT",
-        "value": 4
-      },
-      {
-        "name": "FRONT",
-        "value": 5
-      },
-      {
-        "name": "REAR",
-        "value": 6
-      }
-    ]
-  },
-  {
-    "name": "VehiclePropertyStatus",
-    "values": [
-      {
-        "name": "AVAILABLE",
-        "value": 0
-      },
-      {
-        "name": "UNAVAILABLE",
-        "value": 1
-      },
-      {
-        "name": "ERROR",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "VehicleDisplay",
-    "values": [
-      {
-        "name": "MAIN",
-        "value": 0
-      },
-      {
-        "name": "INSTRUMENT_CLUSTER",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "SwitchUserStatus",
-    "values": [
-      {
-        "name": "SUCCESS",
-        "value": 1
-      },
-      {
-        "name": "FAILURE",
-        "value": 2
-      }
-    ]
-  },
-  {
-    "name": "InitialUserInfoRequestType",
-    "values": [
-      {
-        "name": "UNKNOWN",
-        "value": 0
-      },
-      {
-        "name": "FIRST_BOOT",
-        "value": 1
-      },
-      {
-        "name": "FIRST_BOOT_AFTER_OTA",
-        "value": 2
-      },
-      {
-        "name": "COLD_BOOT",
-        "value": 3
-      },
-      {
-        "name": "RESUME",
-        "value": 4
-      }
-    ]
-  },
-  {
-    "name": "UserIdentificationAssociationSetValue",
-    "values": [
-      {
-        "name": "INVALID",
-        "value": 0
-      },
-      {
-        "name": "ASSOCIATE_CURRENT_USER",
-        "value": 1
-      },
-      {
-        "name": "DISASSOCIATE_CURRENT_USER",
-        "value": 2
-      },
-      {
-        "name": "DISASSOCIATE_ALL_USERS",
-        "value": 3
-      }
-    ]
-  },
-  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "VehicleAreaDoor",
     "values": [
       {
@@ -2092,250 +368,477 @@
     ]
   },
   {
-    "name": "VehicleLightSwitch",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleApPowerBootupReason",
     "values": [
       {
-        "name": "OFF",
+        "name": "USER_POWER_ON",
         "value": 0
       },
       {
-        "name": "ON",
+        "name": "SYSTEM_USER_DETECTION",
         "value": 1
       },
       {
-        "name": "DAYTIME_RUNNING",
+        "name": "SYSTEM_REMOTE_ACCESS",
         "value": 2
-      },
-      {
-        "name": "AUTOMATIC",
-        "value": 256
       }
     ]
   },
   {
-    "name": "VehicleGear",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "EmergencyLaneKeepAssistState",
     "values": [
       {
-        "name": "GEAR_UNKNOWN",
+        "name": "OTHER",
         "value": 0
       },
       {
-        "name": "GEAR_NEUTRAL",
+        "name": "ENABLED",
         "value": 1
       },
       {
-        "name": "GEAR_REVERSE",
+        "name": "WARNING_LEFT",
         "value": 2
       },
       {
-        "name": "GEAR_PARK",
-        "value": 4
-      },
-      {
-        "name": "GEAR_DRIVE",
-        "value": 8
-      },
-      {
-        "name": "GEAR_1",
-        "value": 16
-      },
-      {
-        "name": "GEAR_2",
-        "value": 32
-      },
-      {
-        "name": "GEAR_3",
-        "value": 64
-      },
-      {
-        "name": "GEAR_4",
-        "value": 128
-      },
-      {
-        "name": "GEAR_5",
-        "value": 256
-      },
-      {
-        "name": "GEAR_6",
-        "value": 512
-      },
-      {
-        "name": "GEAR_7",
-        "value": 1024
-      },
-      {
-        "name": "GEAR_8",
-        "value": 2048
-      },
-      {
-        "name": "GEAR_9",
-        "value": 4096
-      }
-    ]
-  },
-  {
-    "name": "Obd2IgnitionMonitorKind",
-    "values": [
-      {
-        "name": "SPARK",
-        "value": 0
-      },
-      {
-        "name": "COMPRESSION",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "CustomInputType",
-    "values": [
-      {
-        "name": "CUSTOM_EVENT_F1",
-        "value": 1001
-      },
-      {
-        "name": "CUSTOM_EVENT_F2",
-        "value": 1002
-      },
-      {
-        "name": "CUSTOM_EVENT_F3",
-        "value": 1003
-      },
-      {
-        "name": "CUSTOM_EVENT_F4",
-        "value": 1004
-      },
-      {
-        "name": "CUSTOM_EVENT_F5",
-        "value": 1005
-      },
-      {
-        "name": "CUSTOM_EVENT_F6",
-        "value": 1006
-      },
-      {
-        "name": "CUSTOM_EVENT_F7",
-        "value": 1007
-      },
-      {
-        "name": "CUSTOM_EVENT_F8",
-        "value": 1008
-      },
-      {
-        "name": "CUSTOM_EVENT_F9",
-        "value": 1009
-      },
-      {
-        "name": "CUSTOM_EVENT_F10",
-        "value": 1010
-      }
-    ]
-  },
-  {
-    "name": "VehicleApPowerStateReport",
-    "values": [
-      {
-        "name": "WAIT_FOR_VHAL",
-        "value": 1
-      },
-      {
-        "name": "DEEP_SLEEP_ENTRY",
-        "value": 2
-      },
-      {
-        "name": "DEEP_SLEEP_EXIT",
+        "name": "WARNING_RIGHT",
         "value": 3
       },
       {
-        "name": "SHUTDOWN_POSTPONE",
+        "name": "ACTIVATED_STEER_LEFT",
         "value": 4
       },
       {
-        "name": "SHUTDOWN_START",
+        "name": "ACTIVATED_STEER_RIGHT",
         "value": 5
       },
       {
-        "name": "ON",
+        "name": "USER_OVERRIDE",
         "value": 6
-      },
-      {
-        "name": "SHUTDOWN_PREPARE",
-        "value": 7
-      },
-      {
-        "name": "SHUTDOWN_CANCELLED",
-        "value": 8
-      },
-      {
-        "name": "HIBERNATION_ENTRY",
-        "value": 9
-      },
-      {
-        "name": "HIBERNATION_EXIT",
-        "value": 10
       }
     ]
   },
   {
-    "name": "VmsMessageWithLayerIntegerValuesIndex",
-    "values": [
-      {
-        "name": "MESSAGE_TYPE",
-        "value": 0
-      },
-      {
-        "name": "LAYER_TYPE",
-        "value": 1
-      },
-      {
-        "name": "LAYER_SUBTYPE",
-        "value": 2
-      },
-      {
-        "name": "LAYER_VERSION",
-        "value": 3
-      }
-    ]
-  },
-  {
-    "name": "EvRegenerativeBrakingState",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "EvConnectorType",
     "values": [
       {
         "name": "UNKNOWN",
         "value": 0
       },
       {
-        "name": "DISABLED",
+        "name": "IEC_TYPE_1_AC",
         "value": 1
       },
       {
-        "name": "PARTIALLY_ENABLED",
+        "name": "IEC_TYPE_2_AC",
         "value": 2
       },
       {
-        "name": "FULLY_ENABLED",
+        "name": "IEC_TYPE_3_AC",
         "value": 3
+      },
+      {
+        "name": "IEC_TYPE_4_DC",
+        "value": 4
+      },
+      {
+        "name": "IEC_TYPE_1_CCS_DC",
+        "value": 5
+      },
+      {
+        "name": "IEC_TYPE_2_CCS_DC",
+        "value": 6
+      },
+      {
+        "name": "TESLA_ROADSTER",
+        "value": 7
+      },
+      {
+        "name": "TESLA_HPWC",
+        "value": 8
+      },
+      {
+        "name": "TESLA_SUPERCHARGER",
+        "value": 9
+      },
+      {
+        "name": "GBT_AC",
+        "value": 10
+      },
+      {
+        "name": "GBT_DC",
+        "value": 11
+      },
+      {
+        "name": "OTHER",
+        "value": 101
       }
     ]
   },
   {
-    "name": "VehiclePropertyGroup",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "UserIdentificationAssociationType",
     "values": [
       {
-        "name": "SYSTEM",
-        "value": 268435456
+        "name": "INVALID",
+        "value": 0
       },
       {
-        "name": "VENDOR",
-        "value": 536870912
+        "name": "KEY_FOB",
+        "value": 1
       },
       {
-        "name": "MASK",
-        "value": 4026531840
+        "name": "CUSTOM_1",
+        "value": 101
+      },
+      {
+        "name": "CUSTOM_2",
+        "value": 102
+      },
+      {
+        "name": "CUSTOM_3",
+        "value": 103
+      },
+      {
+        "name": "CUSTOM_4",
+        "value": 104
       }
     ]
   },
   {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleHvacFanDirection",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "FACE",
+        "value": 1
+      },
+      {
+        "name": "FLOOR",
+        "value": 2
+      },
+      {
+        "name": "FACE_AND_FLOOR",
+        "value": 3
+      },
+      {
+        "name": "DEFROST",
+        "value": 4
+      },
+      {
+        "name": "DEFROST_AND_FLOOR",
+        "value": 6
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleAreaWheel",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "LEFT_FRONT",
+        "value": 1
+      },
+      {
+        "name": "RIGHT_FRONT",
+        "value": 2
+      },
+      {
+        "name": "LEFT_REAR",
+        "value": 4
+      },
+      {
+        "name": "RIGHT_REAR",
+        "value": 8
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "InitialUserInfoRequestType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "FIRST_BOOT",
+        "value": 1
+      },
+      {
+        "name": "FIRST_BOOT_AFTER_OTA",
+        "value": 2
+      },
+      {
+        "name": "COLD_BOOT",
+        "value": 3
+      },
+      {
+        "name": "RESUME",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "HandsOnDetectionDriverState",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "HANDS_ON",
+        "value": 1
+      },
+      {
+        "name": "HANDS_OFF",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "CruiseControlCommand",
+    "values": [
+      {
+        "name": "ACTIVATE",
+        "value": 1
+      },
+      {
+        "name": "SUSPEND",
+        "value": 2
+      },
+      {
+        "name": "INCREASE_TARGET_SPEED",
+        "value": 3
+      },
+      {
+        "name": "DECREASE_TARGET_SPEED",
+        "value": 4
+      },
+      {
+        "name": "INCREASE_TARGET_TIME_GAP",
+        "value": 5
+      },
+      {
+        "name": "DECREASE_TARGET_TIME_GAP",
+        "value": 6
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "WindshieldWipersSwitch",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "OFF",
+        "value": 1
+      },
+      {
+        "name": "MIST",
+        "value": 2
+      },
+      {
+        "name": "INTERMITTENT_LEVEL_1",
+        "value": 3
+      },
+      {
+        "name": "INTERMITTENT_LEVEL_2",
+        "value": 4
+      },
+      {
+        "name": "INTERMITTENT_LEVEL_3",
+        "value": 5
+      },
+      {
+        "name": "INTERMITTENT_LEVEL_4",
+        "value": 6
+      },
+      {
+        "name": "INTERMITTENT_LEVEL_5",
+        "value": 7
+      },
+      {
+        "name": "CONTINUOUS_LEVEL_1",
+        "value": 8
+      },
+      {
+        "name": "CONTINUOUS_LEVEL_2",
+        "value": 9
+      },
+      {
+        "name": "CONTINUOUS_LEVEL_3",
+        "value": 10
+      },
+      {
+        "name": "CONTINUOUS_LEVEL_4",
+        "value": 11
+      },
+      {
+        "name": "CONTINUOUS_LEVEL_5",
+        "value": 12
+      },
+      {
+        "name": "AUTO",
+        "value": 13
+      },
+      {
+        "name": "SERVICE",
+        "value": 14
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleHwMotionToolType",
+    "values": [
+      {
+        "name": "TOOL_TYPE_UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "TOOL_TYPE_FINGER",
+        "value": 1
+      },
+      {
+        "name": "TOOL_TYPE_STYLUS",
+        "value": 2
+      },
+      {
+        "name": "TOOL_TYPE_MOUSE",
+        "value": 3
+      },
+      {
+        "name": "TOOL_TYPE_ERASER",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "SwitchUserStatus",
+    "values": [
+      {
+        "name": "SUCCESS",
+        "value": 1
+      },
+      {
+        "name": "FAILURE",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "EvsServiceType",
+    "values": [
+      {
+        "name": "REARVIEW",
+        "value": 0
+      },
+      {
+        "name": "SURROUNDVIEW",
+        "value": 1
+      },
+      {
+        "name": "FRONTVIEW",
+        "value": 2
+      },
+      {
+        "name": "LEFTVIEW",
+        "value": 3
+      },
+      {
+        "name": "RIGHTVIEW",
+        "value": 4
+      },
+      {
+        "name": "DRIVERVIEW",
+        "value": 5
+      },
+      {
+        "name": "FRONTPASSENGERSVIEW",
+        "value": 6
+      },
+      {
+        "name": "REARPASSENGERSVIEW",
+        "value": 7
+      },
+      {
+        "name": "USER_DEFINED",
+        "value": 1000
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "UserIdentificationAssociationValue",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 1
+      },
+      {
+        "name": "ASSOCIATED_CURRENT_USER",
+        "value": 2
+      },
+      {
+        "name": "ASSOCIATED_ANOTHER_USER",
+        "value": 3
+      },
+      {
+        "name": "NOT_ASSOCIATED_ANY_USER",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "ErrorState",
+    "values": [
+      {
+        "name": "OTHER_ERROR_STATE",
+        "value": -1
+      },
+      {
+        "name": "NOT_AVAILABLE_DISABLED",
+        "value": -2
+      },
+      {
+        "name": "NOT_AVAILABLE_SPEED_LOW",
+        "value": -3
+      },
+      {
+        "name": "NOT_AVAILABLE_SPEED_HIGH",
+        "value": -4
+      },
+      {
+        "name": "NOT_AVAILABLE_POOR_VISIBILITY",
+        "value": -5
+      },
+      {
+        "name": "NOT_AVAILABLE_SAFETY",
+        "value": -6
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "VehicleIgnitionState",
     "values": [
       {
@@ -2365,173 +868,302 @@
     ]
   },
   {
-    "name": "VehicleHwKeyInputAction",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleAreaSeat",
     "values": [
       {
-        "name": "ACTION_DOWN",
-        "value": 0
-      },
-      {
-        "name": "ACTION_UP",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "DiagnosticIntegerSensorIndex",
-    "values": [
-      {
-        "name": "FUEL_SYSTEM_STATUS",
-        "value": 0
-      },
-      {
-        "name": "MALFUNCTION_INDICATOR_LIGHT_ON",
+        "name": "ROW_1_LEFT",
         "value": 1
       },
       {
-        "name": "IGNITION_MONITORS_SUPPORTED",
+        "name": "ROW_1_CENTER",
         "value": 2
       },
       {
-        "name": "IGNITION_SPECIFIC_MONITORS",
-        "value": 3
-      },
-      {
-        "name": "INTAKE_AIR_TEMPERATURE",
+        "name": "ROW_1_RIGHT",
         "value": 4
       },
       {
-        "name": "COMMANDED_SECONDARY_AIR_STATUS",
-        "value": 5
-      },
-      {
-        "name": "NUM_OXYGEN_SENSORS_PRESENT",
-        "value": 6
-      },
-      {
-        "name": "RUNTIME_SINCE_ENGINE_START",
-        "value": 7
-      },
-      {
-        "name": "DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON",
-        "value": 8
-      },
-      {
-        "name": "WARMUPS_SINCE_CODES_CLEARED",
-        "value": 9
-      },
-      {
-        "name": "DISTANCE_TRAVELED_SINCE_CODES_CLEARED",
-        "value": 10
-      },
-      {
-        "name": "ABSOLUTE_BAROMETRIC_PRESSURE",
-        "value": 11
-      },
-      {
-        "name": "CONTROL_MODULE_VOLTAGE",
-        "value": 12
-      },
-      {
-        "name": "AMBIENT_AIR_TEMPERATURE",
-        "value": 13
-      },
-      {
-        "name": "TIME_WITH_MALFUNCTION_LIGHT_ON",
-        "value": 14
-      },
-      {
-        "name": "TIME_SINCE_TROUBLE_CODES_CLEARED",
-        "value": 15
-      },
-      {
-        "name": "MAX_FUEL_AIR_EQUIVALENCE_RATIO",
+        "name": "ROW_2_LEFT",
         "value": 16
       },
       {
-        "name": "MAX_OXYGEN_SENSOR_VOLTAGE",
-        "value": 17
+        "name": "ROW_2_CENTER",
+        "value": 32
       },
       {
-        "name": "MAX_OXYGEN_SENSOR_CURRENT",
-        "value": 18
+        "name": "ROW_2_RIGHT",
+        "value": 64
       },
       {
-        "name": "MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE",
-        "value": 19
+        "name": "ROW_3_LEFT",
+        "value": 256
       },
       {
-        "name": "MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR",
-        "value": 20
+        "name": "ROW_3_CENTER",
+        "value": 512
       },
       {
-        "name": "FUEL_TYPE",
-        "value": 21
-      },
-      {
-        "name": "FUEL_RAIL_ABSOLUTE_PRESSURE",
-        "value": 22
-      },
-      {
-        "name": "ENGINE_OIL_TEMPERATURE",
-        "value": 23
-      },
-      {
-        "name": "DRIVER_DEMAND_PERCENT_TORQUE",
-        "value": 24
-      },
-      {
-        "name": "ENGINE_ACTUAL_PERCENT_TORQUE",
-        "value": 25
-      },
-      {
-        "name": "ENGINE_REFERENCE_PERCENT_TORQUE",
-        "value": 26
-      },
-      {
-        "name": "ENGINE_PERCENT_TORQUE_DATA_IDLE",
-        "value": 27
-      },
-      {
-        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT1",
-        "value": 28
-      },
-      {
-        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT2",
-        "value": 29
-      },
-      {
-        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT3",
-        "value": 30
-      },
-      {
-        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT4",
-        "value": 31
+        "name": "ROW_3_RIGHT",
+        "value": 1024
       }
     ]
   },
   {
-    "name": "UserIdentificationAssociationValue",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "EvsServiceRequestIndex",
     "values": [
       {
-        "name": "UNKNOWN",
+        "name": "TYPE",
+        "value": 0
+      },
+      {
+        "name": "STATE",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "LaneDepartureWarningState",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "NO_WARNING",
         "value": 1
       },
       {
-        "name": "ASSOCIATED_CURRENT_USER",
+        "name": "WARNING_LEFT",
         "value": 2
       },
       {
-        "name": "ASSOCIATED_ANOTHER_USER",
+        "name": "WARNING_RIGHT",
         "value": 3
-      },
-      {
-        "name": "NOT_ASSOCIATED_ANY_USER",
-        "value": 4
       }
     ]
   },
   {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "Obd2SparkIgnitionMonitors",
+    "values": []
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "CreateUserStatus",
+    "values": [
+      {
+        "name": "SUCCESS",
+        "value": 1
+      },
+      {
+        "name": "FAILURE",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehiclePropertyGroup",
+    "values": [
+      {
+        "name": "SYSTEM",
+        "value": 268435456
+      },
+      {
+        "name": "VENDOR",
+        "value": 536870912
+      },
+      {
+        "name": "MASK",
+        "value": 4026531840
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleVendorPermission",
+    "values": [
+      {
+        "name": "PERMISSION_DEFAULT",
+        "value": 0
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_WINDOW",
+        "value": 1
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_WINDOW",
+        "value": 2
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_DOOR",
+        "value": 3
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_DOOR",
+        "value": 4
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_SEAT",
+        "value": 5
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_SEAT",
+        "value": 6
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_MIRROR",
+        "value": 7
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_MIRROR",
+        "value": 8
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_INFO",
+        "value": 9
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_INFO",
+        "value": 10
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_ENGINE",
+        "value": 11
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_ENGINE",
+        "value": 12
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_HVAC",
+        "value": 13
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_HVAC",
+        "value": 14
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_LIGHT",
+        "value": 15
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_LIGHT",
+        "value": 16
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_1",
+        "value": 65536
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_1",
+        "value": 69632
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_2",
+        "value": 131072
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_2",
+        "value": 135168
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_3",
+        "value": 196608
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_3",
+        "value": 200704
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_4",
+        "value": 262144
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_4",
+        "value": 266240
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_5",
+        "value": 327680
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_5",
+        "value": 331776
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_6",
+        "value": 393216
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_6",
+        "value": 397312
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_7",
+        "value": 458752
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_7",
+        "value": 462848
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_8",
+        "value": 524288
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_8",
+        "value": 528384
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_9",
+        "value": 589824
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_9",
+        "value": 593920
+      },
+      {
+        "name": "PERMISSION_SET_VENDOR_CATEGORY_10",
+        "value": 655360
+      },
+      {
+        "name": "PERMISSION_GET_VENDOR_CATEGORY_10",
+        "value": 659456
+      },
+      {
+        "name": "PERMISSION_NOT_ACCESSIBLE",
+        "value": 4026531840
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VmsOfferingMessageIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "PUBLISHER_ID",
+        "value": 1
+      },
+      {
+        "name": "NUMBER_OF_OFFERS",
+        "value": 2
+      },
+      {
+        "name": "OFFERING_START",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "VmsBaseMessageIntegerValuesIndex",
     "values": [
       {
@@ -2541,6 +1173,473 @@
     ]
   },
   {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "Obd2CompressionIgnitionMonitors",
+    "values": []
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "LaneKeepAssistState",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "ENABLED",
+        "value": 1
+      },
+      {
+        "name": "ACTIVATED_STEER_LEFT",
+        "value": 2
+      },
+      {
+        "name": "ACTIVATED_STEER_RIGHT",
+        "value": 3
+      },
+      {
+        "name": "USER_OVERRIDE",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleHwMotionInputAction",
+    "values": [
+      {
+        "name": "ACTION_DOWN",
+        "value": 0
+      },
+      {
+        "name": "ACTION_UP",
+        "value": 1
+      },
+      {
+        "name": "ACTION_MOVE",
+        "value": 2
+      },
+      {
+        "name": "ACTION_CANCEL",
+        "value": 3
+      },
+      {
+        "name": "ACTION_OUTSIDE",
+        "value": 4
+      },
+      {
+        "name": "ACTION_POINTER_DOWN",
+        "value": 5
+      },
+      {
+        "name": "ACTION_POINTER_UP",
+        "value": 6
+      },
+      {
+        "name": "ACTION_HOVER_MOVE",
+        "value": 7
+      },
+      {
+        "name": "ACTION_SCROLL",
+        "value": 8
+      },
+      {
+        "name": "ACTION_HOVER_ENTER",
+        "value": 9
+      },
+      {
+        "name": "ACTION_HOVER_EXIT",
+        "value": 10
+      },
+      {
+        "name": "ACTION_BUTTON_PRESS",
+        "value": 11
+      },
+      {
+        "name": "ACTION_BUTTON_RELEASE",
+        "value": 12
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleApPowerStateConfigFlag",
+    "values": [
+      {
+        "name": "ENABLE_DEEP_SLEEP_FLAG",
+        "value": 1
+      },
+      {
+        "name": "CONFIG_SUPPORT_TIMER_POWER_ON_FLAG",
+        "value": 2
+      },
+      {
+        "name": "ENABLE_HIBERNATION_FLAG",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "Obd2SecondaryAirStatus",
+    "values": [
+      {
+        "name": "UPSTREAM",
+        "value": 1
+      },
+      {
+        "name": "DOWNSTREAM_OF_CATALYCIC_CONVERTER",
+        "value": 2
+      },
+      {
+        "name": "FROM_OUTSIDE_OR_OFF",
+        "value": 4
+      },
+      {
+        "name": "PUMP_ON_FOR_DIAGNOSTICS",
+        "value": 8
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VmsPublisherInformationIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "PUBLISHER_ID",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleApPowerStateReq",
+    "values": [
+      {
+        "name": "ON",
+        "value": 0
+      },
+      {
+        "name": "SHUTDOWN_PREPARE",
+        "value": 1
+      },
+      {
+        "name": "CANCEL_SHUTDOWN",
+        "value": 2
+      },
+      {
+        "name": "FINISHED",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "WindshieldWipersState",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "OFF",
+        "value": 1
+      },
+      {
+        "name": "ON",
+        "value": 2
+      },
+      {
+        "name": "SERVICE",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "LaneCenteringAssistState",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "ENABLED",
+        "value": 1
+      },
+      {
+        "name": "ACTIVATION_REQUESTED",
+        "value": 2
+      },
+      {
+        "name": "ACTIVATED",
+        "value": 3
+      },
+      {
+        "name": "USER_OVERRIDE",
+        "value": 4
+      },
+      {
+        "name": "FORCED_DEACTIVATION_WARNING",
+        "value": 5
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "UserIdentificationAssociationSetValue",
+    "values": [
+      {
+        "name": "INVALID",
+        "value": 0
+      },
+      {
+        "name": "ASSOCIATE_CURRENT_USER",
+        "value": 1
+      },
+      {
+        "name": "DISASSOCIATE_CURRENT_USER",
+        "value": 2
+      },
+      {
+        "name": "DISASSOCIATE_ALL_USERS",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "Obd2CommonIgnitionMonitors",
+    "values": []
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleHwMotionInputSource",
+    "values": [
+      {
+        "name": "SOURCE_UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "SOURCE_KEYBOARD",
+        "value": 1
+      },
+      {
+        "name": "SOURCE_DPAD",
+        "value": 2
+      },
+      {
+        "name": "SOURCE_GAMEPAD",
+        "value": 3
+      },
+      {
+        "name": "SOURCE_TOUCHSCREEN",
+        "value": 4
+      },
+      {
+        "name": "SOURCE_MOUSE",
+        "value": 5
+      },
+      {
+        "name": "SOURCE_STYLUS",
+        "value": 6
+      },
+      {
+        "name": "SOURCE_BLUETOOTH_STYLUS",
+        "value": 7
+      },
+      {
+        "name": "SOURCE_TRACKBALL",
+        "value": 8
+      },
+      {
+        "name": "SOURCE_MOUSE_RELATIVE",
+        "value": 9
+      },
+      {
+        "name": "SOURCE_TOUCHPAD",
+        "value": 10
+      },
+      {
+        "name": "SOURCE_TOUCH_NAVIGATION",
+        "value": 11
+      },
+      {
+        "name": "SOURCE_ROTARY_ENCODER",
+        "value": 12
+      },
+      {
+        "name": "SOURCE_JOYSTICK",
+        "value": 13
+      },
+      {
+        "name": "SOURCE_HDMI",
+        "value": 14
+      },
+      {
+        "name": "SOURCE_SENSOR",
+        "value": 15
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "ForwardCollisionWarningState",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "NO_WARNING",
+        "value": 1
+      },
+      {
+        "name": "WARNING",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleArea",
+    "values": [
+      {
+        "name": "GLOBAL",
+        "value": 16777216
+      },
+      {
+        "name": "WINDOW",
+        "value": 50331648
+      },
+      {
+        "name": "MIRROR",
+        "value": 67108864
+      },
+      {
+        "name": "SEAT",
+        "value": 83886080
+      },
+      {
+        "name": "DOOR",
+        "value": 100663296
+      },
+      {
+        "name": "WHEEL",
+        "value": 117440512
+      },
+      {
+        "name": "MASK",
+        "value": 251658240
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "PortLocationType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "FRONT_LEFT",
+        "value": 1
+      },
+      {
+        "name": "FRONT_RIGHT",
+        "value": 2
+      },
+      {
+        "name": "REAR_RIGHT",
+        "value": 3
+      },
+      {
+        "name": "REAR_LEFT",
+        "value": 4
+      },
+      {
+        "name": "FRONT",
+        "value": 5
+      },
+      {
+        "name": "REAR",
+        "value": 6
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "InitialUserInfoResponseAction",
+    "values": [
+      {
+        "name": "DEFAULT",
+        "value": 0
+      },
+      {
+        "name": "SWITCH",
+        "value": 1
+      },
+      {
+        "name": "CREATE",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VmsSubscriptionsStateIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "SEQUENCE_NUMBER",
+        "value": 1
+      },
+      {
+        "name": "NUMBER_OF_LAYERS",
+        "value": 2
+      },
+      {
+        "name": "NUMBER_OF_ASSOCIATED_LAYERS",
+        "value": 3
+      },
+      {
+        "name": "SUBSCRIPTIONS_START",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "CruiseControlType",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "STANDARD",
+        "value": 1
+      },
+      {
+        "name": "ADAPTIVE",
+        "value": 2
+      },
+      {
+        "name": "PREDICTIVE",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "DiagnosticFloatSensorIndex",
     "values": [
       {
@@ -2830,7 +1929,40 @@
     ]
   },
   {
-    "name": "VmsMessageWithLayerAndPublisherIdIntegerValuesIndex",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "GsrComplianceRequirementType",
+    "values": [
+      {
+        "name": "GSR_COMPLIANCE_NOT_REQUIRED",
+        "value": 0
+      },
+      {
+        "name": "GSR_COMPLIANCE_REQUIRED_V1",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleLightState",
+    "values": [
+      {
+        "name": "OFF",
+        "value": 0
+      },
+      {
+        "name": "ON",
+        "value": 1
+      },
+      {
+        "name": "DAYTIME_RUNNING",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VmsMessageWithLayerIntegerValuesIndex",
     "values": [
       {
         "name": "MESSAGE_TYPE",
@@ -2847,92 +1979,61 @@
       {
         "name": "LAYER_VERSION",
         "value": 3
-      },
-      {
-        "name": "PUBLISHER_ID",
-        "value": 4
       }
     ]
   },
   {
-    "name": "FuelType",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "EvRegenerativeBrakingState",
     "values": [
       {
-        "name": "FUEL_TYPE_UNKNOWN",
+        "name": "UNKNOWN",
         "value": 0
       },
       {
-        "name": "FUEL_TYPE_UNLEADED",
+        "name": "DISABLED",
         "value": 1
       },
       {
-        "name": "FUEL_TYPE_LEADED",
+        "name": "PARTIALLY_ENABLED",
         "value": 2
       },
       {
-        "name": "FUEL_TYPE_DIESEL_1",
-        "value": 3
-      },
-      {
-        "name": "FUEL_TYPE_DIESEL_2",
-        "value": 4
-      },
-      {
-        "name": "FUEL_TYPE_BIODIESEL",
-        "value": 5
-      },
-      {
-        "name": "FUEL_TYPE_E85",
-        "value": 6
-      },
-      {
-        "name": "FUEL_TYPE_LPG",
-        "value": 7
-      },
-      {
-        "name": "FUEL_TYPE_CNG",
-        "value": 8
-      },
-      {
-        "name": "FUEL_TYPE_LNG",
-        "value": 9
-      },
-      {
-        "name": "FUEL_TYPE_ELECTRIC",
-        "value": 10
-      },
-      {
-        "name": "FUEL_TYPE_HYDROGEN",
-        "value": 11
-      },
-      {
-        "name": "FUEL_TYPE_OTHER",
-        "value": 12
-      }
-    ]
-  },
-  {
-    "name": "VehicleApPowerStateReq",
-    "values": [
-      {
-        "name": "ON",
-        "value": 0
-      },
-      {
-        "name": "SHUTDOWN_PREPARE",
-        "value": 1
-      },
-      {
-        "name": "CANCEL_SHUTDOWN",
-        "value": 2
-      },
-      {
-        "name": "FINISHED",
+        "name": "FULLY_ENABLED",
         "value": 3
       }
     ]
   },
   {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleApPowerStateReqIndex",
+    "values": [
+      {
+        "name": "STATE",
+        "value": 0
+      },
+      {
+        "name": "ADDITIONAL",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "RotaryInputType",
+    "values": [
+      {
+        "name": "ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION",
+        "value": 0
+      },
+      {
+        "name": "ROTARY_INPUT_TYPE_AUDIO_VOLUME",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "VmsMessageType",
     "values": [
       {
@@ -3006,96 +2107,417 @@
     ]
   },
   {
-    "name": "Obd2CommonIgnitionMonitors",
-    "values": []
-  },
-  {
-    "name": "UserIdentificationAssociationType",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "FuelType",
     "values": [
       {
-        "name": "INVALID",
+        "name": "FUEL_TYPE_UNKNOWN",
         "value": 0
       },
       {
-        "name": "KEY_FOB",
+        "name": "FUEL_TYPE_UNLEADED",
         "value": 1
       },
       {
-        "name": "CUSTOM_1",
-        "value": 101
+        "name": "FUEL_TYPE_LEADED",
+        "value": 2
       },
       {
-        "name": "CUSTOM_2",
-        "value": 102
+        "name": "FUEL_TYPE_DIESEL_1",
+        "value": 3
       },
       {
-        "name": "CUSTOM_3",
-        "value": 103
+        "name": "FUEL_TYPE_DIESEL_2",
+        "value": 4
       },
       {
-        "name": "CUSTOM_4",
-        "value": 104
+        "name": "FUEL_TYPE_BIODIESEL",
+        "value": 5
+      },
+      {
+        "name": "FUEL_TYPE_E85",
+        "value": 6
+      },
+      {
+        "name": "FUEL_TYPE_LPG",
+        "value": 7
+      },
+      {
+        "name": "FUEL_TYPE_CNG",
+        "value": 8
+      },
+      {
+        "name": "FUEL_TYPE_LNG",
+        "value": 9
+      },
+      {
+        "name": "FUEL_TYPE_ELECTRIC",
+        "value": 10
+      },
+      {
+        "name": "FUEL_TYPE_HYDROGEN",
+        "value": 11
+      },
+      {
+        "name": "FUEL_TYPE_OTHER",
+        "value": 12
       }
     ]
   },
   {
-    "name": "EvConnectorType",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleSeatOccupancyState",
     "values": [
       {
         "name": "UNKNOWN",
         "value": 0
       },
       {
-        "name": "IEC_TYPE_1_AC",
+        "name": "VACANT",
         "value": 1
       },
       {
-        "name": "IEC_TYPE_2_AC",
+        "name": "OCCUPIED",
         "value": 2
-      },
-      {
-        "name": "IEC_TYPE_3_AC",
-        "value": 3
-      },
-      {
-        "name": "IEC_TYPE_4_DC",
-        "value": 4
-      },
-      {
-        "name": "IEC_TYPE_1_CCS_DC",
-        "value": 5
-      },
-      {
-        "name": "IEC_TYPE_2_CCS_DC",
-        "value": 6
-      },
-      {
-        "name": "TESLA_ROADSTER",
-        "value": 7
-      },
-      {
-        "name": "TESLA_HPWC",
-        "value": 8
-      },
-      {
-        "name": "TESLA_SUPERCHARGER",
-        "value": 9
-      },
-      {
-        "name": "GBT_AC",
-        "value": 10
-      },
-      {
-        "name": "GBT_DC",
-        "value": 11
-      },
-      {
-        "name": "OTHER",
-        "value": 101
       }
     ]
   },
   {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "EvStoppingMode",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "CREEP",
+        "value": 1
+      },
+      {
+        "name": "ROLL",
+        "value": 2
+      },
+      {
+        "name": "HOLD",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "AutomaticEmergencyBrakingState",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "ENABLED",
+        "value": 1
+      },
+      {
+        "name": "ACTIVATED",
+        "value": 2
+      },
+      {
+        "name": "USER_OVERRIDE",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleApPowerStateReport",
+    "values": [
+      {
+        "name": "WAIT_FOR_VHAL",
+        "value": 1
+      },
+      {
+        "name": "DEEP_SLEEP_ENTRY",
+        "value": 2
+      },
+      {
+        "name": "DEEP_SLEEP_EXIT",
+        "value": 3
+      },
+      {
+        "name": "SHUTDOWN_POSTPONE",
+        "value": 4
+      },
+      {
+        "name": "SHUTDOWN_START",
+        "value": 5
+      },
+      {
+        "name": "ON",
+        "value": 6
+      },
+      {
+        "name": "SHUTDOWN_PREPARE",
+        "value": 7
+      },
+      {
+        "name": "SHUTDOWN_CANCELLED",
+        "value": 8
+      },
+      {
+        "name": "HIBERNATION_ENTRY",
+        "value": 9
+      },
+      {
+        "name": "HIBERNATION_EXIT",
+        "value": 10
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "SwitchUserMessageType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "LEGACY_ANDROID_SWITCH",
+        "value": 1
+      },
+      {
+        "name": "ANDROID_SWITCH",
+        "value": 2
+      },
+      {
+        "name": "VEHICLE_RESPONSE",
+        "value": 3
+      },
+      {
+        "name": "VEHICLE_REQUEST",
+        "value": 4
+      },
+      {
+        "name": "ANDROID_POST_SWITCH",
+        "value": 5
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleAreaMirror",
+    "values": [
+      {
+        "name": "DRIVER_LEFT",
+        "value": 1
+      },
+      {
+        "name": "DRIVER_RIGHT",
+        "value": 2
+      },
+      {
+        "name": "DRIVER_CENTER",
+        "value": 4
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "TrailerState",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "NOT_PRESENT",
+        "value": 1
+      },
+      {
+        "name": "PRESENT",
+        "value": 2
+      },
+      {
+        "name": "ERROR",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "EvsServiceState",
+    "values": [
+      {
+        "name": "OFF",
+        "value": 0
+      },
+      {
+        "name": "ON",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleHwKeyInputAction",
+    "values": [
+      {
+        "name": "ACTION_DOWN",
+        "value": 0
+      },
+      {
+        "name": "ACTION_UP",
+        "value": 1
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "BlindSpotWarningState",
+    "values": [
+      {
+        "name": "OTHER",
+        "value": 0
+      },
+      {
+        "name": "NO_WARNING",
+        "value": 1
+      },
+      {
+        "name": "WARNING",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleGear",
+    "values": [
+      {
+        "name": "GEAR_UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "GEAR_NEUTRAL",
+        "value": 1
+      },
+      {
+        "name": "GEAR_REVERSE",
+        "value": 2
+      },
+      {
+        "name": "GEAR_PARK",
+        "value": 4
+      },
+      {
+        "name": "GEAR_DRIVE",
+        "value": 8
+      },
+      {
+        "name": "GEAR_1",
+        "value": 16
+      },
+      {
+        "name": "GEAR_2",
+        "value": 32
+      },
+      {
+        "name": "GEAR_3",
+        "value": 64
+      },
+      {
+        "name": "GEAR_4",
+        "value": 128
+      },
+      {
+        "name": "GEAR_5",
+        "value": 256
+      },
+      {
+        "name": "GEAR_6",
+        "value": 512
+      },
+      {
+        "name": "GEAR_7",
+        "value": 1024
+      },
+      {
+        "name": "GEAR_8",
+        "value": 2048
+      },
+      {
+        "name": "GEAR_9",
+        "value": 4096
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VmsStartSessionMessageIntegerValuesIndex",
+    "values": [
+      {
+        "name": "MESSAGE_TYPE",
+        "value": 0
+      },
+      {
+        "name": "SERVICE_ID",
+        "value": 1
+      },
+      {
+        "name": "CLIENT_ID",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "Obd2FuelSystemStatus",
+    "values": [
+      {
+        "name": "OPEN_INSUFFICIENT_ENGINE_TEMPERATURE",
+        "value": 1
+      },
+      {
+        "name": "CLOSED_LOOP",
+        "value": 2
+      },
+      {
+        "name": "OPEN_ENGINE_LOAD_OR_DECELERATION",
+        "value": 4
+      },
+      {
+        "name": "OPEN_SYSTEM_FAILURE",
+        "value": 8
+      },
+      {
+        "name": "CLOSED_LOOP_BUT_FEEDBACK_FAULT",
+        "value": 16
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "ElectronicTollCollectionCardStatus",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_VALID",
+        "value": 1
+      },
+      {
+        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_INVALID",
+        "value": 2
+      },
+      {
+        "name": "ELECTRONIC_TOLL_COLLECTION_CARD_NOT_INSERTED",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "VehicleApPowerStateShutdownParam",
     "values": [
       {
@@ -3125,271 +2547,53 @@
     ]
   },
   {
-    "name": "VmsOfferingMessageIntegerValuesIndex",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "CustomInputType",
     "values": [
       {
-        "name": "MESSAGE_TYPE",
-        "value": 0
+        "name": "CUSTOM_EVENT_F1",
+        "value": 1001
       },
       {
-        "name": "PUBLISHER_ID",
-        "value": 1
+        "name": "CUSTOM_EVENT_F2",
+        "value": 1002
       },
       {
-        "name": "NUMBER_OF_OFFERS",
-        "value": 2
+        "name": "CUSTOM_EVENT_F3",
+        "value": 1003
       },
       {
-        "name": "OFFERING_START",
-        "value": 3
+        "name": "CUSTOM_EVENT_F4",
+        "value": 1004
+      },
+      {
+        "name": "CUSTOM_EVENT_F5",
+        "value": 1005
+      },
+      {
+        "name": "CUSTOM_EVENT_F6",
+        "value": 1006
+      },
+      {
+        "name": "CUSTOM_EVENT_F7",
+        "value": 1007
+      },
+      {
+        "name": "CUSTOM_EVENT_F8",
+        "value": 1008
+      },
+      {
+        "name": "CUSTOM_EVENT_F9",
+        "value": 1009
+      },
+      {
+        "name": "CUSTOM_EVENT_F10",
+        "value": 1010
       }
     ]
   },
   {
-    "name": "VehicleAreaSeat",
-    "values": [
-      {
-        "name": "ROW_1_LEFT",
-        "value": 1
-      },
-      {
-        "name": "ROW_1_CENTER",
-        "value": 2
-      },
-      {
-        "name": "ROW_1_RIGHT",
-        "value": 4
-      },
-      {
-        "name": "ROW_2_LEFT",
-        "value": 16
-      },
-      {
-        "name": "ROW_2_CENTER",
-        "value": 32
-      },
-      {
-        "name": "ROW_2_RIGHT",
-        "value": 64
-      },
-      {
-        "name": "ROW_3_LEFT",
-        "value": 256
-      },
-      {
-        "name": "ROW_3_CENTER",
-        "value": 512
-      },
-      {
-        "name": "ROW_3_RIGHT",
-        "value": 1024
-      }
-    ]
-  },
-  {
-    "name": "VehicleVendorPermission",
-    "values": [
-      {
-        "name": "PERMISSION_DEFAULT",
-        "value": 0
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_WINDOW",
-        "value": 1
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_WINDOW",
-        "value": 2
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_DOOR",
-        "value": 3
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_DOOR",
-        "value": 4
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_SEAT",
-        "value": 5
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_SEAT",
-        "value": 6
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_MIRROR",
-        "value": 7
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_MIRROR",
-        "value": 8
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_INFO",
-        "value": 9
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_INFO",
-        "value": 10
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_ENGINE",
-        "value": 11
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_ENGINE",
-        "value": 12
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_HVAC",
-        "value": 13
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_HVAC",
-        "value": 14
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_LIGHT",
-        "value": 15
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_LIGHT",
-        "value": 16
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_1",
-        "value": 65536
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_1",
-        "value": 69632
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_2",
-        "value": 131072
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_2",
-        "value": 135168
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_3",
-        "value": 196608
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_3",
-        "value": 200704
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_4",
-        "value": 262144
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_4",
-        "value": 266240
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_5",
-        "value": 327680
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_5",
-        "value": 331776
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_6",
-        "value": 393216
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_6",
-        "value": 397312
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_7",
-        "value": 458752
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_7",
-        "value": 462848
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_8",
-        "value": 524288
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_8",
-        "value": 528384
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_9",
-        "value": 589824
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_9",
-        "value": 593920
-      },
-      {
-        "name": "PERMISSION_SET_VENDOR_CATEGORY_10",
-        "value": 655360
-      },
-      {
-        "name": "PERMISSION_GET_VENDOR_CATEGORY_10",
-        "value": 659456
-      },
-      {
-        "name": "PERMISSION_NOT_ACCESSIBLE",
-        "value": 4026531840
-      }
-    ]
-  },
-  {
-    "name": "VehiclePropertyAccess",
-    "values": [
-      {
-        "name": "NONE",
-        "value": 0
-      },
-      {
-        "name": "READ",
-        "value": 1
-      },
-      {
-        "name": "WRITE",
-        "value": 2
-      },
-      {
-        "name": "READ_WRITE",
-        "value": 3
-      }
-    ]
-  },
-  {
-    "name": "VmsAvailabilityStateIntegerValuesIndex",
-    "values": [
-      {
-        "name": "MESSAGE_TYPE",
-        "value": 0
-      },
-      {
-        "name": "SEQUENCE_NUMBER",
-        "value": 1
-      },
-      {
-        "name": "NUMBER_OF_ASSOCIATED_LAYERS",
-        "value": 2
-      },
-      {
-        "name": "LAYERS_START",
-        "value": 3
-      }
-    ]
-  },
-  {
-    "name": "Obd2SparkIgnitionMonitors",
-    "values": []
-  },
-  {
+    "package": "android.hardware.automotive.vehicle",
     "name": "VehicleTurnSignal",
     "values": [
       {
@@ -3407,53 +2611,1992 @@
     ]
   },
   {
-    "name": "VmsPublisherInformationIntegerValuesIndex",
+    "package": "android.hardware.automotive.vehicle",
+    "name": "ElectronicTollCollectionCardType",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
+      },
+      {
+        "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD",
+        "value": 1
+      },
+      {
+        "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleProperty",
+    "values": [
+      {
+        "name": "Undefined property.",
+        "value": 0
+      },
+      {
+        "name": "VIN of vehicle",
+        "value": 286261504,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Manufacturer of vehicle",
+        "value": 286261505,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Model of vehicle",
+        "value": 286261506,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Model year of vehicle.",
+        "value": 289407235,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:YEAR"
+      },
+      {
+        "name": "Fuel capacity of the vehicle in milliliters",
+        "value": 291504388,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MILLILITER"
+      },
+      {
+        "name": "List of fuels the vehicle may use.",
+        "value": 289472773,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "FuelType"
+      },
+      {
+        "name": "Nominal battery capacity for EV or hybrid vehicle",
+        "value": 291504390,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:WH"
+      },
+      {
+        "name": "List of connectors this EV may use",
+        "value": 289472775,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "data_enum": "EvConnectorType",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Fuel door location",
+        "value": 289407240,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "data_enum": "PortLocationType",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "EV port location",
+        "value": 289407241,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "PortLocationType"
+      },
+      {
+        "name": "INFO_DRIVER_SEAT",
+        "value": 356516106,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "data_enum": "VehicleAreaSeat",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Exterior dimensions of vehicle.",
+        "value": 289472779,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MILLIMETER"
+      },
+      {
+        "name": "Multiple EV port locations",
+        "value": 289472780,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "PortLocationType"
+      },
+      {
+        "name": "Current odometer value of the vehicle",
+        "value": 291504644,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:KILOMETER"
+      },
+      {
+        "name": "Speed of the vehicle",
+        "value": 291504647,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:METER_PER_SEC"
+      },
+      {
+        "name": "Speed of the vehicle for displays",
+        "value": 291504648,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:METER_PER_SEC"
+      },
+      {
+        "name": "Front bicycle model steering angle for vehicle",
+        "value": 291504649,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:DEGREES"
+      },
+      {
+        "name": "Rear bicycle model steering angle for vehicle",
+        "value": 291504656,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:DEGREES"
+      },
+      {
+        "name": "Temperature of engine coolant",
+        "value": 291504897,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "Engine oil level",
+        "value": 289407747,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleOilLevel"
+      },
+      {
+        "name": "Temperature of engine oil",
+        "value": 291504900,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "Engine rpm",
+        "value": 291504901,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:RPM"
+      },
+      {
+        "name": "Reports wheel ticks",
+        "value": 290521862,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "FUEL_LEVEL",
+        "value": 291504903,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MILLILITER"
+      },
+      {
+        "name": "Fuel door open",
+        "value": 287310600,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Battery level for EV or hybrid vehicle",
+        "value": 291504905,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:WH"
+      },
+      {
+        "name": "Current battery capacity for EV or hybrid vehicle",
+        "value": 291504909,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:WH"
+      },
+      {
+        "name": "EV charge port open",
+        "value": 287310602,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "EV charge port connected",
+        "value": 287310603,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "EV instantaneous charge rate in milliwatts",
+        "value": 291504908,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MW"
+      },
+      {
+        "name": "Range remaining",
+        "value": 291504904,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "unit": "VehicleUnit:METER"
+      },
+      {
+        "name": "Tire pressure",
+        "value": 392168201,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:KILOPASCAL"
+      },
+      {
+        "name": "Critically low tire pressure",
+        "value": 392168202,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:KILOPASCAL"
+      },
+      {
+        "name": "Represents feature for engine idle automatic stop.",
+        "value": 287310624,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Currently selected gear",
+        "value": 289408000,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleGear"
+      },
+      {
+        "name": "CURRENT_GEAR",
+        "value": 289408001,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleGear"
+      },
+      {
+        "name": "Parking brake state.",
+        "value": 287310850,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "PARKING_BRAKE_AUTO_APPLY",
+        "value": 287310851,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Regenerative braking level of a electronic vehicle",
+        "value": 289408012,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Warning for fuel low level.",
+        "value": 287310853,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Night mode",
+        "value": 287310855,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "State of the vehicles turn signals",
+        "value": 289408008,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleTurnSignal"
+      },
+      {
+        "name": "Represents ignition state",
+        "value": 289408009,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleIgnitionState"
+      },
+      {
+        "name": "ABS is active",
+        "value": 287310858,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Traction Control is active",
+        "value": 287310859,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Represents property for the current stopping mode of the vehicle.",
+        "value": 289408013,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "EvStoppingMode"
+      },
+      {
+        "name": "HVAC Properties",
+        "value": 356517120,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Fan direction setting",
+        "value": 356517121,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleHvacFanDirection"
+      },
+      {
+        "name": "HVAC current temperature.",
+        "value": 358614274,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "HVAC_TEMPERATURE_SET",
+        "value": 358614275,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "HVAC_DEFROSTER",
+        "value": 320865540,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_AC_ON",
+        "value": 354419973,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "config_flags": "Supported"
+      },
+      {
+        "name": "HVAC_MAX_AC_ON",
+        "value": 354419974,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_MAX_DEFROST_ON",
+        "value": 354419975,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_RECIRC_ON",
+        "value": 354419976,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Enable temperature coupling between areas.",
+        "value": 354419977,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_AUTO_ON",
+        "value": 354419978,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_SEAT_TEMPERATURE",
+        "value": 356517131,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Side Mirror Heat",
+        "value": 339739916,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_STEERING_WHEEL_HEAT",
+        "value": 289408269,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Temperature units for display",
+        "value": 289408270,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "Actual fan speed",
+        "value": 356517135,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "HVAC_POWER_ON",
+        "value": 354419984,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Fan Positions Available",
+        "value": 356582673,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleHvacFanDirection"
+      },
+      {
+        "name": "HVAC_AUTO_RECIRC_ON",
+        "value": 354419986,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat ventilation",
+        "value": 356517139,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HVAC_ELECTRIC_DEFROSTER_ON",
+        "value": 320865556,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Suggested values for setting HVAC temperature.",
+        "value": 291570965,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Distance units for display",
+        "value": 289408512,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "Fuel volume units for display",
+        "value": 289408513,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "Tire pressure units for display",
+        "value": 289408514,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "EV battery units for display",
+        "value": 289408515,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleUnit"
+      },
+      {
+        "name": "Fuel consumption units for display",
+        "value": 287311364,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Speed units for display",
+        "value": 289408517,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "ANDROID_EPOCH_TIME",
+        "value": 290457094,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE",
+        "unit": "VehicleUnit:MILLI_SECS"
+      },
+      {
+        "name": "External encryption binding seed.",
+        "value": 292554247,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Outside temperature",
+        "value": 291505923,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:CELSIUS"
+      },
+      {
+        "name": "Property to control power state of application processor",
+        "value": 289475072,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Property to report power state of application processor",
+        "value": 289475073,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "AP_POWER_BOOTUP_REASON",
+        "value": 289409538,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Property to represent brightness of the display.",
+        "value": 289409539,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Property to represent brightness of the displays which are controlled separately.",
+        "value": 289475076,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HW_KEY_INPUT",
+        "value": 289475088,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "config_flags": ""
+      },
+      {
+        "name": "HW_KEY_INPUT_V2",
+        "value": 367004177,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "config_flags": ""
+      },
+      {
+        "name": "HW_MOTION_INPUT",
+        "value": 367004178,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "config_flags": ""
+      },
+      {
+        "name": "HW_ROTARY_INPUT",
+        "value": 289475104,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "data_enum": "RotaryInputType",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Defines a custom OEM partner input event.",
+        "value": 289475120,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "data_enum": "CustomInputType",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "DOOR_POS",
+        "value": 373295872,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Door move",
+        "value": 373295873,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Door lock",
+        "value": 371198722,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Door child lock feature enabled",
+        "value": 371198723,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Z Position",
+        "value": 339741504,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Z Move",
+        "value": 339741505,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Y Position",
+        "value": 339741506,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Y Move",
+        "value": 339741507,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Lock",
+        "value": 287312708,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Mirror Fold",
+        "value": 287312709,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Represents property for Mirror Auto Fold feature.",
+        "value": 337644358,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Represents property for Mirror Auto Tilt feature.",
+        "value": 337644359,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat memory select",
+        "value": 356518784,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Seat memory set",
+        "value": 356518785,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Seatbelt buckled",
+        "value": 354421634,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seatbelt height position",
+        "value": 356518787,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seatbelt height move",
+        "value": 356518788,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_FORE_AFT_POS",
+        "value": 356518789,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_FORE_AFT_MOVE",
+        "value": 356518790,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat backrest angle 1 position",
+        "value": 356518791,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat backrest angle 1 move",
+        "value": 356518792,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat backrest angle 2 position",
+        "value": 356518793,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat backrest angle 2 move",
+        "value": 356518794,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat height position",
+        "value": 356518795,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat height move",
+        "value": 356518796,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat depth position",
+        "value": 356518797,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat depth move",
+        "value": 356518798,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat tilt position",
+        "value": 356518799,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat tilt move",
+        "value": 356518800,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_LUMBAR_FORE_AFT_POS",
+        "value": 356518801,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_LUMBAR_FORE_AFT_MOVE",
+        "value": 356518802,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Lumbar side support position",
+        "value": 356518803,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Lumbar side support move",
+        "value": 356518804,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_HEADREST_HEIGHT_POS",
+        "value": 289409941,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Headrest height position",
+        "value": 356518820,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Headrest height move",
+        "value": 356518806,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Headrest angle position",
+        "value": 356518807,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Headrest angle move",
+        "value": 356518808,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_HEADREST_FORE_AFT_POS",
+        "value": 356518809,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_HEADREST_FORE_AFT_MOVE",
+        "value": 356518810,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Represents property for the seat footwell lights state.",
+        "value": 356518811,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Represents property for the seat footwell lights switch.",
+        "value": 356518812,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Represents property for Seat easy access feature.",
+        "value": 354421661,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_AIRBAG_ENABLED",
+        "value": 354421662,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_CUSHION_SIDE_SUPPORT_POS",
+        "value": 356518815,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Represents property for movement direction and speed of seat cushion side support.",
+        "value": 356518816,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_LUMBAR_VERTICAL_POS",
+        "value": 356518817,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Represents property for vertical movement direction and speed of seat lumbar support.",
+        "value": 356518818,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "SEAT_WALK_IN_POS",
+        "value": 356518819,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Seat Occupancy",
+        "value": 356518832,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleSeatOccupancyState"
+      },
+      {
+        "name": "Window Position",
+        "value": 322964416,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Window Move",
+        "value": 322964417,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Window Lock",
+        "value": 320867268,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "WINDSHIELD_WIPERS_PERIOD",
+        "value": 322964421,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MILLI_SECS"
+      },
+      {
+        "name": "Windshield wipers state.",
+        "value": 322964422,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "WindshieldWipersState"
+      },
+      {
+        "name": "Windshield wipers switch.",
+        "value": 322964423,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "WindshieldWipersSwitch"
+      },
+      {
+        "name": "Steering wheel depth position",
+        "value": 289410016,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Steering wheel depth movement",
+        "value": 289410017,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Steering wheel height position",
+        "value": 289410018,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Steering wheel height movement",
+        "value": 289410019,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Steering wheel theft lock feature enabled",
+        "value": 287312868,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Steering wheel locked",
+        "value": 287312869,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Steering wheel easy access feature enabled",
+        "value": 287312870,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Property that represents the current position of the glove box door.",
+        "value": 356518896,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Lock or unlock the glove box.",
+        "value": 354421745,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "VEHICLE_MAP_SERVICE",
+        "value": 299895808,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Characterization of inputs used for computing location.",
+        "value": 289410064,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "OBD2 Live Sensor Data",
+        "value": 299896064,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "OBD2 Freeze Frame Sensor Data",
+        "value": 299896065,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "OBD2 Freeze Frame Information",
+        "value": 299896066,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "OBD2 Freeze Frame Clear",
+        "value": 299896067,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Headlights State",
+        "value": 289410560,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "High beam lights state",
+        "value": 289410561,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Fog light state",
+        "value": 289410562,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Hazard light status",
+        "value": 289410563,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Headlight switch",
+        "value": 289410576,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "High beam light switch",
+        "value": 289410577,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Fog light switch",
+        "value": 289410578,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Hazard light switch",
+        "value": 289410579,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Cabin lights",
+        "value": 289410817,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Cabin lights switch",
+        "value": 289410818,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Reading lights",
+        "value": 356519683,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Reading lights switch",
+        "value": 356519684,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Steering wheel lights state",
+        "value": 289410828,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Steering wheel lights switch",
+        "value": 289410829,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Support customize permissions for vendor properties",
+        "value": 287313669,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Allow disabling optional featurs from vhal.",
+        "value": 286265094,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Defines the initial Android user to be used during initialization.",
+        "value": 299896583,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Defines a request to switch the foreground Android user.",
+        "value": 299896584,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Called by the Android System after an Android user was created.",
+        "value": 299896585,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Called by the Android System after an Android user was removed.",
+        "value": 299896586,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "USER_IDENTIFICATION_ASSOCIATION",
+        "value": 299896587,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "EVS_SERVICE_REQUEST",
+        "value": 289476368,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Defines a request to apply power policy.",
+        "value": 286265121,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "POWER_POLICY_GROUP_REQ",
+        "value": 286265122,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Notifies the current power policy to VHAL layer.",
+        "value": 286265123,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "WATCHDOG_ALIVE",
+        "value": 290459441,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Defines a process terminated by car watchdog and the reason of termination.",
+        "value": 299896626,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Defines an event that VHAL signals to car watchdog as a heartbeat.",
+        "value": 290459443,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Starts the ClusterUI in cluster display.",
+        "value": 289410868,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Changes the state of the cluster display.",
+        "value": 289476405,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Reports the current display state and ClusterUI state.",
+        "value": 299896630,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Requests to change the cluster display state to show some ClusterUI.",
+        "value": 289410871,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Informs the current navigation state.",
+        "value": 292556600,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE"
+      },
+      {
+        "name": "Electronic Toll Collection card type.",
+        "value": 289410873,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ElectronicTollCollectionCardType"
+      },
+      {
+        "name": "Electronic Toll Collection card status.",
+        "value": 289410874,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ElectronicTollCollectionCardStatus"
+      },
+      {
+        "name": "Front fog lights state",
+        "value": 289410875,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Front fog lights switch",
+        "value": 289410876,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Rear fog lights state",
+        "value": 289410877,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "VehicleLightState"
+      },
+      {
+        "name": "Rear fog lights switch",
+        "value": 289410878,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "VehicleLightSwitch"
+      },
+      {
+        "name": "Indicates the maximum current draw threshold for charging set by the user",
+        "value": 291508031,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "unit": "VehicleUnit:AMPERE"
+      },
+      {
+        "name": "Indicates the maximum charge percent threshold set by the user",
+        "value": 291508032,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Charging state of the car",
+        "value": 289410881,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "EvChargeState"
+      },
+      {
+        "name": "Start or stop charging the EV battery",
+        "value": 287313730,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Estimated charge time remaining in seconds",
+        "value": 289410883,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:SECS"
+      },
+      {
+        "name": "EV_REGENERATIVE_BRAKING_STATE",
+        "value": 289410884,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "EvRegenerativeBrakingState"
+      },
+      {
+        "name": "Indicates if there is a trailer present or not.",
+        "value": 289410885,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "TrailerState"
+      },
+      {
+        "name": "VEHICLE_CURB_WEIGHT",
+        "value": 289410886,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:KILOGRAM"
+      },
+      {
+        "name": "GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT",
+        "value": 289410887,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "GsrComplianceRequirementType"
+      },
+      {
+        "name": "SUPPORTED_PROPERTY_IDS",
+        "value": 289476424,
+        "change_mode": "VehiclePropertyChangeMode:STATIC",
+        "access": "VehiclePropertyAccess:READ"
+      },
+      {
+        "name": "Request the head unit to be shutdown.",
+        "value": 289410889,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE",
+        "data_enum": "VehicleApPowerStateShutdownParam"
+      },
+      {
+        "name": "Whether the vehicle is currently in use.",
+        "value": 287313738,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "Start of ADAS Properties",
+        "value": 287313920,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "AUTOMATIC_EMERGENCY_BRAKING_STATE",
+        "value": 289411073,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "FORWARD_COLLISION_WARNING_ENABLED",
+        "value": 287313922,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "FORWARD_COLLISION_WARNING_STATE",
+        "value": 289411075,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "BLIND_SPOT_WARNING_ENABLED",
+        "value": 287313924,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "BLIND_SPOT_WARNING_STATE",
+        "value": 339742725,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "LANE_DEPARTURE_WARNING_ENABLED",
+        "value": 287313926,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "LANE_DEPARTURE_WARNING_STATE",
+        "value": 289411079,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "LANE_KEEP_ASSIST_ENABLED",
+        "value": 287313928,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "LANE_KEEP_ASSIST_STATE",
+        "value": 289411081,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "LANE_CENTERING_ASSIST_ENABLED",
+        "value": 287313930,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "LANE_CENTERING_ASSIST_COMMAND",
+        "value": 289411083,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE",
+        "data_enum": "LaneCenteringAssistCommand"
+      },
+      {
+        "name": "LANE_CENTERING_ASSIST_STATE",
+        "value": 289411084,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "EMERGENCY_LANE_KEEP_ASSIST_ENABLED",
+        "value": 287313933
+      },
+      {
+        "name": "EMERGENCY_LANE_KEEP_ASSIST_STATE",
+        "value": 289411086,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "CRUISE_CONTROL_ENABLED",
+        "value": 287313935,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "CRUISE_CONTROL_TYPE",
+        "value": 289411088,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "CRUISE_CONTROL_STATE",
+        "value": 289411089,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "CRUISE_CONTROL_COMMAND",
+        "value": 289411090,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:WRITE",
+        "data_enum": "CruiseControlCommand"
+      },
+      {
+        "name": "CRUISE_CONTROL_TARGET_SPEED",
+        "value": 291508243,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:METER_PER_SEC"
+      },
+      {
+        "name": "ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP",
+        "value": 289411092,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE",
+        "unit": "VehicleUnit:MILLI_SECS"
+      },
+      {
+        "name": "ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE",
+        "value": 289411093,
+        "change_mode": "VehiclePropertyChangeMode:CONTINUOUS",
+        "access": "VehiclePropertyAccess:READ",
+        "unit": "VehicleUnit:MILLIMETER"
+      },
+      {
+        "name": "HANDS_ON_DETECTION_ENABLED",
+        "value": 287313942,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ_WRITE"
+      },
+      {
+        "name": "HANDS_ON_DETECTION_DRIVER_STATE",
+        "value": 289411095,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      },
+      {
+        "name": "HANDS_ON_DETECTION_WARNING",
+        "value": 289411096,
+        "change_mode": "VehiclePropertyChangeMode:ON_CHANGE",
+        "access": "VehiclePropertyAccess:READ",
+        "data_enum": "ErrorState"
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "DiagnosticIntegerSensorIndex",
+    "values": [
+      {
+        "name": "FUEL_SYSTEM_STATUS",
+        "value": 0
+      },
+      {
+        "name": "MALFUNCTION_INDICATOR_LIGHT_ON",
+        "value": 1
+      },
+      {
+        "name": "IGNITION_MONITORS_SUPPORTED",
+        "value": 2
+      },
+      {
+        "name": "IGNITION_SPECIFIC_MONITORS",
+        "value": 3
+      },
+      {
+        "name": "INTAKE_AIR_TEMPERATURE",
+        "value": 4
+      },
+      {
+        "name": "COMMANDED_SECONDARY_AIR_STATUS",
+        "value": 5
+      },
+      {
+        "name": "NUM_OXYGEN_SENSORS_PRESENT",
+        "value": 6
+      },
+      {
+        "name": "RUNTIME_SINCE_ENGINE_START",
+        "value": 7
+      },
+      {
+        "name": "DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON",
+        "value": 8
+      },
+      {
+        "name": "WARMUPS_SINCE_CODES_CLEARED",
+        "value": 9
+      },
+      {
+        "name": "DISTANCE_TRAVELED_SINCE_CODES_CLEARED",
+        "value": 10
+      },
+      {
+        "name": "ABSOLUTE_BAROMETRIC_PRESSURE",
+        "value": 11
+      },
+      {
+        "name": "CONTROL_MODULE_VOLTAGE",
+        "value": 12
+      },
+      {
+        "name": "AMBIENT_AIR_TEMPERATURE",
+        "value": 13
+      },
+      {
+        "name": "TIME_WITH_MALFUNCTION_LIGHT_ON",
+        "value": 14
+      },
+      {
+        "name": "TIME_SINCE_TROUBLE_CODES_CLEARED",
+        "value": 15
+      },
+      {
+        "name": "MAX_FUEL_AIR_EQUIVALENCE_RATIO",
+        "value": 16
+      },
+      {
+        "name": "MAX_OXYGEN_SENSOR_VOLTAGE",
+        "value": 17
+      },
+      {
+        "name": "MAX_OXYGEN_SENSOR_CURRENT",
+        "value": 18
+      },
+      {
+        "name": "MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE",
+        "value": 19
+      },
+      {
+        "name": "MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR",
+        "value": 20
+      },
+      {
+        "name": "FUEL_TYPE",
+        "value": 21
+      },
+      {
+        "name": "FUEL_RAIL_ABSOLUTE_PRESSURE",
+        "value": 22
+      },
+      {
+        "name": "ENGINE_OIL_TEMPERATURE",
+        "value": 23
+      },
+      {
+        "name": "DRIVER_DEMAND_PERCENT_TORQUE",
+        "value": 24
+      },
+      {
+        "name": "ENGINE_ACTUAL_PERCENT_TORQUE",
+        "value": 25
+      },
+      {
+        "name": "ENGINE_REFERENCE_PERCENT_TORQUE",
+        "value": 26
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_IDLE",
+        "value": 27
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT1",
+        "value": 28
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT2",
+        "value": 29
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT3",
+        "value": 30
+      },
+      {
+        "name": "ENGINE_PERCENT_TORQUE_DATA_POINT4",
+        "value": 31
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VehicleUnit",
+    "values": [
+      {
+        "name": "SHOULD_NOT_USE",
+        "value": 0
+      },
+      {
+        "name": "METER_PER_SEC",
+        "value": 1
+      },
+      {
+        "name": "RPM",
+        "value": 2
+      },
+      {
+        "name": "HERTZ",
+        "value": 3
+      },
+      {
+        "name": "PERCENTILE",
+        "value": 16
+      },
+      {
+        "name": "MILLIMETER",
+        "value": 32
+      },
+      {
+        "name": "METER",
+        "value": 33
+      },
+      {
+        "name": "KILOMETER",
+        "value": 35
+      },
+      {
+        "name": "MILE",
+        "value": 36
+      },
+      {
+        "name": "CELSIUS",
+        "value": 48
+      },
+      {
+        "name": "FAHRENHEIT",
+        "value": 49
+      },
+      {
+        "name": "KELVIN",
+        "value": 50
+      },
+      {
+        "name": "MILLILITER",
+        "value": 64
+      },
+      {
+        "name": "LITER",
+        "value": 65
+      },
+      {
+        "name": "GALLON",
+        "value": 66
+      },
+      {
+        "name": "US_GALLON",
+        "value": 66
+      },
+      {
+        "name": "IMPERIAL_GALLON",
+        "value": 67
+      },
+      {
+        "name": "NANO_SECS",
+        "value": 80
+      },
+      {
+        "name": "MILLI_SECS",
+        "value": 81
+      },
+      {
+        "name": "SECS",
+        "value": 83
+      },
+      {
+        "name": "YEAR",
+        "value": 89
+      },
+      {
+        "name": "WATT_HOUR",
+        "value": 96
+      },
+      {
+        "name": "MILLIAMPERE",
+        "value": 97
+      },
+      {
+        "name": "MILLIVOLT",
+        "value": 98
+      },
+      {
+        "name": "MILLIWATTS",
+        "value": 99
+      },
+      {
+        "name": "AMPERE_HOURS",
+        "value": 100
+      },
+      {
+        "name": "KILOWATT_HOUR",
+        "value": 101
+      },
+      {
+        "name": "AMPERE",
+        "value": 102
+      },
+      {
+        "name": "KILOPASCAL",
+        "value": 112
+      },
+      {
+        "name": "PSI",
+        "value": 113
+      },
+      {
+        "name": "BAR",
+        "value": 114
+      },
+      {
+        "name": "DEGREES",
+        "value": 128
+      },
+      {
+        "name": "MILES_PER_HOUR",
+        "value": 144
+      },
+      {
+        "name": "KILOMETERS_PER_HOUR",
+        "value": 145
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "LaneCenteringAssistCommand",
+    "values": [
+      {
+        "name": "ACTIVATE",
+        "value": 1
+      },
+      {
+        "name": "DEACTIVATE",
+        "value": 2
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "Obd2FuelType",
+    "values": [
+      {
+        "name": "NOT_AVAILABLE",
+        "value": 0
+      },
+      {
+        "name": "GASOLINE",
+        "value": 1
+      },
+      {
+        "name": "METHANOL",
+        "value": 2
+      },
+      {
+        "name": "ETHANOL",
+        "value": 3
+      },
+      {
+        "name": "DIESEL",
+        "value": 4
+      },
+      {
+        "name": "LPG",
+        "value": 5
+      },
+      {
+        "name": "CNG",
+        "value": 6
+      },
+      {
+        "name": "PROPANE",
+        "value": 7
+      },
+      {
+        "name": "ELECTRIC",
+        "value": 8
+      },
+      {
+        "name": "BIFUEL_RUNNING_GASOLINE",
+        "value": 9
+      },
+      {
+        "name": "BIFUEL_RUNNING_METHANOL",
+        "value": 10
+      },
+      {
+        "name": "BIFUEL_RUNNING_ETHANOL",
+        "value": 11
+      },
+      {
+        "name": "BIFUEL_RUNNING_LPG",
+        "value": 12
+      },
+      {
+        "name": "BIFUEL_RUNNING_CNG",
+        "value": 13
+      },
+      {
+        "name": "BIFUEL_RUNNING_PROPANE",
+        "value": 14
+      },
+      {
+        "name": "BIFUEL_RUNNING_ELECTRIC",
+        "value": 15
+      },
+      {
+        "name": "BIFUEL_RUNNING_ELECTRIC_AND_COMBUSTION",
+        "value": 16
+      },
+      {
+        "name": "HYBRID_GASOLINE",
+        "value": 17
+      },
+      {
+        "name": "HYBRID_ETHANOL",
+        "value": 18
+      },
+      {
+        "name": "HYBRID_DIESEL",
+        "value": 19
+      },
+      {
+        "name": "HYBRID_ELECTRIC",
+        "value": 20
+      },
+      {
+        "name": "HYBRID_RUNNING_ELECTRIC_AND_COMBUSTION",
+        "value": 21
+      },
+      {
+        "name": "HYBRID_REGENERATIVE",
+        "value": 22
+      },
+      {
+        "name": "BIFUEL_RUNNING_DIESEL",
+        "value": 23
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "ProcessTerminationReason",
+    "values": [
+      {
+        "name": "NOT_RESPONDING",
+        "value": 1
+      },
+      {
+        "name": "IO_OVERUSE",
+        "value": 2
+      },
+      {
+        "name": "MEMORY_OVERUSE",
+        "value": 3
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "VmsMessageWithLayerAndPublisherIdIntegerValuesIndex",
     "values": [
       {
         "name": "MESSAGE_TYPE",
         "value": 0
       },
       {
-        "name": "PUBLISHER_ID",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "RotaryInputType",
-    "values": [
-      {
-        "name": "ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION",
-        "value": 0
-      },
-      {
-        "name": "ROTARY_INPUT_TYPE_AUDIO_VOLUME",
-        "value": 1
-      }
-    ]
-  },
-  {
-    "name": "Obd2FuelSystemStatus",
-    "values": [
-      {
-        "name": "OPEN_INSUFFICIENT_ENGINE_TEMPERATURE",
+        "name": "LAYER_TYPE",
         "value": 1
       },
       {
-        "name": "CLOSED_LOOP",
+        "name": "LAYER_SUBTYPE",
         "value": 2
       },
       {
-        "name": "OPEN_ENGINE_LOAD_OR_DECELERATION",
+        "name": "LAYER_VERSION",
+        "value": 3
+      },
+      {
+        "name": "PUBLISHER_ID",
         "value": 4
+      }
+    ]
+  },
+  {
+    "package": "android.hardware.automotive.vehicle",
+    "name": "EvChargeState",
+    "values": [
+      {
+        "name": "UNKNOWN",
+        "value": 0
       },
       {
-        "name": "OPEN_SYSTEM_FAILURE",
-        "value": 8
+        "name": "CHARGING",
+        "value": 1
       },
       {
-        "name": "CLOSED_LOOP_BUT_FEEDBACK_FAULT",
-        "value": 16
+        "name": "FULLY_CHARGED",
+        "value": 2
+      },
+      {
+        "name": "NOT_CHARGING",
+        "value": 3
+      },
+      {
+        "name": "ERROR",
+        "value": 4
       }
     ]
   }
diff --git a/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py b/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py
index b2eb172..5706571 100755
--- a/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py
+++ b/automotive/vehicle/aidl/emu_metadata/generate_emulator_metadata.py
@@ -19,23 +19,56 @@
 
 from pathlib import Path
 
+RE_PACKAGE = re.compile(r"\npackage\s([\.a-z0-9]*);")
+RE_IMPORT = re.compile(r"\nimport\s([\.a-zA-Z0-9]*);")
 RE_ENUM = re.compile(r"\s*enum\s+(\w*) {\n(.*)}", re.MULTILINE | re.DOTALL)
-RE_COMMENT = re.compile(r"(?:(?:\/\*\*)((?:.|\n)*?)(?:\*\/))?(?:\n|^)\s*(\w*)(?:\s+=\s*)?((?:[a-zA-Z0-9]|\s|\+|)*),", re.DOTALL)
+RE_COMMENT = re.compile(r"(?:(?:\/\*\*)((?:.|\n)*?)(?:\*\/))?(?:\n|^)\s*(\w*)(?:\s+=\s*)?((?:[\.\-a-zA-Z0-9]|\s|\+|)*),",
+                        re.DOTALL)
 RE_BLOCK_COMMENT_TITLE = re.compile("^(?:\s|\*)*((?:\w|\s|\.)*)\n(?:\s|\*)*(?:\n|$)")
-RE_BLOCK_COMMENT_ANNOTATION = re.compile("^(?:\s|\*)*@(\w*)\s+((?:\w|:)*)", re.MULTILINE)
-RE_HEX_NUMBER = re.compile("([0-9A-Fa-fxX]+)")
+RE_BLOCK_COMMENT_ANNOTATION = re.compile("^(?:\s|\*)*@(\w*)\s+((?:[\w:\.])*)", re.MULTILINE)
+RE_HEX_NUMBER = re.compile("([\.\-0-9A-Za-z]+)")
 
 
 class JEnum:
-    def __init__(self, name):
+    def __init__(self, package, name):
+        self.package = package
         self.name = name
         self.values = []
 
+class Enum:
+    def __init__(self, package, name, text, imports):
+        self.text = text
+        self.parsed = False
+        self.imports = imports
+        self.jenum = JEnum(package, name)
 
-class Converter:
-    # Only addition is supported for now, but that covers all existing properties except
-    # OBD diagnostics, which use bitwise shifts
-    def calculateValue(self, expression, default_value):
+    def parse(self, enums):
+        if self.parsed:
+            return
+        for dep in self.imports:
+            enums[dep].parse(enums)
+        print("Parsing " + self.jenum.name)
+        matches = RE_COMMENT.findall(self.text)
+        defaultValue = 0
+        for match in matches:
+            value = dict()
+            value['name'] = match[1]
+            value['value'] = self.calculateValue(match[2], defaultValue, enums)
+            defaultValue = value['value'] + 1
+            if self.jenum.name == "VehicleProperty":
+                block_comment = match[0]
+                self.parseBlockComment(value, block_comment)
+            self.jenum.values.append(value)
+        self.parsed = True
+        self.text = None
+
+    def get_value(self, value_name):
+        for value in self.jenum.values:
+            if value['name'] == value_name:
+                return value['value']
+        raise Exception("Cannot decode value: " + self.jenum.package + " : " + value_name)
+
+    def calculateValue(self, expression, default_value, enums):
         numbers = RE_HEX_NUMBER.findall(expression)
         if len(numbers) == 0:
             return default_value
@@ -44,7 +77,13 @@
         if numbers[0].lower().startswith("0x"):
             base = 16
         for number in numbers:
-            result += int(number, base)
+            if '.' in number:
+                package, val_name = number.split('.')
+                for dep in self.imports:
+                    if package in dep:
+                        result += enums[dep].get_value(val_name)
+            else:
+                result += int(number, base)
         return result
 
     def parseBlockComment(self, value, blockComment):
@@ -54,30 +93,22 @@
             break
         annots_res = RE_BLOCK_COMMENT_ANNOTATION.findall(blockComment)
         for annot in annots_res:
-            value[annot[0]] = annot[1]
+            value[annot[0]] = annot[1].replace(".", ":")
 
-    def parseEnumContents(self, enum: JEnum, enumValue):
-        matches = RE_COMMENT.findall(enumValue)
-        defaultValue = 0
-        for match in matches:
-            value = dict()
-            value['name'] = match[1]
-            value['value'] = self.calculateValue(match[2], defaultValue)
-            defaultValue = value['value'] + 1
-            if enum.name == "VehicleProperty":
-                block_comment = match[0]
-                self.parseBlockComment(value, block_comment)
-            enum.values.append(value)
-
+class Converter:
+    # Only addition is supported for now, but that covers all existing properties except
+    # OBD diagnostics, which use bitwise shifts
     def convert(self, input):
         text = Path(input).read_text()
         matches = RE_ENUM.findall(text)
-        jenums = []
+        package = RE_PACKAGE.findall(text)[0]
+        imports = RE_IMPORT.findall(text)
+        enums = []
         for match in matches:
-            enum = JEnum(match[0])
-            self.parseEnumContents(enum, match[1])
-            jenums.append(enum)
-        return jenums
+            enum = Enum(package, match[0], match[1], imports)
+            enums.append(enum)
+        return enums
+
 
 def main():
     if (len(sys.argv) != 3):
@@ -85,10 +116,18 @@
         sys.exit(1)
     aidl_path = sys.argv[1]
     out_path = sys.argv[2]
-    result = []
+    enums_dict = dict()
     for file in os.listdir(aidl_path):
-        result.extend(Converter().convert(os.path.join(aidl_path, file)))
-    json_result = json.dumps(result, default=vars, indent=2)
+        enums = Converter().convert(os.path.join(aidl_path, file))
+        for enum in enums:
+            enums_dict[enum.jenum.package + "." + enum.jenum.name] = enum
+
+    result = []
+    for enum_name, enum in enums_dict.items():
+        enum.parse(enums_dict)
+        result.append(enum.jenum.__dict__)
+
+    json_result = json.dumps(result, default=None, indent=2)
     with open(out_path, 'w') as f:
         f.write(json_result)
 
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index a8effcb..15056e2 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -22,8 +22,7 @@
 
 // clang-format off
 
-#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
-#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+#pragma once
 
 #include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
 #include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
@@ -309,5 +308,3 @@
 }  // namespace hardware
 }  // namespace android
 }  // aidl
-
-#endif  // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
index 3321c20..d3f97e3 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
@@ -22,8 +22,7 @@
 
 // clang-format off
 
-#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
-#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+#pragma once
 
 #include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
 #include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
@@ -309,5 +308,3 @@
 }  // namespace hardware
 }  // namespace android
 }  // aidl
-
-#endif  // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
new file mode 100644
index 0000000..70c914d
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
@@ -0,0 +1,309 @@
+/*
+ * 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.
+ */
+
+/**
+ * DO NOT EDIT MANUALLY!!!
+ *
+ * Generated by tools/generate_annotation_enums.py.
+ */
+
+// clang-format off
+
+#pragma once
+
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, int32_t> VersionForVehicleProperty = {
+        {VehicleProperty::INFO_VIN, 2},
+        {VehicleProperty::INFO_MAKE, 2},
+        {VehicleProperty::INFO_MODEL, 2},
+        {VehicleProperty::INFO_MODEL_YEAR, 2},
+        {VehicleProperty::INFO_FUEL_CAPACITY, 2},
+        {VehicleProperty::INFO_FUEL_TYPE, 2},
+        {VehicleProperty::INFO_EV_BATTERY_CAPACITY, 2},
+        {VehicleProperty::INFO_EV_CONNECTOR_TYPE, 2},
+        {VehicleProperty::INFO_FUEL_DOOR_LOCATION, 2},
+        {VehicleProperty::INFO_EV_PORT_LOCATION, 2},
+        {VehicleProperty::INFO_DRIVER_SEAT, 2},
+        {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, 2},
+        {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, 2},
+        {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::ENGINE_COOLANT_TEMP, 2},
+        {VehicleProperty::ENGINE_OIL_LEVEL, 2},
+        {VehicleProperty::ENGINE_OIL_TEMP, 2},
+        {VehicleProperty::ENGINE_RPM, 2},
+        {VehicleProperty::WHEEL_TICK, 2},
+        {VehicleProperty::FUEL_LEVEL, 2},
+        {VehicleProperty::FUEL_DOOR_OPEN, 2},
+        {VehicleProperty::EV_BATTERY_LEVEL, 2},
+        {VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, 2},
+        {VehicleProperty::EV_CHARGE_PORT_OPEN, 2},
+        {VehicleProperty::EV_CHARGE_PORT_CONNECTED, 2},
+        {VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, 2},
+        {VehicleProperty::RANGE_REMAINING, 2},
+        {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, 3},
+        {VehicleProperty::TIRE_PRESSURE, 2},
+        {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, 2},
+        {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, 2},
+        {VehicleProperty::IMPACT_DETECTED, 3},
+        {VehicleProperty::GEAR_SELECTION, 2},
+        {VehicleProperty::CURRENT_GEAR, 2},
+        {VehicleProperty::PARKING_BRAKE_ON, 2},
+        {VehicleProperty::PARKING_BRAKE_AUTO_APPLY, 2},
+        {VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, 2},
+        {VehicleProperty::FUEL_LEVEL_LOW, 2},
+        {VehicleProperty::NIGHT_MODE, 2},
+        {VehicleProperty::TURN_SIGNAL_STATE, 2},
+        {VehicleProperty::IGNITION_STATE, 2},
+        {VehicleProperty::ABS_ACTIVE, 2},
+        {VehicleProperty::TRACTION_CONTROL_ACTIVE, 2},
+        {VehicleProperty::EV_STOPPING_MODE, 2},
+        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, 3},
+        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, 2},
+        {VehicleProperty::HVAC_FAN_SPEED, 2},
+        {VehicleProperty::HVAC_FAN_DIRECTION, 2},
+        {VehicleProperty::HVAC_TEMPERATURE_CURRENT, 2},
+        {VehicleProperty::HVAC_TEMPERATURE_SET, 2},
+        {VehicleProperty::HVAC_DEFROSTER, 2},
+        {VehicleProperty::HVAC_AC_ON, 2},
+        {VehicleProperty::HVAC_MAX_AC_ON, 2},
+        {VehicleProperty::HVAC_MAX_DEFROST_ON, 2},
+        {VehicleProperty::HVAC_RECIRC_ON, 2},
+        {VehicleProperty::HVAC_DUAL_ON, 2},
+        {VehicleProperty::HVAC_AUTO_ON, 2},
+        {VehicleProperty::HVAC_SEAT_TEMPERATURE, 2},
+        {VehicleProperty::HVAC_SIDE_MIRROR_HEAT, 2},
+        {VehicleProperty::HVAC_STEERING_WHEEL_HEAT, 2},
+        {VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, 2},
+        {VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, 2},
+        {VehicleProperty::HVAC_POWER_ON, 2},
+        {VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, 2},
+        {VehicleProperty::HVAC_AUTO_RECIRC_ON, 2},
+        {VehicleProperty::HVAC_SEAT_VENTILATION, 2},
+        {VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, 2},
+        {VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, 2},
+        {VehicleProperty::DISTANCE_DISPLAY_UNITS, 2},
+        {VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, 2},
+        {VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, 2},
+        {VehicleProperty::EV_BATTERY_DISPLAY_UNITS, 2},
+        {VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, 2},
+        {VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, 2},
+        {VehicleProperty::EXTERNAL_CAR_TIME, 2},
+        {VehicleProperty::ANDROID_EPOCH_TIME, 2},
+        {VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, 2},
+        {VehicleProperty::ENV_OUTSIDE_TEMPERATURE, 2},
+        {VehicleProperty::AP_POWER_STATE_REQ, 2},
+        {VehicleProperty::AP_POWER_STATE_REPORT, 2},
+        {VehicleProperty::AP_POWER_BOOTUP_REASON, 2},
+        {VehicleProperty::DISPLAY_BRIGHTNESS, 2},
+        {VehicleProperty::PER_DISPLAY_BRIGHTNESS, 2},
+        {VehicleProperty::VALET_MODE_ENABLED, 3},
+        {VehicleProperty::HEAD_UP_DISPLAY_ENABLED, 3},
+        {VehicleProperty::HW_KEY_INPUT, 2},
+        {VehicleProperty::HW_KEY_INPUT_V2, 2},
+        {VehicleProperty::HW_MOTION_INPUT, 2},
+        {VehicleProperty::HW_ROTARY_INPUT, 2},
+        {VehicleProperty::HW_CUSTOM_INPUT, 2},
+        {VehicleProperty::DOOR_POS, 2},
+        {VehicleProperty::DOOR_MOVE, 2},
+        {VehicleProperty::DOOR_LOCK, 2},
+        {VehicleProperty::DOOR_CHILD_LOCK_ENABLED, 2},
+        {VehicleProperty::MIRROR_Z_POS, 2},
+        {VehicleProperty::MIRROR_Z_MOVE, 2},
+        {VehicleProperty::MIRROR_Y_POS, 2},
+        {VehicleProperty::MIRROR_Y_MOVE, 2},
+        {VehicleProperty::MIRROR_LOCK, 2},
+        {VehicleProperty::MIRROR_FOLD, 2},
+        {VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, 2},
+        {VehicleProperty::MIRROR_AUTO_TILT_ENABLED, 2},
+        {VehicleProperty::SEAT_MEMORY_SELECT, 2},
+        {VehicleProperty::SEAT_MEMORY_SET, 2},
+        {VehicleProperty::SEAT_BELT_BUCKLED, 2},
+        {VehicleProperty::SEAT_BELT_HEIGHT_POS, 2},
+        {VehicleProperty::SEAT_BELT_HEIGHT_MOVE, 2},
+        {VehicleProperty::SEAT_FORE_AFT_POS, 2},
+        {VehicleProperty::SEAT_FORE_AFT_MOVE, 2},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, 2},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, 2},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, 2},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, 2},
+        {VehicleProperty::SEAT_HEIGHT_POS, 2},
+        {VehicleProperty::SEAT_HEIGHT_MOVE, 2},
+        {VehicleProperty::SEAT_DEPTH_POS, 2},
+        {VehicleProperty::SEAT_DEPTH_MOVE, 2},
+        {VehicleProperty::SEAT_TILT_POS, 2},
+        {VehicleProperty::SEAT_TILT_MOVE, 2},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, 2},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, 2},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, 2},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, 2},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, 2},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, 2},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, 2},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_POS, 2},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, 2},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, 2},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, 2},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, 2},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, 2},
+        {VehicleProperty::SEAT_EASY_ACCESS_ENABLED, 2},
+        {VehicleProperty::SEAT_AIRBAG_ENABLED, 3},
+        {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, 2},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, 2},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, 2},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, 2},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, 2},
+        {VehicleProperty::SEAT_WALK_IN_POS, 2},
+        {VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, 3},
+        {VehicleProperty::SEAT_OCCUPANCY, 2},
+        {VehicleProperty::WINDOW_POS, 2},
+        {VehicleProperty::WINDOW_MOVE, 2},
+        {VehicleProperty::WINDOW_LOCK, 2},
+        {VehicleProperty::WINDSHIELD_WIPERS_PERIOD, 2},
+        {VehicleProperty::WINDSHIELD_WIPERS_STATE, 2},
+        {VehicleProperty::WINDSHIELD_WIPERS_SWITCH, 2},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_POS, 2},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, 2},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_POS, 2},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, 2},
+        {VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, 2},
+        {VehicleProperty::STEERING_WHEEL_LOCKED, 2},
+        {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, 2},
+        {VehicleProperty::GLOVE_BOX_DOOR_POS, 2},
+        {VehicleProperty::GLOVE_BOX_LOCKED, 2},
+        {VehicleProperty::VEHICLE_MAP_SERVICE, 2},
+        {VehicleProperty::LOCATION_CHARACTERIZATION, 2},
+        {VehicleProperty::ULTRASONICS_SENSOR_POSITION, 3},
+        {VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, 3},
+        {VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, 3},
+        {VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, 3},
+        {VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, 3},
+        {VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, 3},
+        {VehicleProperty::OBD2_LIVE_FRAME, 2},
+        {VehicleProperty::OBD2_FREEZE_FRAME, 2},
+        {VehicleProperty::OBD2_FREEZE_FRAME_INFO, 2},
+        {VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, 2},
+        {VehicleProperty::HEADLIGHTS_STATE, 2},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_STATE, 2},
+        {VehicleProperty::FOG_LIGHTS_STATE, 2},
+        {VehicleProperty::HAZARD_LIGHTS_STATE, 2},
+        {VehicleProperty::HEADLIGHTS_SWITCH, 2},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, 2},
+        {VehicleProperty::FOG_LIGHTS_SWITCH, 2},
+        {VehicleProperty::HAZARD_LIGHTS_SWITCH, 2},
+        {VehicleProperty::CABIN_LIGHTS_STATE, 2},
+        {VehicleProperty::CABIN_LIGHTS_SWITCH, 2},
+        {VehicleProperty::READING_LIGHTS_STATE, 2},
+        {VehicleProperty::READING_LIGHTS_SWITCH, 2},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, 2},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, 2},
+        {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, 2},
+        {VehicleProperty::DISABLED_OPTIONAL_FEATURES, 2},
+        {VehicleProperty::INITIAL_USER_INFO, 2},
+        {VehicleProperty::SWITCH_USER, 2},
+        {VehicleProperty::CREATE_USER, 2},
+        {VehicleProperty::REMOVE_USER, 2},
+        {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, 2},
+        {VehicleProperty::EVS_SERVICE_REQUEST, 2},
+        {VehicleProperty::POWER_POLICY_REQ, 2},
+        {VehicleProperty::POWER_POLICY_GROUP_REQ, 2},
+        {VehicleProperty::CURRENT_POWER_POLICY, 2},
+        {VehicleProperty::WATCHDOG_ALIVE, 2},
+        {VehicleProperty::WATCHDOG_TERMINATED_PROCESS, 2},
+        {VehicleProperty::VHAL_HEARTBEAT, 2},
+        {VehicleProperty::CLUSTER_SWITCH_UI, 2},
+        {VehicleProperty::CLUSTER_DISPLAY_STATE, 2},
+        {VehicleProperty::CLUSTER_REPORT_STATE, 2},
+        {VehicleProperty::CLUSTER_REQUEST_DISPLAY, 2},
+        {VehicleProperty::CLUSTER_NAVIGATION_STATE, 2},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, 2},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, 2},
+        {VehicleProperty::FRONT_FOG_LIGHTS_STATE, 2},
+        {VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, 2},
+        {VehicleProperty::REAR_FOG_LIGHTS_STATE, 2},
+        {VehicleProperty::REAR_FOG_LIGHTS_SWITCH, 2},
+        {VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, 2},
+        {VehicleProperty::EV_CHARGE_PERCENT_LIMIT, 2},
+        {VehicleProperty::EV_CHARGE_STATE, 2},
+        {VehicleProperty::EV_CHARGE_SWITCH, 2},
+        {VehicleProperty::EV_CHARGE_TIME_REMAINING, 2},
+        {VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, 2},
+        {VehicleProperty::TRAILER_PRESENT, 2},
+        {VehicleProperty::VEHICLE_CURB_WEIGHT, 2},
+        {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, 2},
+        {VehicleProperty::SUPPORTED_PROPERTY_IDS, 2},
+        {VehicleProperty::SHUTDOWN_REQUEST, 2},
+        {VehicleProperty::VEHICLE_IN_USE, 2},
+        {VehicleProperty::CLUSTER_HEARTBEAT, 3},
+        {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, 3},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 2},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, 2},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, 2},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_STATE, 2},
+        {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, 2},
+        {VehicleProperty::BLIND_SPOT_WARNING_STATE, 2},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, 2},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_STATE, 2},
+        {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, 2},
+        {VehicleProperty::LANE_KEEP_ASSIST_STATE, 2},
+        {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, 2},
+        {VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, 2},
+        {VehicleProperty::LANE_CENTERING_ASSIST_STATE, 2},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, 2},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, 2},
+        {VehicleProperty::CRUISE_CONTROL_ENABLED, 2},
+        {VehicleProperty::CRUISE_CONTROL_TYPE, 2},
+        {VehicleProperty::CRUISE_CONTROL_STATE, 2},
+        {VehicleProperty::CRUISE_CONTROL_COMMAND, 2},
+        {VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, 2},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, 2},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, 2},
+        {VehicleProperty::HANDS_ON_DETECTION_ENABLED, 2},
+        {VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, 2},
+        {VehicleProperty::HANDS_ON_DETECTION_WARNING, 2},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, 3},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, 3},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, 3},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, 3},
+        {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, 3},
+        {VehicleProperty::DRIVER_DISTRACTION_STATE, 3},
+        {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, 2},
+        {VehicleProperty::DRIVER_DISTRACTION_WARNING, 3},
+        {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, 3},
+        {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, 3},
+        {VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, 3},
+        {VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, 3},
+        {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 3},
+        {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, 3},
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+}  // aidl
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
index 8cd92b3..96eff0e 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h
@@ -294,7 +294,7 @@
     void registerRefreshLocked(PropIdAreaId propIdAreaId, VehiclePropertyStore::EventMode eventMode,
                                float sampleRateHz) REQUIRES(mLock);
     void unregisterRefreshLocked(PropIdAreaId propIdAreaId) REQUIRES(mLock);
-    void refreshTimeStampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
+    void refreshTimestampForInterval(int64_t intervalInNanos) EXCLUDES(mLock);
 
     static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
             aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
index 385f616..d95ffd6 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -2109,7 +2109,7 @@
     return false;
 }
 
-void FakeVehicleHardware::refreshTimeStampForInterval(int64_t intervalInNanos) {
+void FakeVehicleHardware::refreshTimestampForInterval(int64_t intervalInNanos) {
     std::unordered_map<PropIdAreaId, VehiclePropertyStore::EventMode, PropIdAreaIdHash>
             eventModeByPropIdAreaId;
 
@@ -2159,7 +2159,7 @@
 
     // This is the first action for the interval, register a timer callback for that interval.
     auto action = std::make_shared<RecurrentTimer::Callback>(
-            [this, intervalInNanos] { refreshTimeStampForInterval(intervalInNanos); });
+            [this, intervalInNanos] { refreshTimestampForInterval(intervalInNanos); });
     mActionByIntervalInNanos[intervalInNanos] = ActionForInterval{
             .propIdAreaIdsToRefresh = {propIdAreaId},
             .recurrentAction = action,
@@ -2201,7 +2201,7 @@
         case VehiclePropertyChangeMode::CONTINUOUS:
             if (sampleRateHz == 0.f) {
                 ALOGE("Must not use sample rate 0 for a continuous property");
-                return StatusCode::INTERNAL_ERROR;
+                return StatusCode::INVALID_ARG;
             }
             // For continuous properties, we must generate a new onPropertyChange event
             // periodically according to the sample rate.
diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
index 6d2efd5..909c89d 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp
@@ -3444,6 +3444,14 @@
             << "must not receive on change events if the propId, areaId is unsubscribed";
 }
 
+TEST_F(FakeVehicleHardwareTest, testSubscribeContinuous_rate0_mustReturnInvalidArg) {
+    int32_t propSpeed = toInt(VehicleProperty::PERF_VEHICLE_SPEED);
+    int32_t areaId = 0;
+    auto status = getHardware()->subscribe(newSubscribeOptions(propSpeed, areaId, 0));
+
+    ASSERT_EQ(status, StatusCode::INVALID_ARG);
+}
+
 TEST_F(FakeVehicleHardwareTest, testSetHvacTemperatureValueSuggestion) {
     float CELSIUS = static_cast<float>(toInt(VehicleUnit::CELSIUS));
     float FAHRENHEIT = static_cast<float>(toInt(VehicleUnit::FAHRENHEIT));
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
index 6e812d1..501ce40 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleObjectPool.h
@@ -235,7 +235,7 @@
 
     bool isDisposable(aidl::android::hardware::automotive::vehicle::VehiclePropertyType type,
                       size_t vectorSize) const {
-        return vectorSize > mMaxRecyclableVectorSize || isComplexType(type);
+        return vectorSize == 0 || vectorSize > mMaxRecyclableVectorSize || isComplexType(type);
     }
 
     RecyclableType obtainDisposable(
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
index 546421e..523cac5 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h
@@ -124,7 +124,6 @@
             break;  // Valid, but nothing to do.
         default:
             ALOGE("createVehiclePropValue: unknown type: %d", toInt(type));
-            val.reset(nullptr);
     }
     return val;
 }
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp
index 2480a73..7e02767 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehicleObjectPool.cpp
@@ -55,13 +55,6 @@
     int propId = src.prop;
     VehiclePropertyType type = getPropType(propId);
     size_t vectorSize = getVehicleRawValueVectorSize(src.value, type);
-    if (vectorSize == 0 && !isComplexType(type)) {
-        ALOGW("empty vehicle prop value, contains no content");
-        ALOGW("empty vehicle prop value, contains no content, prop: %d", propId);
-        // Return any empty VehiclePropValue.
-        return RecyclableType{new VehiclePropValue{}, mDisposableDeleter};
-    }
-
     auto dest = obtain(type, vectorSize);
 
     dest->prop = propId;
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp
index a62532c..6226e89 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehicleObjectPoolTest.cpp
@@ -267,6 +267,20 @@
     ASSERT_EQ(*gotValue, prop);
 }
 
+TEST_F(VehicleObjectPoolTest, testObtainCopyInt32ValuesEmptyArray) {
+    VehiclePropValue prop{
+            // INT32_VEC property.
+            .prop = toInt(VehicleProperty::INFO_FUEL_TYPE),
+            .areaId = 2,
+            .timestamp = 3,
+            .value = {.int32Values = {}},
+    };
+    auto gotValue = mValuePool->obtain(prop);
+
+    ASSERT_NE(gotValue, nullptr);
+    ASSERT_EQ(*gotValue, prop);
+}
+
 TEST_F(VehicleObjectPoolTest, testObtainCopyInt64Values) {
     VehiclePropValue prop{
             // INT64_VEC property.
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index c29345f..20bba7f 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -61,6 +61,7 @@
     ],
     header_libs: [
         "IVehicleHardware",
+        "IVehicleGeneratedHeaders",
     ],
     shared_libs: [
         "libbinder_ndk",
diff --git a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
index f7a71b4..250b30c 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -49,6 +49,9 @@
 
     explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
 
+    // Test-only
+    DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware, int32_t testInterfaceVersion);
+
     ~DefaultVehicleHal();
 
     ndk::ScopedAStatus getAllPropConfigs(
@@ -153,6 +156,8 @@
             mPropertyChangeEventsBatchingConsumer;
     // Only set once during initialization.
     std::chrono::nanoseconds mEventBatchingWindow;
+    // Only used for testing.
+    int32_t mTestInterfaceVersion = 0;
 
     std::mutex mLock;
     std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
@@ -227,6 +232,8 @@
             std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
                     batchedEvents);
 
+    int32_t getVhalInterfaceVersion();
+
     // Puts the property change events into a queue so that they can handled in batch.
     static void batchPropertyChangeEvent(
             const std::weak_ptr<ConcurrentQueue<
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index 76d2f31..cc5edcc 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -22,6 +22,7 @@
 #include <LargeParcelableBase.h>
 #include <VehicleHalTypes.h>
 #include <VehicleUtils.h>
+#include <VersionForVehicleProperty.h>
 
 #include <android-base/result.h>
 #include <android-base/stringprintf.h>
@@ -61,6 +62,7 @@
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyStatus;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue;
+using ::aidl::android::hardware::automotive::vehicle::VersionForVehicleProperty;
 using ::android::automotive::car_binder_lib::LargeParcelableBase;
 using ::android::base::Error;
 using ::android::base::expected;
@@ -94,8 +96,13 @@
 }  // namespace
 
 DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware)
+    : DefaultVehicleHal(std::move(vehicleHardware), /* testInterfaceVersion= */ 0){};
+
+DefaultVehicleHal::DefaultVehicleHal(std::unique_ptr<IVehicleHardware> vehicleHardware,
+                                     int32_t testInterfaceVersion)
     : mVehicleHardware(std::move(vehicleHardware)),
-      mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)) {
+      mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)),
+      mTestInterfaceVersion(testInterfaceVersion) {
     if (!getAllPropConfigsFromHardware()) {
         return;
     }
@@ -312,13 +319,46 @@
     mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano);
 }
 
+int32_t DefaultVehicleHal::getVhalInterfaceVersion() {
+    if (mTestInterfaceVersion != 0) {
+        return mTestInterfaceVersion;
+    }
+    int32_t myVersion = 0;
+    getInterfaceVersion(&myVersion);
+    return myVersion;
+}
+
 bool DefaultVehicleHal::getAllPropConfigsFromHardware() {
     auto configs = mVehicleHardware->getAllPropertyConfigs();
+    std::vector<VehiclePropConfig> filteredConfigs;
+    int32_t myVersion = getVhalInterfaceVersion();
     for (auto& config : configs) {
+        if (!isSystemProp(config.prop)) {
+            filteredConfigs.push_back(std::move(config));
+            continue;
+        }
+        VehicleProperty property = static_cast<VehicleProperty>(config.prop);
+        std::string propertyName = aidl::android::hardware::automotive::vehicle::toString(property);
+        auto it = VersionForVehicleProperty.find(property);
+        if (it == VersionForVehicleProperty.end()) {
+            ALOGE("The property: %s is not a supported system property, ignore",
+                  propertyName.c_str());
+            continue;
+        }
+        int requiredVersion = it->second;
+        if (myVersion < requiredVersion) {
+            ALOGE("The property: %s is not supported for current client VHAL version, "
+                  "require %d, current version: %d, ignore",
+                  propertyName.c_str(), requiredVersion, myVersion);
+            continue;
+        }
+        filteredConfigs.push_back(std::move(config));
+    }
+    for (auto& config : filteredConfigs) {
         mConfigsByPropId[config.prop] = config;
     }
     VehiclePropConfigs vehiclePropConfigs;
-    vehiclePropConfigs.payloads = std::move(configs);
+    vehiclePropConfigs.payloads = std::move(filteredConfigs);
     auto result = LargeParcelableBase::parcelableToStableLargeParcelable(vehiclePropConfigs);
     if (!result.ok()) {
         ALOGE("failed to convert configs to shared memory file, error: %s, code: %d",
@@ -413,9 +453,9 @@
                     .status = getErrorCode(result),
                     .prop = {},
             });
-        } else {
-            hardwareRequests.push_back(request);
+            continue;
         }
+        hardwareRequests.push_back(request);
     }
 
     // The set of request Ids that we would send to hardware.
@@ -816,6 +856,7 @@
     if (!result.ok()) {
         return StatusError(StatusCode::INVALID_ARG) << getErrorMsg(result);
     }
+
     const VehiclePropConfig* config = result.value();
     const VehicleAreaConfig* areaConfig = getAreaConfig(value, *config);
 
@@ -900,6 +941,7 @@
     dprintf(fd, "Vehicle HAL State: \n");
     {
         std::scoped_lock<std::mutex> lockGuard(mLock);
+        dprintf(fd, "Interface version: %" PRId32 "\n", getVhalInterfaceVersion());
         dprintf(fd, "Containing %zu property configs\n", mConfigsByPropId.size());
         dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size());
         dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size());
diff --git a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
index a63cb84..bb82108 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/DefaultVehicleHalTest.cpp
@@ -79,36 +79,37 @@
 using ::ndk::SpAIBinder;
 
 using ::testing::ContainsRegex;
+using ::testing::ElementsAre;
 using ::testing::Eq;
 using ::testing::UnorderedElementsAre;
 using ::testing::UnorderedElementsAreArray;
 using ::testing::WhenSortedBy;
 
 constexpr int32_t INVALID_PROP_ID = 0;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x10000000 + 0x03000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t GLOBAL_ON_CHANGE_PROP = 10002 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t GLOBAL_CONTINUOUS_PROP = 10003 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-constexpr int32_t AREA_ON_CHANGE_PROP = 10004 + 0x10000000 + 0x03000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-constexpr int32_t AREA_CONTINUOUS_PROP = 10005 + 0x10000000 + 0x03000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t READ_ONLY_PROP = 10006 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t WRITE_ONLY_PROP = 10007 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t GLOBAL_CONTINUOUS_PROP_NO_VUR = 10008 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
-constexpr int32_t GLOBAL_NONE_ACCESS_PROP = 10009 + 0x10000000 + 0x01000000 + 0x00400000;
-// VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
-constexpr int32_t AREA_NONE_ACCESS_PROP = 10010 + 0x10000000 + 0x03000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t INT32_WINDOW_PROP = 10001 + 0x20000000 + 0x03000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t GLOBAL_ON_CHANGE_PROP = 10002 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t GLOBAL_CONTINUOUS_PROP = 10003 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t AREA_ON_CHANGE_PROP = 10004 + 0x20000000 + 0x03000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t AREA_CONTINUOUS_PROP = 10005 + 0x20000000 + 0x03000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t READ_ONLY_PROP = 10006 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t WRITE_ONLY_PROP = 10007 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t GLOBAL_CONTINUOUS_PROP_NO_VUR = 10008 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32
+constexpr int32_t GLOBAL_NONE_ACCESS_PROP = 10009 + 0x20000000 + 0x01000000 + 0x00400000;
+// VehiclePropertyGroup:VENDOR,VehicleArea:WINDOW,VehiclePropertyType:INT32
+constexpr int32_t AREA_NONE_ACCESS_PROP = 10010 + 0x20000000 + 0x03000000 + 0x00400000;
 
 int32_t testInt32VecProp(size_t i) {
-    // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
-    return static_cast<int32_t>(i) + 0x10000000 + 0x01000000 + 0x00410000;
+    // VehiclePropertyGroup:VENDOR,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
+    return static_cast<int32_t>(i) + 0x20000000 + 0x01000000 + 0x00410000;
 }
 
 std::string toString(const std::vector<SubscribeOptions>& options) {
@@ -556,10 +557,10 @@
 TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsSmall) {
     auto testConfigs = std::vector<VehiclePropConfig>({
             VehiclePropConfig{
-                    .prop = 1,
+                    .prop = testInt32VecProp(1),
             },
             VehiclePropConfig{
-                    .prop = 2,
+                    .prop = testInt32VecProp(2),
             },
     });
 
@@ -580,7 +581,7 @@
     // 5000 VehiclePropConfig exceeds 4k memory limit, so it would be sent through shared memory.
     for (size_t i = 0; i < 5000; i++) {
         testConfigs.push_back(VehiclePropConfig{
-                .prop = static_cast<int32_t>(i),
+                .prop = testInt32VecProp(i),
         });
     }
 
@@ -600,13 +601,42 @@
     ASSERT_EQ(result.value().getObject()->payloads, testConfigs);
 }
 
+TEST_F(DefaultVehicleHalTest, testGetAllPropConfigsFilterOutUnsupportedPropIdsForThisVersion) {
+    auto testConfigs = std::vector<VehiclePropConfig>({
+            // This is supported from V2.
+            VehiclePropConfig{
+                    .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+            },
+            // This is supported from V3
+            VehiclePropConfig{
+                    .prop = toInt(VehicleProperty::ULTRASONICS_SENSOR_POSITION),
+            },
+    });
+
+    auto hardware = std::make_unique<MockVehicleHardware>();
+    hardware->setPropertyConfigs(testConfigs);
+    auto vhal = ndk::SharedRefBase::make<DefaultVehicleHal>(std::move(hardware),
+                                                            /* testInterfaceVersion= */ 2);
+    std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
+
+    VehiclePropConfigs output;
+    auto status = client->getAllPropConfigs(&output);
+
+    ASSERT_TRUE(status.isOk()) << "getAllPropConfigs failed: " << status.getMessage();
+    ASSERT_THAT(output.payloads, ElementsAre(VehiclePropConfig{
+                                         .prop = toInt(VehicleProperty::PERF_VEHICLE_SPEED),
+                                 }));
+}
+
 TEST_F(DefaultVehicleHalTest, testGetPropConfigs) {
+    int32_t propId1 = testInt32VecProp(1);
+    int32_t propId2 = testInt32VecProp(2);
     auto testConfigs = std::vector<VehiclePropConfig>({
             VehiclePropConfig{
-                    .prop = 1,
+                    .prop = propId1,
             },
             VehiclePropConfig{
-                    .prop = 2,
+                    .prop = propId2,
             },
     });
 
@@ -616,7 +646,7 @@
     std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
 
     VehiclePropConfigs output;
-    auto status = client->getPropConfigs(std::vector<int32_t>({1, 2}), &output);
+    auto status = client->getPropConfigs(std::vector<int32_t>({propId1, propId2}), &output);
 
     ASSERT_TRUE(status.isOk()) << "getPropConfigs failed: " << status.getMessage();
     ASSERT_EQ(output.payloads, testConfigs);
@@ -625,10 +655,10 @@
 TEST_F(DefaultVehicleHalTest, testGetPropConfigsInvalidArg) {
     auto testConfigs = std::vector<VehiclePropConfig>({
             VehiclePropConfig{
-                    .prop = 1,
+                    .prop = testInt32VecProp(1),
             },
             VehiclePropConfig{
-                    .prop = 2,
+                    .prop = testInt32VecProp(2),
             },
     });
 
@@ -638,7 +668,9 @@
     std::shared_ptr<IVehicle> client = IVehicle::fromBinder(vhal->asBinder());
 
     VehiclePropConfigs output;
-    auto status = client->getPropConfigs(std::vector<int32_t>({1, 2, 3}), &output);
+    auto status = client->getPropConfigs(
+            std::vector<int32_t>({testInt32VecProp(1), testInt32VecProp(2), testInt32VecProp(3)}),
+            &output);
 
     ASSERT_FALSE(status.isOk()) << "getPropConfigs must fail with invalid prop ID";
     ASSERT_EQ(status.getServiceSpecificError(), toInt(StatusCode::INVALID_ARG));
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 fb8f730..026c040 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -52,6 +52,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     INFO_VIN = 0x0100 + 0x10000000 + 0x01000000
             + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -60,6 +61,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     INFO_MAKE = 0x0101 + 0x10000000 + 0x01000000
             + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -68,6 +70,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     INFO_MODEL = 0x0102 + 0x10000000 + 0x01000000
             + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -77,6 +80,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:YEAR
+     * @version 2
      */
     INFO_MODEL_YEAR = 0x0103 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -86,6 +90,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:MILLILITER
+     * @version 2
      */
     INFO_FUEL_CAPACITY = 0x0104 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -105,6 +110,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @data_enum FuelType
+     * @version 2
      */
     INFO_FUEL_TYPE = 0x0105 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -119,6 +125,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:WH
+     * @version 2
      */
     INFO_EV_BATTERY_CAPACITY = 0x0106 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -128,6 +135,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @data_enum EvConnectorType
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     INFO_EV_CONNECTOR_TYPE = 0x0107 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -137,6 +145,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @data_enum PortLocationType
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     INFO_FUEL_DOOR_LOCATION = 0x0108 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -146,6 +155,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @data_enum PortLocationType
+     * @version 2
      */
     INFO_EV_PORT_LOCATION = 0x0109 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -156,6 +166,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @data_enum VehicleAreaSeat
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     INFO_DRIVER_SEAT = 0x010A + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -174,6 +185,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:MILLIMETER
+     * @version 2
      */
     INFO_EXTERIOR_DIMENSIONS = 0x010B + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -189,6 +201,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @data_enum PortLocationType
+     * @version 2
      */
     INFO_MULTI_EV_PORT_LOCATIONS = 0x010C + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -198,6 +211,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:KILOMETER
+     * @version 2
      */
     PERF_ODOMETER = 0x0204 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -213,6 +227,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:METER_PER_SEC
+     * @version 2
      */
     PERF_VEHICLE_SPEED = 0x0207 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -225,6 +240,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:METER_PER_SEC
+     * @version 2
      */
     PERF_VEHICLE_SPEED_DISPLAY = 0x0208 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -236,6 +252,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:DEGREES
+     * @version 2
      */
     PERF_STEERING_ANGLE = 0x0209 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -247,6 +264,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:DEGREES
+     * @version 2
      */
     PERF_REAR_STEERING_ANGLE = 0x0210 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -256,6 +274,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:CELSIUS
+     * @version 2
      */
     ENGINE_COOLANT_TEMP = 0x0301 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -265,6 +284,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleOilLevel
+     * @version 2
      */
     ENGINE_OIL_LEVEL = 0x0303 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -274,6 +294,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:CELSIUS
+     * @version 2
      */
     ENGINE_OIL_TEMP = 0x0304 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -283,6 +304,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:RPM
+     * @version 2
      */
     ENGINE_RPM = 0x0305 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -323,6 +345,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     WHEEL_TICK = 0x0306 + 0x10000000 + 0x01000000
             + 0x00510000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64_VEC
@@ -334,6 +357,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:MILLILITER
+     * @version 2
      */
     FUEL_LEVEL = 0x0307 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -346,6 +370,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     FUEL_DOOR_OPEN = 0x0308 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -359,6 +384,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:WH
+     * @version 2
      */
     EV_BATTERY_LEVEL = 0x0309 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -373,6 +399,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:WH
+     * @version 2
      */
     EV_CURRENT_BATTERY_CAPACITY =
             0x030D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
@@ -385,6 +412,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     EV_CHARGE_PORT_OPEN = 0x030A + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -393,6 +421,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     EV_CHARGE_PORT_CONNECTED = 0x030B + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -405,6 +434,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:MW
+     * @version 2
      */
     EV_BATTERY_INSTANTANEOUS_CHARGE_RATE = 0x030C + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -423,6 +453,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:METER
+     * @version 2
      */
     RANGE_REMAINING = 0x0308 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -436,6 +467,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:CELSIUS
+     * @version 3
      */
     EV_BATTERY_AVERAGE_TEMPERATURE =
             0x030E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
@@ -463,6 +495,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:KILOPASCAL
+     * @version 2
      */
     TIRE_PRESSURE = 0x0309 + 0x10000000 + 0x07000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
@@ -478,6 +511,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:KILOPASCAL
+     * @version 2
      */
     CRITICALLY_LOW_TIRE_PRESSURE = 0x030A + 0x10000000 + 0x07000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WHEEL,VehiclePropertyType:FLOAT
@@ -493,6 +527,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     ENGINE_IDLE_AUTO_STOP_ENABLED =
             0x0320 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -509,6 +544,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum ImpactSensorLocation
+     * @version 3
      */
     IMPACT_DETECTED =
             0x0330 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -529,6 +565,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleGear
+     * @version 2
      */
     GEAR_SELECTION = 0x0400 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -548,6 +585,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleGear
+     * @version 2
      */
     CURRENT_GEAR = 0x0401 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -559,6 +597,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     PARKING_BRAKE_ON = 0x0402 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -576,6 +615,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     PARKING_BRAKE_AUTO_APPLY = 0x0403 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -594,6 +634,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     EV_BRAKE_REGENERATION_LEVEL =
             0x040C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -612,6 +653,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     FUEL_LEVEL_LOW = 0x0405 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -624,6 +666,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     NIGHT_MODE = 0x0407 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -633,6 +676,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleTurnSignal
+     * @version 2
      */
     TURN_SIGNAL_STATE = 0x0408 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -642,6 +686,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleIgnitionState
+     * @version 2
      */
     IGNITION_STATE = 0x0409 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -654,6 +699,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     ABS_ACTIVE = 0x040A + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -666,6 +712,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     TRACTION_CONTROL_ACTIVE = 0x040B + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -684,6 +731,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum EvStoppingMode
+     * @version 2
      */
     EV_STOPPING_MODE =
             0x040D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -705,6 +753,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     ELECTRONIC_STABILITY_CONTROL_ENABLED =
             0x040E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -723,6 +772,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum ElectronicStabilityControlState
      * @data_enum ErrorState
+     * @version 2
      */
     ELECTRONIC_STABILITY_CONTROL_STATE =
             0x040F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -789,6 +839,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_FAN_SPEED = 0x0500 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -802,6 +853,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleHvacFanDirection
+     * @version 2
      */
     HVAC_FAN_DIRECTION = 0x0501 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -811,6 +863,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:CELSIUS
+     * @version 2
      */
     HVAC_TEMPERATURE_CURRENT = 0x0502 + 0x10000000 + 0x05000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
@@ -842,6 +895,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:CELSIUS
+     * @version 2
      */
     HVAC_TEMPERATURE_SET = 0x0503 + 0x10000000 + 0x05000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
@@ -854,6 +908,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_DEFROSTER = 0x0504 + 0x10000000 + 0x03000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
@@ -867,6 +922,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @config_flags Supported areaIds
+     * @version 2
      */
     HVAC_AC_ON = 0x0505 + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -884,6 +940,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_MAX_AC_ON = 0x0506 + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -907,6 +964,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_MAX_DEFROST_ON = 0x0507 + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -924,6 +982,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_RECIRC_ON = 0x0508 + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -963,6 +1022,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_DUAL_ON = 0x0509 + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -985,6 +1045,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_AUTO_ON = 0x050A + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -1007,6 +1068,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_SEAT_TEMPERATURE = 0x050B + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -1030,6 +1092,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_SIDE_MIRROR_HEAT = 0x050C + 0x10000000 + 0x04000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1053,6 +1116,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_STEERING_WHEEL_HEAT = 0x050D + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1079,6 +1143,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleUnit
+     * @version 2
      */
     HVAC_TEMPERATURE_DISPLAY_UNITS = 0x050E + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1087,6 +1152,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_ACTUAL_FAN_SPEED_RPM = 0x050F + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -1133,6 +1199,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_POWER_ON = 0x0510 + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -1152,6 +1219,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleHvacFanDirection
+     * @version 2
      */
     HVAC_FAN_DIRECTION_AVAILABLE = 0x0511 + 0x10000000 + 0x05000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32_VEC
@@ -1168,6 +1236,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_AUTO_RECIRC_ON = 0x0512 + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -1193,6 +1262,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_SEAT_VENTILATION = 0x0513 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -1205,6 +1275,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HVAC_ELECTRIC_DEFROSTER_ON = 0x0514 + 0x10000000 + 0x03000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
@@ -1245,6 +1316,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     HVAC_TEMPERATURE_VALUE_SUGGESTION = 0x0515 + 0x10000000 + 0x01000000
             + 0x00610000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT_VEC
@@ -1270,6 +1342,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleUnit
+     * @version 2
      */
     DISTANCE_DISPLAY_UNITS = 0x0600 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1294,6 +1367,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleUnit
+     * @version 2
      */
     FUEL_VOLUME_DISPLAY_UNITS = 0x0601 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1319,6 +1393,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleUnit
+     * @version 2
      */
     TIRE_PRESSURE_DISPLAY_UNITS = 0x0602 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1344,6 +1419,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleUnit
+     * @version 2
      */
     EV_BATTERY_DISPLAY_UNITS = 0x0603 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1360,6 +1436,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 0x0604 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -1383,6 +1460,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1427,6 +1505,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:MILLI_SECS
+     * @version 2
      */
     EXTERNAL_CAR_TIME = 0x0608 + 0x10000000 // VehiclePropertyGroup:SYSTEM
             + 0x01000000 // VehicleArea:GLOBAL
@@ -1456,6 +1535,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
      * @unit VehicleUnit:MILLI_SECS
+     * @version 2
      */
     ANDROID_EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000
             + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
@@ -1470,6 +1550,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     STORAGE_ENCRYPTION_BINDING_SEED = 0x0607 + 0x10000000 + 0x01000000
             + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
@@ -1479,6 +1560,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:CELSIUS
+     * @version 2
      */
     ENV_OUTSIDE_TEMPERATURE = 0x0703 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -1497,6 +1579,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     AP_POWER_STATE_REQ = 0x0A00 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1511,6 +1594,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     AP_POWER_STATE_REPORT = 0x0A01 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1525,6 +1609,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     AP_POWER_BOOTUP_REASON = 0x0A02 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1547,6 +1632,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -1570,6 +1656,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     PER_DISPLAY_BRIGHTNESS = 0x0A04 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1586,6 +1673,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     VALET_MODE_ENABLED =
             0x0A05 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -1602,6 +1690,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     HEAD_UP_DISPLAY_ENABLED =
             0x0A06 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
@@ -1619,6 +1708,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @config_flags
+     * @version 2
      */
     HW_KEY_INPUT = 0x0A10 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1641,6 +1731,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @config_flags
+     * @version 2
      */
     HW_KEY_INPUT_V2 =
             0x0A11 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.MIXED,
@@ -1675,6 +1766,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @config_flags
+     * @version 2
      */
     HW_MOTION_INPUT =
             0x0A12 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.MIXED,
@@ -1698,6 +1790,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @data_enum RotaryInputType
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HW_ROTARY_INPUT = 0x0A20 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1721,6 +1814,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @data_enum CustomInputType
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HW_CUSTOM_INPUT = 0X0A30 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -1765,6 +1859,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     DOOR_POS = 0x0B00 + 0x10000000 + 0x06000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
@@ -1790,6 +1885,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     DOOR_MOVE = 0x0B01 + 0x10000000 + 0x06000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:INT32
@@ -1804,6 +1900,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     DOOR_LOCK = 0x0B02 + 0x10000000 + 0x06000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:DOOR,VehiclePropertyType:BOOLEAN
@@ -1820,6 +1917,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     DOOR_CHILD_LOCK_ENABLED =
             0x0B03 + VehiclePropertyGroup.SYSTEM + VehicleArea.DOOR + VehiclePropertyType.BOOLEAN,
@@ -1846,6 +1944,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     MIRROR_Z_POS = 0x0B40 + 0x10000000 + 0x04000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1872,6 +1971,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     MIRROR_Z_MOVE = 0x0B41 + 0x10000000 + 0x04000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1898,6 +1998,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     MIRROR_Y_POS = 0x0B42 + 0x10000000 + 0x04000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1923,6 +2024,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     MIRROR_Y_MOVE = 0x0B43 + 0x10000000 + 0x04000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:MIRROR,VehiclePropertyType:INT32
@@ -1937,6 +2039,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     MIRROR_LOCK = 0x0B44 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -1951,6 +2054,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     MIRROR_FOLD = 0x0B45 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -1968,6 +2072,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
 
     MIRROR_AUTO_FOLD_ENABLED =
@@ -1986,6 +2091,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
 
     MIRROR_AUTO_TILT_ENABLED =
@@ -2005,6 +2111,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     SEAT_MEMORY_SELECT = 0x0B80 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2018,6 +2125,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     SEAT_MEMORY_SET = 0x0B81 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2035,6 +2143,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_BELT_BUCKLED = 0x0B82 + 0x10000000 + 0x05000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:BOOLEAN
@@ -2060,6 +2169,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_BELT_HEIGHT_POS = 0x0B83 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2088,6 +2198,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_BELT_HEIGHT_MOVE = 0x0B84 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2113,6 +2224,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_FORE_AFT_POS = 0x0B85 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2140,6 +2252,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_FORE_AFT_MOVE = 0x0B86 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2167,6 +2280,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_BACKREST_ANGLE_1_POS = 0x0B87 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2194,6 +2308,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_BACKREST_ANGLE_1_MOVE = 0x0B88 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2223,6 +2338,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_BACKREST_ANGLE_2_POS = 0x0B89 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2250,6 +2366,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_BACKREST_ANGLE_2_MOVE = 0x0B8A + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2273,6 +2390,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEIGHT_POS = 0x0B8B + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2298,6 +2416,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEIGHT_MOVE = 0x0B8C + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2326,6 +2445,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_DEPTH_POS = 0x0B8D + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2352,6 +2472,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_DEPTH_MOVE = 0x0B8E + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2379,6 +2500,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_TILT_POS = 0x0B8F + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2406,6 +2528,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_TILT_MOVE = 0x0B90 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2431,6 +2554,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_LUMBAR_FORE_AFT_POS = 0x0B91 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2459,6 +2583,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_LUMBAR_FORE_AFT_MOVE = 0x0B92 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2484,6 +2609,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_LUMBAR_SIDE_SUPPORT_POS = 0x0B93 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2512,6 +2638,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_LUMBAR_SIDE_SUPPORT_MOVE = 0x0B94 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2532,6 +2659,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEADREST_HEIGHT_POS = 0x0B95 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -2559,6 +2687,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEADREST_HEIGHT_POS_V2 =
             0x0BA4 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2588,6 +2717,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEADREST_HEIGHT_MOVE = 0x0B96 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2611,6 +2741,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEADREST_ANGLE_POS = 0x0B97 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2639,6 +2770,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEADREST_ANGLE_MOVE = 0x0B98 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2662,6 +2794,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEADREST_FORE_AFT_POS = 0x0B99 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2690,6 +2823,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_HEADREST_FORE_AFT_MOVE = 0x0B9A + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2711,6 +2845,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     SEAT_FOOTWELL_LIGHTS_STATE =
             0x0B9B + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2736,6 +2871,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     SEAT_FOOTWELL_LIGHTS_SWITCH =
             0x0B9C + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2752,6 +2888,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_EASY_ACCESS_ENABLED =
             0x0B9D + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
@@ -2772,6 +2909,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     SEAT_AIRBAG_ENABLED =
             0x0B9E + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
@@ -2794,6 +2932,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleAirbagLocation
+     * @version 2
      */
     SEAT_AIRBAGS_DEPLOYED =
             0x0BA5 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2819,6 +2958,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_CUSHION_SIDE_SUPPORT_POS =
             0x0B9F + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2847,6 +2987,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_CUSHION_SIDE_SUPPORT_MOVE =
             0x0BA0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2870,6 +3011,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_LUMBAR_VERTICAL_POS =
             0x0BA1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2896,6 +3038,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_LUMBAR_VERTICAL_MOVE =
             0x0BA2 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2922,6 +3065,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SEAT_WALK_IN_POS =
             0x0BA3 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -2940,6 +3084,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     SEAT_BELT_PRETENSIONER_DEPLOYED =
             0x0BA6 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
@@ -2952,6 +3097,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleSeatOccupancyState
+     * @version 2
      */
     SEAT_OCCUPANCY = 0x0BB0 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -2988,6 +3134,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     WINDOW_POS = 0x0BC0 + 0x10000000 + 0x03000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
@@ -3030,6 +3177,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     WINDOW_MOVE = 0x0BC1 + 0x10000000 + 0x03000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
@@ -3044,6 +3192,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     WINDOW_LOCK = 0x0BC4 + 0x10000000 + 0x03000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:BOOLEAN
@@ -3064,6 +3213,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:MILLI_SECS
+     * @version 2
      */
     WINDSHIELD_WIPERS_PERIOD =
             0x0BC5 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
@@ -3085,6 +3235,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum WindshieldWipersState
+     * @version 2
      */
     WINDSHIELD_WIPERS_STATE =
             0x0BC6 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
@@ -3111,6 +3262,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum WindshieldWipersSwitch
+     * @version 2
      */
     WINDSHIELD_WIPERS_SWITCH =
             0x0BC7 + VehiclePropertyGroup.SYSTEM + VehicleArea.WINDOW + VehiclePropertyType.INT32,
@@ -3137,6 +3289,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     STEERING_WHEEL_DEPTH_POS =
             0x0BE0 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3163,6 +3316,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     STEERING_WHEEL_DEPTH_MOVE =
             0x0BE1 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3186,6 +3340,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     STEERING_WHEEL_HEIGHT_POS =
             0x0BE2 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3212,6 +3367,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     STEERING_WHEEL_HEIGHT_MOVE =
             0x0BE3 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3227,6 +3383,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     STEERING_WHEEL_THEFT_LOCK_ENABLED =
             0x0BE4 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -3241,6 +3398,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     STEERING_WHEEL_LOCKED =
             0x0BE5 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -3256,6 +3414,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     STEERING_WHEEL_EASY_ACCESS_ENABLED =
             0x0BE6 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -3283,6 +3442,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     GLOVE_BOX_DOOR_POS =
             0x0BF0 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -3302,6 +3462,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     GLOVE_BOX_LOCKED =
             0x0BF1 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
@@ -3321,6 +3482,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     VEHICLE_MAP_SERVICE = 0x0C00 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3340,6 +3502,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     LOCATION_CHARACTERIZATION =
             0x0C10 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3363,6 +3526,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     ULTRASONICS_SENSOR_POSITION = 0x0C20 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
             + VehiclePropertyType.INT32_VEC,
@@ -3394,6 +3558,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     ULTRASONICS_SENSOR_ORIENTATION = 0x0C21 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
             + VehiclePropertyType.INT32_VEC,
@@ -3417,6 +3582,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     ULTRASONICS_SENSOR_FIELD_OF_VIEW = 0x0C22 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
             + VehiclePropertyType.INT32_VEC,
@@ -3438,6 +3604,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     ULTRASONICS_SENSOR_DETECTION_RANGE = 0x0C23 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
             + VehiclePropertyType.INT32_VEC,
@@ -3484,6 +3651,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     ULTRASONICS_SENSOR_SUPPORTED_RANGES = 0x0C24 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
             + VehiclePropertyType.INT32_VEC,
@@ -3510,6 +3678,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     ULTRASONICS_SENSOR_MEASURED_DISTANCE = 0x0C25 + VehiclePropertyGroup.SYSTEM + VehicleArea.VENDOR
             + VehiclePropertyType.INT32_VEC,
@@ -3554,6 +3723,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     OBD2_LIVE_FRAME = 0x0D00 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3580,6 +3750,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     OBD2_FREEZE_FRAME = 0x0D01 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3597,6 +3768,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     OBD2_FREEZE_FRAME_INFO = 0x0D02 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3619,6 +3791,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     OBD2_FREEZE_FRAME_CLEAR = 0x0D03 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -3630,6 +3803,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     HEADLIGHTS_STATE = 0x0E00 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3641,6 +3815,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     HIGH_BEAM_LIGHTS_STATE = 0x0E01 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3668,6 +3843,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     FOG_LIGHTS_STATE = 0x0E02 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3679,6 +3855,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     HAZARD_LIGHTS_STATE = 0x0E03 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3694,6 +3871,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     HEADLIGHTS_SWITCH = 0x0E10 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3709,6 +3887,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     HIGH_BEAM_LIGHTS_SWITCH = 0x0E11 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3740,6 +3919,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     FOG_LIGHTS_SWITCH = 0x0E12 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3755,6 +3935,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     HAZARD_LIGHTS_SWITCH = 0x0E13 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3766,6 +3947,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     CABIN_LIGHTS_STATE = 0x0F01 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3784,6 +3966,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     CABIN_LIGHTS_SWITCH = 0x0F02 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -3795,6 +3978,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     READING_LIGHTS_STATE = 0x0F03 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -3813,6 +3997,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     READING_LIGHTS_SWITCH = 0x0F04 + 0x10000000 + 0x05000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:INT32
@@ -3834,6 +4019,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     STEERING_WHEEL_LIGHTS_STATE =
             0x0F0C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3859,6 +4045,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     STEERING_WHEEL_LIGHTS_SWITCH =
             0x0F0D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -3887,6 +4074,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SUPPORT_CUSTOMIZE_VENDOR_PERMISSION = 0x0F05 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -3903,6 +4091,7 @@
      * ex) "com.android.car.user.CarUserNoticeService,storage_monitoring"
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     DISABLED_OPTIONAL_FEATURES = 0x0F06 + 0x10000000 + 0x01000000
             + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -3953,6 +4142,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     INITIAL_USER_INFO = 0x0F07 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4119,6 +4309,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     SWITCH_USER = 0x0F08 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4165,6 +4356,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     CREATE_USER = 0x0F09 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4196,6 +4388,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     REMOVE_USER = 0x0F0A + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4271,6 +4464,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     USER_IDENTIFICATION_ASSOCIATION = 0x0F0B + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4290,6 +4484,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     EVS_SERVICE_REQUEST = 0x0F10 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -4307,6 +4502,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     POWER_POLICY_REQ = 0x0F21 + 0x10000000 + 0x01000000
             + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -4326,6 +4522,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     POWER_POLICY_GROUP_REQ = 0x0F22 + 0x10000000 + 0x01000000
             + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -4338,6 +4535,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @version 2
      */
     CURRENT_POWER_POLICY = 0x0F23 + 0x10000000 + 0x01000000
             + 0x00100000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:STRING
@@ -4349,6 +4547,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     WATCHDOG_ALIVE = 0xF31 + 0x10000000 + 0x01000000
             + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
@@ -4360,6 +4559,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     WATCHDOG_TERMINATED_PROCESS = 0x0F32 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4375,6 +4575,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     VHAL_HEARTBEAT = 0x0F33 + 0x10000000 + 0x01000000
             + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64
@@ -4388,6 +4589,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     CLUSTER_SWITCH_UI = 0x0F34 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4412,6 +4614,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     CLUSTER_DISPLAY_STATE = 0x0F35 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -4447,6 +4650,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     CLUSTER_REPORT_STATE = 0x0F36 + 0x10000000 + 0x01000000
             + 0x00e00000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:MIXED
@@ -4461,6 +4665,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     CLUSTER_REQUEST_DISPLAY = 0x0F37 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4471,6 +4676,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 2
      */
     CLUSTER_NAVIGATION_STATE = 0x0F38 + 0x10000000 + 0x01000000
             + 0x00700000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BYTES
@@ -4484,6 +4690,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum ElectronicTollCollectionCardType
+     * @version 2
      */
     ELECTRONIC_TOLL_COLLECTION_CARD_TYPE = 0x0F39 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4498,6 +4705,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum ElectronicTollCollectionCardStatus
+     * @version 2
      */
     ELECTRONIC_TOLL_COLLECTION_CARD_STATUS = 0x0F3A + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4511,6 +4719,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     FRONT_FOG_LIGHTS_STATE = 0x0F3B + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4529,6 +4738,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     FRONT_FOG_LIGHTS_SWITCH = 0x0F3C + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4543,6 +4753,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightState
+     * @version 2
      */
     REAR_FOG_LIGHTS_STATE = 0x0F3D + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4561,6 +4772,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleLightSwitch
+     * @version 2
      */
     REAR_FOG_LIGHTS_SWITCH = 0x0F3E + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4578,6 +4790,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:AMPERE
+     * @version 2
      */
     EV_CHARGE_CURRENT_DRAW_LIMIT = 0x0F3F + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -4599,6 +4812,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     EV_CHARGE_PERCENT_LIMIT = 0x0F40 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
@@ -4611,6 +4825,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum EvChargeState
+     * @version 2
      */
     EV_CHARGE_STATE = 0x0F41 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4627,6 +4842,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     EV_CHARGE_SWITCH = 0x0F42 + 0x10000000 + 0x01000000
             + 0x00200000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:BOOLEAN
@@ -4639,6 +4855,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:SECS
+     * @version 2
      */
     EV_CHARGE_TIME_REMAINING = 0x0F43 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4652,6 +4869,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum EvRegenerativeBrakingState
+     * @version 2
      */
     EV_REGENERATIVE_BRAKING_STATE = 0x0F44 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4664,6 +4882,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum TrailerState
+     * @version 2
      */
     TRAILER_PRESENT = 0x0F45 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4687,6 +4906,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:KILOGRAM
+     * @version 2
      */
 
     VEHICLE_CURB_WEIGHT = 0x0F46 + 0x10000000 + 0x01000000
@@ -4701,6 +4921,7 @@
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @data_enum GsrComplianceRequirementType
+     * @version 2
      */
     GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT = 0x0F47 + 0x10000000 + 0x01000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
@@ -4725,6 +4946,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     SUPPORTED_PROPERTY_IDS = 0x0F48 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
@@ -4772,6 +4994,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
      * @data_enum VehicleApPowerStateShutdownParam
+     * @version 2
      */
     SHUTDOWN_REQUEST =
             0x0F49 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4804,6 +5027,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     VEHICLE_IN_USE =
             0x0F4A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4818,6 +5042,7 @@
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
+     * @version 3
      */
     CLUSTER_HEARTBEAT =
             0x0F4B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.MIXED,
@@ -4837,6 +5062,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleAutonomousState
+     * @version 3
      */
     VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL =
             0x0F4C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4866,6 +5092,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     AUTOMATIC_EMERGENCY_BRAKING_ENABLED =
             0x1000 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4890,6 +5117,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum AutomaticEmergencyBrakingState
      * @data_enum ErrorState
+     * @version 2
      */
     AUTOMATIC_EMERGENCY_BRAKING_STATE =
             0x1001 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4911,6 +5139,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     FORWARD_COLLISION_WARNING_ENABLED =
             0x1002 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4930,6 +5159,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum ForwardCollisionWarningState
      * @data_enum ErrorState
+     * @version 2
      */
     FORWARD_COLLISION_WARNING_STATE =
             0x1003 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -4951,6 +5181,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     BLIND_SPOT_WARNING_ENABLED =
             0x1004 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -4970,6 +5201,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum BlindSpotWarningState
      * @data_enum ErrorState
+     * @version 2
      */
     BLIND_SPOT_WARNING_STATE =
             0x1005 + VehiclePropertyGroup.SYSTEM + VehicleArea.MIRROR + VehiclePropertyType.INT32,
@@ -4992,6 +5224,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     LANE_DEPARTURE_WARNING_ENABLED =
             0x1006 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5011,6 +5244,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum LaneDepartureWarningState
      * @data_enum ErrorState
+     * @version 2
      */
     LANE_DEPARTURE_WARNING_STATE =
             0x1007 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5037,6 +5271,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     LANE_KEEP_ASSIST_ENABLED =
             0x1008 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5059,6 +5294,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum LaneKeepAssistState
      * @data_enum ErrorState
+     * @version 2
      */
     LANE_KEEP_ASSIST_STATE =
             0x1009 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5086,6 +5322,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     LANE_CENTERING_ASSIST_ENABLED =
             0x100A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5116,6 +5353,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
      * @data_enum LaneCenteringAssistCommand
+     * @version 2
      */
     LANE_CENTERING_ASSIST_COMMAND =
             0x100B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5138,6 +5376,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum LaneCenteringAssistState
      * @data_enum ErrorState
+     * @version 2
      */
     LANE_CENTERING_ASSIST_STATE =
             0x100C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5161,6 +5400,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     EMERGENCY_LANE_KEEP_ASSIST_ENABLED =
             0x100D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5181,6 +5421,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum EmergencyLaneKeepAssistState
      * @data_enum ErrorState
+     * @version 2
      */
     EMERGENCY_LANE_KEEP_ASSIST_STATE =
             0x100E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5205,6 +5446,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     CRUISE_CONTROL_ENABLED =
             0x100F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5233,6 +5475,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum CruiseControlType
      * @data_enum ErrorState
+     * @version 2
      */
     CRUISE_CONTROL_TYPE =
             0x1010 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5253,6 +5496,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum CruiseControlState
      * @data_enum ErrorState
+     * @version 2
      */
     CRUISE_CONTROL_STATE =
             0x1011 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5276,6 +5520,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.WRITE
      * @data_enum CruiseControlCommand
+     * @version 2
      */
     CRUISE_CONTROL_COMMAND =
             0x1012 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5299,6 +5544,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:METER_PER_SEC
+     * @version 2
      */
     CRUISE_CONTROL_TARGET_SPEED =
             0x1013 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.FLOAT,
@@ -5330,6 +5576,7 @@
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:MILLI_SECS
+     * @version 2
      */
     ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP =
             0x1014 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5360,6 +5607,7 @@
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit:MILLIMETER
+     * @version 2
      */
     ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE =
             0x1015 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5381,6 +5629,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     HANDS_ON_DETECTION_ENABLED =
             0x1016 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5405,6 +5654,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum HandsOnDetectionDriverState
      * @data_enum ErrorState
+     * @version 2
      */
     HANDS_ON_DETECTION_DRIVER_STATE =
             0x1017 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5427,6 +5677,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum HandsOnDetectionWarning
      * @data_enum ErrorState
+     * @version 2
      */
     HANDS_ON_DETECTION_WARNING =
             0x1018 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5449,6 +5700,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED =
             0x1019 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5475,6 +5727,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum DriverDrowsinessAttentionState
      * @data_enum ErrorState
+     * @version 3
      */
     DRIVER_DROWSINESS_ATTENTION_STATE =
             0x101A + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5499,6 +5752,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED =
             0x101B + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5520,6 +5774,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum DriverDrowsinessAttentionWarning
      * @data_enum ErrorState
+     * @version 3
      */
     DRIVER_DROWSINESS_ATTENTION_WARNING =
             0x101C + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5542,6 +5797,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     DRIVER_DISTRACTION_SYSTEM_ENABLED =
             0x101D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5566,6 +5822,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum DriverDistractionState
      * @data_enum ErrorState
+     * @version 3
      */
     DRIVER_DISTRACTION_STATE =
             0x101E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5589,6 +5846,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 2
      */
     DRIVER_DISTRACTION_WARNING_ENABLED =
             0x101F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5610,6 +5868,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum DriverDistractionWarning
      * @data_enum ErrorState
+     * @version 3
      */
     DRIVER_DISTRACTION_WARNING =
             0x1020 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5635,6 +5894,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     LOW_SPEED_COLLISION_WARNING_ENABLED =
             0x1021 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5657,6 +5917,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum LowSpeedCollisionWarningState
      * @data_enum ErrorState
+     * @version 3
      */
     LOW_SPEED_COLLISION_WARNING_STATE =
             0x1022 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5679,6 +5940,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     CROSS_TRAFFIC_MONITORING_ENABLED =
             0x1023 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5698,6 +5960,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum CrossTrafficMonitoringWarningState
      * @data_enum ErrorState
+     * @version 3
      */
     CROSS_TRAFFIC_MONITORING_WARNING_STATE =
             0x1024 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -5724,6 +5987,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
+     * @version 3
      */
     LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED =
             0x1025 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
@@ -5750,6 +6014,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum LowSpeedAutomaticEmergencyBrakingState
      * @data_enum ErrorState
+     * @version 3
      */
     LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE =
             0x1026 + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
index 05fc99a..87e9bdc 100755
--- a/automotive/vehicle/tools/generate_annotation_enums.py
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -42,6 +42,8 @@
     'AccessForVehicleProperty.java')
 ENUM_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
                          'EnumForVehicleProperty.java')
+VERSION_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
+    'VersionForVehicleProperty.h')
 SCRIPT_PATH = 'hardware/interfaces/automotive/vehicle/tools/generate_annotation_enums.py'
 
 TAB = '    '
@@ -50,6 +52,7 @@
 RE_COMMENT_BEGIN = re.compile('\s*\/\*\*?')
 RE_COMMENT_END = re.compile('\s*\*\/')
 RE_CHANGE_MODE = re.compile('\s*\* @change_mode (\S+)\s*')
+RE_VERSION = re.compile('\s*\* @version (\S+)\s*')
 RE_ACCESS = re.compile('\s*\* @access (\S+)\s*')
 RE_DATA_ENUM = re.compile('\s*\* @data_enum (\S+)\s*')
 RE_UNIT = re.compile('\s*\* @unit (\S+)\s+')
@@ -81,8 +84,7 @@
 
 """
 
-CHANGE_MODE_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
-#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
+CHANGE_MODE_CPP_HEADER = """#pragma once
 
 #include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
 #include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
@@ -98,7 +100,7 @@
 std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = {
 """
 
-CHANGE_MODE_CPP_FOOTER = """
+CPP_FOOTER = """
 };
 
 }  // namespace vehicle
@@ -106,12 +108,9 @@
 }  // namespace hardware
 }  // namespace android
 }  // aidl
-
-#endif  // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
 """
 
-ACCESS_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
-#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+ACCESS_CPP_HEADER = """#pragma once
 
 #include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
 #include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
@@ -127,16 +126,19 @@
 std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = {
 """
 
-ACCESS_CPP_FOOTER = """
-};
+VERSION_CPP_HEADER = """#pragma once
 
-}  // namespace vehicle
-}  // namespace automotive
-}  // namespace hardware
-}  // namespace android
-}  // aidl
+#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
 
-#endif  // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, int32_t> VersionForVehicleProperty = {
 """
 
 CHANGE_MODE_JAVA_HEADER = """package android.hardware.automotive.vehicle;
@@ -148,7 +150,7 @@
     public static final Map<Integer, Integer> values = Map.ofEntries(
 """
 
-CHANGE_MODE_JAVA_FOOTER = """
+JAVA_FOOTER = """
     );
 
 }
@@ -163,12 +165,6 @@
     public static final Map<Integer, Integer> values = Map.ofEntries(
 """
 
-ACCESS_JAVA_FOOTER = """
-    );
-
-}
-"""
-
 ENUM_JAVA_HEADER = """package android.hardware.automotive.vehicle;
 
 import java.util.List;
@@ -179,12 +175,6 @@
     public static final Map<Integer, List<Class<?>>> values = Map.ofEntries(
 """
 
-ENUM_JAVA_FOOTER = """
-    );
-
-}
-"""
-
 
 class PropertyConfig:
     """Represents one VHAL property definition in VehicleProperty.aidl."""
@@ -196,6 +186,7 @@
         self.access_modes = []
         self.enum_types = []
         self.unit_type = None
+        self.version = None
 
     def __repr__(self):
         return self.__str__()
@@ -258,6 +249,11 @@
                     match = RE_DATA_ENUM.match(line)
                     if match:
                         config.enum_types.append(match.group(1))
+                    match = RE_VERSION.match(line)
+                    if match:
+                        if config.version != None:
+                            raise Exception('Duplicate version annotation for property: ' + prop_name)
+                        config.version = match.group(1)
                 else:
                     match = RE_VALUE.match(line)
                     if match:
@@ -270,6 +266,9 @@
                         if not config.access_modes:
                             raise Exception(
                                     'No access_mode annotation for property: ' + prop_name)
+                        if not config.version:
+                            raise Exception(
+                                    'no version annotation for property: ' + prop_name)
                         config.name = prop_name
                         configs.append(config)
 
@@ -295,6 +294,9 @@
                     continue;
                 if not cpp:
                     annotation = "List.of(" + ', '.join([class_name + ".class" for class_name in config.enum_types]) + ")"
+            elif field == 'version':
+                if cpp:
+                    annotation = config.version
             else:
                 raise Exception('Unknown field: ' + field)
             if counter != 0:
@@ -347,6 +349,69 @@
     return f.name
 
 
+class GeneratedFile:
+
+    def __init__(self, type):
+        self.type = type
+        self.cpp_file_path = None
+        self.java_file_path = None
+        self.cpp_header = None
+        self.java_header = None
+        self.cpp_footer = None
+        self.java_footer = None
+        self.cpp_output_file = None
+        self.java_output_file = None
+
+    def setCppFilePath(self, cpp_file_path):
+        self.cpp_file_path = cpp_file_path
+
+    def setJavaFilePath(self, java_file_path):
+        self.java_file_path = java_file_path
+
+    def setCppHeader(self, cpp_header):
+        self.cpp_header = cpp_header
+
+    def setCppFooter(self, cpp_footer):
+        self.cpp_footer = cpp_footer
+
+    def setJavaHeader(self, java_header):
+        self.java_header = java_header
+
+    def setJavaFooter(self, java_footer):
+        self.java_footer = java_footer
+
+    def convert(self, file_parser, check_only, temp_files):
+        if self.cpp_file_path:
+            output_file = GeneratedFile._getOutputFile(self.cpp_file_path, check_only, temp_files)
+            file_parser.convert(output_file, self.cpp_header, self.cpp_footer, True, self.type)
+            self.cpp_output_file = output_file
+
+        if self.java_file_path:
+            output_file = GeneratedFile._getOutputFile(self.java_file_path, check_only, temp_files)
+            file_parser.convert(output_file, self.java_header, self.java_footer, False, self.type)
+            self.java_output_file = output_file
+
+    def cmp(self):
+        if self.cpp_file_path:
+            if not filecmp.cmp(self.cpp_output_file, self.cpp_file_path):
+                return False
+
+        if self.java_file_path:
+            if not filecmp.cmp(self.java_output_file, self.java_file_path):
+                return False
+
+        return True
+
+    @staticmethod
+    def _getOutputFile(file_path, check_only, temp_files):
+        if not check_only:
+            return file_path
+
+        temp_file = createTempFile()
+        temp_files.append(temp_file)
+        return temp_file
+
+
 def main():
     parser = argparse.ArgumentParser(
             description='Generate Java and C++ enums based on annotations in VehicleProperty.aidl')
@@ -382,51 +447,52 @@
         f.outputAsCsv(args.output_csv)
         return
 
-    change_mode_cpp_file = os.path.join(android_top, CHANGE_MODE_CPP_FILE_PATH);
-    access_cpp_file = os.path.join(android_top, ACCESS_CPP_FILE_PATH);
-    change_mode_java_file = os.path.join(android_top, CHANGE_MODE_JAVA_FILE_PATH);
-    access_java_file = os.path.join(android_top, ACCESS_JAVA_FILE_PATH);
-    enum_java_file = os.path.join(android_top, ENUM_JAVA_FILE_PATH);
+    generated_files = []
+
+    change_mode = GeneratedFile('change_mode')
+    change_mode.setCppFilePath(os.path.join(android_top, CHANGE_MODE_CPP_FILE_PATH))
+    change_mode.setJavaFilePath(os.path.join(android_top, CHANGE_MODE_JAVA_FILE_PATH))
+    change_mode.setCppHeader(CHANGE_MODE_CPP_HEADER)
+    change_mode.setCppFooter(CPP_FOOTER)
+    change_mode.setJavaHeader(CHANGE_MODE_JAVA_HEADER)
+    change_mode.setJavaFooter(JAVA_FOOTER)
+    generated_files.append(change_mode)
+
+    access_mode = GeneratedFile('access_mode')
+    access_mode.setCppFilePath(os.path.join(android_top, ACCESS_CPP_FILE_PATH))
+    access_mode.setJavaFilePath(os.path.join(android_top, ACCESS_JAVA_FILE_PATH))
+    access_mode.setCppHeader(ACCESS_CPP_HEADER)
+    access_mode.setCppFooter(CPP_FOOTER)
+    access_mode.setJavaHeader(ACCESS_JAVA_HEADER)
+    access_mode.setJavaFooter(JAVA_FOOTER)
+    generated_files.append(access_mode)
+
+    enum_types = GeneratedFile('enum_types')
+    enum_types.setJavaFilePath(os.path.join(android_top, ENUM_JAVA_FILE_PATH))
+    enum_types.setJavaHeader(ENUM_JAVA_HEADER)
+    enum_types.setJavaFooter(JAVA_FOOTER)
+    generated_files.append(enum_types)
+
+    version = GeneratedFile('version')
+    version.setCppFilePath(os.path.join(android_top, VERSION_CPP_FILE_PATH))
+    version.setCppHeader(VERSION_CPP_HEADER)
+    version.setCppFooter(CPP_FOOTER)
+    generated_files.append(version)
+
     temp_files = []
 
-    if not args.check_only:
-        change_mode_cpp_output = change_mode_cpp_file
-        access_cpp_output = access_cpp_file
-        change_mode_java_output = change_mode_java_file
-        access_java_output = access_java_file
-        enum_java_output = enum_java_file
-    else:
-        change_mode_cpp_output = createTempFile()
-        temp_files.append(change_mode_cpp_output)
-        access_cpp_output = createTempFile()
-        temp_files.append(access_cpp_output)
-        change_mode_java_output = createTempFile()
-        temp_files.append(change_mode_java_output)
-        access_java_output = createTempFile()
-        temp_files.append(access_java_output)
-        enum_java_output = createTempFile()
-        temp_files.append(enum_java_output)
-
     try:
-        f.convert(change_mode_cpp_output, CHANGE_MODE_CPP_HEADER, CHANGE_MODE_CPP_FOOTER,
-                True, 'change_mode')
-        f.convert(change_mode_java_output, CHANGE_MODE_JAVA_HEADER,
-                CHANGE_MODE_JAVA_FOOTER, False, 'change_mode')
-        f.convert(access_cpp_output, ACCESS_CPP_HEADER, ACCESS_CPP_FOOTER, True, 'access_mode')
-        f.convert(access_java_output, ACCESS_JAVA_HEADER, ACCESS_JAVA_FOOTER, False, 'access_mode')
-        f.convert(enum_java_output, ENUM_JAVA_HEADER, ENUM_JAVA_FOOTER, False, 'enum_types')
+        for generated_file in generated_files:
+            generated_file.convert(f, args.check_only, temp_files)
 
         if not args.check_only:
             return
 
-        if ((not filecmp.cmp(change_mode_cpp_output, change_mode_cpp_file)) or
-                (not filecmp.cmp(change_mode_java_output, change_mode_java_file)) or
-                (not filecmp.cmp(access_cpp_output, access_cpp_file)) or
-                (not filecmp.cmp(access_java_output, access_java_file)) or
-                (not filecmp.cmp(enum_java_output, enum_java_file))):
-            print('The generated enum files for VehicleProperty.aidl requires update, ')
-            print('Run \npython ' + android_top + '/' + SCRIPT_PATH)
-            sys.exit(1)
+        for generated_file in generated_files:
+            if not generated_file.cmp():
+                print('The generated enum files for VehicleProperty.aidl requires update, ')
+                print('Run \npython ' + android_top + '/' + SCRIPT_PATH)
+                sys.exit(1)
     except Exception as e:
         print('Error parsing VehicleProperty.aidl')
         print(e)
diff --git a/automotive/vehicle/vts/Android.bp b/automotive/vehicle/vts/Android.bp
index 736787b..67d0d34 100644
--- a/automotive/vehicle/vts/Android.bp
+++ b/automotive/vehicle/vts/Android.bp
@@ -30,6 +30,7 @@
     ],
     static_libs: [
         "libgtest",
+        "libgmock",
         "libvhalclient",
     ],
     shared_libs: [
@@ -41,6 +42,9 @@
         "use_libaidlvintf_gtest_helper_static",
         "vhalclient_defaults",
     ],
+    header_libs: [
+        "IVehicleGeneratedHeaders",
+    ],
     test_suites: [
         "general-tests",
         "vts",
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index b5ee335..f8ddfaa 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -19,12 +19,14 @@
 #include <IVhalClient.h>
 #include <VehicleHalTypes.h>
 #include <VehicleUtils.h>
+#include <VersionForVehicleProperty.h>
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/automotive/vehicle/IVehicle.h>
 #include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
 #include <android/binder_process.h>
+#include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
@@ -47,6 +49,7 @@
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyChangeMode;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
 using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType;
+using ::aidl::android::hardware::automotive::vehicle::VersionForVehicleProperty;
 using ::android::getAidlHalInstanceNames;
 using ::android::base::ScopedLockAssertion;
 using ::android::base::StringPrintf;
@@ -58,7 +61,10 @@
 using ::android::frameworks::automotive::vhal::IVhalClient;
 using ::android::hardware::getAllHalInstanceNames;
 using ::android::hardware::Sanitize;
+using ::android::hardware::automotive::vehicle::isSystemProp;
+using ::android::hardware::automotive::vehicle::propIdToString;
 using ::android::hardware::automotive::vehicle::toInt;
+using ::testing::Ge;
 
 constexpr int32_t kInvalidProp = 0x31600207;
 
@@ -202,6 +208,41 @@
     ASSERT_NE(result.error().message(), "") << "Expect error message not to be empty";
 }
 
+// Test system property IDs returned by getPropConfigs() are defined in the VHAL property interface.
+TEST_P(VtsHalAutomotiveVehicleTargetTest, testPropConfigs_onlyDefinedSystemPropertyIdsReturned) {
+    if (!mVhalClient->isAidlVhal()) {
+        GTEST_SKIP() << "Skip for HIDL VHAL because HAL interface run-time version is only"
+                     << "introduced for AIDL";
+    }
+
+    auto result = mVhalClient->getAllPropConfigs();
+    ASSERT_TRUE(result.ok()) << "Failed to get all property configs, error: "
+                             << result.error().message();
+
+    int32_t vhalVersion = mVhalClient->getRemoteInterfaceVersion();
+    const auto& configs = result.value();
+    for (size_t i = 0; i < configs.size(); i++) {
+        int32_t propId = configs[i]->getPropId();
+        if (!isSystemProp(propId)) {
+            continue;
+        }
+
+        std::string propName = propIdToString(propId);
+        auto it = VersionForVehicleProperty.find(static_cast<VehicleProperty>(propId));
+        bool found = (it != VersionForVehicleProperty.end());
+        EXPECT_TRUE(found) << "System Property: " << propName
+                           << " is not defined in VHAL property interface";
+        if (!found) {
+            continue;
+        }
+        int32_t requiredVersion = it->second;
+        EXPECT_THAT(vhalVersion, Ge(requiredVersion))
+                << "System Property: " << propName << " requires VHAL version: " << requiredVersion
+                << ", but the current VHAL version"
+                << " is " << vhalVersion << ", must not be supported";
+    }
+}
+
 // Test get() return current value for properties.
 TEST_P(VtsHalAutomotiveVehicleTargetTest, get) {
     ALOGD("VtsHalAutomotiveVehicleTargetTest::get");
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
index 42c305a..8d913c8 100644
--- a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationContext.aidl
@@ -46,4 +46,5 @@
   android.hardware.biometrics.common.DisplayState displayState = android.hardware.biometrics.common.DisplayState.UNKNOWN;
   @nullable android.hardware.biometrics.common.AuthenticateReason authenticateReason;
   android.hardware.biometrics.common.FoldState foldState = android.hardware.biometrics.common.FoldState.UNKNOWN;
+  @nullable android.hardware.biometrics.common.OperationState operationState;
 }
diff --git a/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationState.aidl b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationState.aidl
new file mode 100644
index 0000000..fca9525
--- /dev/null
+++ b/biometrics/common/aidl/aidl_api/android.hardware.biometrics.common/current/android/hardware/biometrics/common/OperationState.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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.biometrics.common;
+/* @hide */
+@VintfStability
+union OperationState {
+  android.hardware.biometrics.common.OperationState.FingerprintOperationState fingerprintOperationState;
+  android.hardware.biometrics.common.OperationState.FaceOperationState faceOperationState;
+  @VintfStability
+  parcelable FingerprintOperationState {
+    ParcelableHolder extension;
+    boolean isHardwareIgnoringTouches = false;
+  }
+  @VintfStability
+  parcelable FaceOperationState {
+    ParcelableHolder extension;
+  }
+}
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
index 584057d..5f9844f 100644
--- a/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationContext.aidl
@@ -20,6 +20,7 @@
 import android.hardware.biometrics.common.DisplayState;
 import android.hardware.biometrics.common.FoldState;
 import android.hardware.biometrics.common.OperationReason;
+import android.hardware.biometrics.common.OperationState;
 import android.hardware.biometrics.common.WakeReason;
 
 /**
@@ -75,4 +76,7 @@
 
     /** The current fold/unfold state. */
     FoldState foldState = FoldState.UNKNOWN;
+
+    /** An associated operation state for this operation. */
+    @nullable OperationState operationState;
 }
diff --git a/biometrics/common/aidl/android/hardware/biometrics/common/OperationState.aidl b/biometrics/common/aidl/android/hardware/biometrics/common/OperationState.aidl
new file mode 100644
index 0000000..40cf589
--- /dev/null
+++ b/biometrics/common/aidl/android/hardware/biometrics/common/OperationState.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.biometrics.common;
+
+/**
+ * Additional state associated with an operation
+ *
+ * @hide
+ */
+@VintfStability
+union OperationState {
+    /** Operation state related to fingerprint*/
+    @VintfStability
+    parcelable FingerprintOperationState {
+        ParcelableHolder extension;
+
+        /** Flag indicating if the HAL should ignore touches on the fingerprint sensor */
+        boolean isHardwareIgnoringTouches = false;
+    }
+
+    /** Operation state related to face*/
+    @VintfStability
+    parcelable FaceOperationState {
+        ParcelableHolder extension;
+    }
+
+    OperationState.FingerprintOperationState fingerprintOperationState;
+    OperationState.FaceOperationState faceOperationState;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index 4fdcefc..feb6ba3 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -62,5 +62,8 @@
   void onPointerUpWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
   void onContextChanged(in android.hardware.biometrics.common.OperationContext context);
   void onPointerCancelWithContext(in android.hardware.biometrics.fingerprint.PointerContext context);
+  /**
+   * @deprecated use isHardwareIgnoringTouches in OperationContext from onContextChanged instead
+   */
   void setIgnoreDisplayTouches(in boolean shouldIgnore);
 }
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index 83e7bbc..07e22c2 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -544,6 +544,8 @@
      * whenever it's appropriate.
      *
      * @param shouldIgnore whether the display touches should be ignored.
+
+     * @deprecated use isHardwareIgnoringTouches in OperationContext from onContextChanged instead
      */
     void setIgnoreDisplayTouches(in boolean shouldIgnore);
 }
diff --git a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index f155634..87401ff 100644
--- a/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/aidl_api/android.hardware.bluetooth.audio/current/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -45,7 +45,7 @@
   void setCodecPriority(in android.hardware.bluetooth.audio.CodecId codecId, int priority);
   List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseConfigurationSetting> getLeAudioAseConfiguration(in @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities> remoteSinkAudioCapabilities, in @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities> remoteSourceAudioCapabilities, in List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioConfigurationRequirement> requirements);
   android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationPair getLeAudioAseQosConfiguration(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioAseQosConfigurationRequirement qosRequirement);
-  android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(in android.hardware.bluetooth.audio.AudioContext context, in android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap);
+  android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(in @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.StreamConfig sinkConfig, in @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.StreamConfig sourceConfig);
   void onSinkAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata);
   void onSourceAseMetadataChanged(in android.hardware.bluetooth.audio.IBluetoothAudioProvider.AseState state, int cigId, int cisId, in @nullable android.hardware.bluetooth.audio.MetadataLtv[] metadata);
   android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastConfigurationSetting getLeAudioBroadcastConfiguration(in @nullable List<android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDeviceCapabilities> remoteSinkAudioCapabilities, in android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioBroadcastConfigurationRequirement requirement);
@@ -146,6 +146,10 @@
     @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration inputConfig;
     @nullable android.hardware.bluetooth.audio.IBluetoothAudioProvider.LeAudioDataPathConfiguration outputConfig;
   }
+  parcelable StreamConfig {
+    android.hardware.bluetooth.audio.AudioContext context;
+    android.hardware.bluetooth.audio.LeAudioConfiguration.StreamMap[] streamMap;
+  }
   @Backing(type="byte") @VintfStability
   enum AseState {
     ENABLING = 0x00,
diff --git a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
index 2e16f4e..8c6fe69 100644
--- a/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
+++ b/bluetooth/audio/aidl/android/hardware/bluetooth/audio/IBluetoothAudioProvider.aidl
@@ -519,14 +519,37 @@
     }
 
     /**
+     * Stream Configuration
+     */
+    parcelable StreamConfig {
+        /**
+         * Streaming Audio Context.
+         * This can serve as a hint for selecting the proper configuration by
+         * the offloader.
+         */
+        AudioContext context;
+        /**
+         * Stream configuration, including connection handles and audio channel
+         * allocations.
+         */
+        StreamMap[] streamMap;
+    }
+
+    /**
      * Used to get a data path configuration which dynamically depends on CIS
      * connection handles in StreamMap. This is used if non-dynamic data path
      * was not provided in LeAudioAseConfigurationSetting. Calling this during
      * the unicast audio stream establishment might slightly delay the stream
      * start.
+     *
+     * @param sinkConfig - remote sink device stream configuration
+     * @param sourceConfig - remote source device stream configuration
+     *
+     * @return LeAudioDataPathConfigurationPair
      */
     LeAudioDataPathConfigurationPair getLeAudioAseDatapathConfiguration(
-            in AudioContext context, in StreamMap[] streamMap);
+            in @nullable StreamConfig sinkConfig,
+            in @nullable StreamConfig sourceConfig);
 
     /*
      * Audio Stream Endpoint state used to report Metadata changes on the remote
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
index bdba898..8d03fae 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.cpp
@@ -229,14 +229,17 @@
 };
 
 ndk::ScopedAStatus BluetoothAudioProvider::getLeAudioAseDatapathConfiguration(
-    const ::aidl::android::hardware::bluetooth::audio::AudioContext& in_context,
-    const std::vector<::aidl::android::hardware::bluetooth::audio::
-                          LeAudioConfiguration::StreamMap>& in_streamMap,
+    const std::optional<::aidl::android::hardware::bluetooth::audio::
+                            IBluetoothAudioProvider::StreamConfig>&
+        in_sinkConfig,
+    const std::optional<::aidl::android::hardware::bluetooth::audio::
+                            IBluetoothAudioProvider::StreamConfig>&
+        in_sourceConfig,
     ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
         LeAudioDataPathConfigurationPair* _aidl_return) {
   /* TODO: Implement */
-  (void)in_context;
-  (void)in_streamMap;
+  (void)in_sinkConfig;
+  (void)in_sourceConfig;
   (void)_aidl_return;
   return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
 }
diff --git a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
index 5064869..2c21440 100644
--- a/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/aidl/default/BluetoothAudioProvider.h
@@ -71,10 +71,12 @@
       ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
           LeAudioAseQosConfigurationPair* _aidl_return) override;
   ndk::ScopedAStatus getLeAudioAseDatapathConfiguration(
-      const ::aidl::android::hardware::bluetooth::audio::AudioContext&
-          in_context,
-      const std::vector<::aidl::android::hardware::bluetooth::audio::
-                            LeAudioConfiguration::StreamMap>& in_streamMap,
+      const std::optional<::aidl::android::hardware::bluetooth::audio::
+                              IBluetoothAudioProvider::StreamConfig>&
+          in_sinkConfig,
+      const std::optional<::aidl::android::hardware::bluetooth::audio::
+                              IBluetoothAudioProvider::StreamConfig>&
+          in_sourceConfig,
       ::aidl::android::hardware::bluetooth::audio::IBluetoothAudioProvider::
           LeAudioDataPathConfigurationPair* _aidl_return) override;
   ndk::ScopedAStatus onSinkAseMetadataChanged(
diff --git a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
index 88f2f97..be49a74 100644
--- a/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
+++ b/bluetooth/audio/aidl/vts/VtsHalBluetoothAudioTargetTest.cpp
@@ -2506,6 +2506,40 @@
   // QoS Configurations should not be empty, as we searched for all contexts
   ASSERT_FALSE(QoSConfigurations.empty());
 }
+
+TEST_P(BluetoothAudioProviderLeAudioOutputHardwareAidl,
+       GetDataPathConfiguration) {
+  IBluetoothAudioProvider::StreamConfig sink_requirement;
+  IBluetoothAudioProvider::StreamConfig source_requirement;
+  std::vector<IBluetoothAudioProvider::LeAudioDataPathConfiguration>
+      DataPathConfigurations;
+  bool is_supported = false;
+
+  for (auto bitmask : all_context_bitmasks) {
+    sink_requirement.context = GetAudioContext(bitmask);
+    source_requirement.context = GetAudioContext(bitmask);
+    IBluetoothAudioProvider::LeAudioDataPathConfigurationPair result;
+    auto aidl_retval = audio_provider_->getLeAudioAseDatapathConfiguration(
+        sink_requirement, source_requirement, &result);
+    if (!aidl_retval.isOk()) {
+      // If not OK, then it could be not supported, as it is an optional feature
+      ASSERT_EQ(aidl_retval.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+    } else {
+      is_supported = true;
+      if (result.inputConfig.has_value())
+        DataPathConfigurations.push_back(result.inputConfig.value());
+      if (result.inputConfig.has_value())
+        DataPathConfigurations.push_back(result.inputConfig.value());
+    }
+  }
+
+  if (is_supported) {
+    // Datapath Configurations should not be empty, as we searched for all
+    // contexts
+    ASSERT_FALSE(DataPathConfigurations.empty());
+  }
+}
+
 /**
  * Test whether each provider of type
  * SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH can be started and
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
index c057505..67ba93c 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioSession.cpp
@@ -500,14 +500,12 @@
                << " has NO session";
     return false;
   }
-  bool retval = false;
-
   if (!stack_iface_->getPresentationPosition(&presentation_position).isOk()) {
     LOG(WARNING) << __func__ << " - IBluetoothAudioPort SessionType="
                  << toString(session_type_) << " failed";
     return false;
   }
-  return retval;
+  return true;
 }
 
 void BluetoothAudioSession::UpdateSourceMetadata(
diff --git a/bluetooth/finder/aidl/Android.bp b/bluetooth/finder/aidl/Android.bp
index e606d2d..24f5ca5 100644
--- a/bluetooth/finder/aidl/Android.bp
+++ b/bluetooth/finder/aidl/Android.bp
@@ -28,7 +28,11 @@
         },
         java: {
             enabled: true,
-            platform_apis: true,
+            sdk_version: "module_current",
+            min_sdk_version: "30",
+            apex_available: [
+                "com.android.tethering",
+            ],
         },
     },
 }
diff --git a/bluetooth/lmp_event/aidl/Android.bp b/bluetooth/lmp_event/aidl/Android.bp
new file mode 100644
index 0000000..6c2f278
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/Android.bp
@@ -0,0 +1,33 @@
+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.bluetooth.lmp_event",
+    vendor_available: true,
+    host_supported: true,
+    srcs: ["android/hardware/bluetooth/lmp_event/*.aidl"],
+    stability: "vintf",
+    backend: {
+        java: {
+            enabled: true,
+            platform_apis: true,
+        },
+        cpp: {
+            enabled: true,
+        },
+        ndk: {
+            enabled: true,
+            min_sdk_version: "33",
+        },
+        rust: {
+            enabled: true,
+            min_sdk_version: "33",
+        },
+    },
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/AddressType.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/AddressType.aidl
new file mode 100644
index 0000000..0f239e8
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/AddressType.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.lmp_event;
+@Backing(type="byte") @VintfStability
+enum AddressType {
+  PUBLIC = 0x00,
+  RANDOM = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Direction.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Direction.aidl
new file mode 100644
index 0000000..6f807cc
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Direction.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.lmp_event;
+@Backing(type="byte") @VintfStability
+enum Direction {
+  TX = 0x00,
+  RX = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl
new file mode 100644
index 0000000..3431010
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.lmp_event;
+@VintfStability
+interface IBluetoothLmpEvent {
+  void registerForLmpEvents(in android.hardware.bluetooth.lmp_event.IBluetoothLmpEventCallback callback, in android.hardware.bluetooth.lmp_event.AddressType addressType, in byte[6] address, in android.hardware.bluetooth.lmp_event.LmpEventId[] lmpEventIds);
+  void unregisterLmpEvents(in android.hardware.bluetooth.lmp_event.AddressType addressType, in byte[6] address);
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl
new file mode 100644
index 0000000..fc6758c
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.lmp_event;
+@VintfStability
+interface IBluetoothLmpEventCallback {
+  void onEventGenerated(in android.hardware.bluetooth.lmp_event.Timestamp timestamp, in android.hardware.bluetooth.lmp_event.AddressType addressType, in byte[6] address, in android.hardware.bluetooth.lmp_event.Direction direction, in android.hardware.bluetooth.lmp_event.LmpEventId lmpEventId, in char connEventCounter);
+  void onRegistered(in boolean status);
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/LmpEventId.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
new file mode 100644
index 0000000..4ee95d1
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.lmp_event;
+@Backing(type="byte") @VintfStability
+enum LmpEventId {
+  CONNECT_IND = 0x00,
+  LL_PHY_UPDATE_IND = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Timestamp.aidl b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Timestamp.aidl
new file mode 100644
index 0000000..5ef32ba
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/aidl_api/android.hardware.bluetooth.lmp_event/current/android/hardware/bluetooth/lmp_event/Timestamp.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.bluetooth.lmp_event;
+@VintfStability
+parcelable Timestamp {
+  long systemTimeUs;
+  long bluetoothTimeUs;
+}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/AddressType.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/AddressType.aidl
new file mode 100644
index 0000000..6bfc7c7
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/AddressType.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 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 android.hardware.bluetooth.lmp_event;
+
+/**
+ * Type of Address
+ */
+@VintfStability
+@Backing(type="byte")
+enum AddressType {
+    PUBLIC = 0x00,
+    RANDOM = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Direction.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Direction.aidl
new file mode 100644
index 0000000..884c2bb
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Direction.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 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 android.hardware.bluetooth.lmp_event;
+
+/**
+ * Direction of the LMP event
+ */
+@VintfStability
+@Backing(type="byte")
+enum Direction {
+    TX = 0x00,
+    RX = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl
new file mode 100644
index 0000000..3828af6
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEvent.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright 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 android.hardware.bluetooth.lmp_event;
+
+import android.hardware.bluetooth.lmp_event.IBluetoothLmpEventCallback;
+import android.hardware.bluetooth.lmp_event.AddressType;
+import android.hardware.bluetooth.lmp_event.LmpEventId;
+
+@VintfStability
+interface IBluetoothLmpEvent {
+    /**
+     * API to monitor specific LMP event timestamp for given Bluetooth device.
+     *
+     * @param callback An instance of the |IBluetoothLmpEventCallback| AIDL interface object.
+     * @param addressType  Type of bluetooth address.
+     * @param address Bluetooth address to monitor.
+     * @param lmpEventIds LMP events to monitor.
+     */
+    void registerForLmpEvents(in IBluetoothLmpEventCallback callback,
+                              in AddressType addressType,
+                              in byte[6] address,
+                              in LmpEventId[] lmpEventIds);
+
+    /**
+     * API to stop monitoring a given Bluetooth device.
+     *
+     * @param addressType  Type of Bluetooth address.
+     * @param address Bluetooth device to stop monitoring.
+     */
+    void unregisterLmpEvents(in AddressType addressType, in byte[6] address);
+}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl
new file mode 100644
index 0000000..3295ef0
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/IBluetoothLmpEventCallback.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 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 android.hardware.bluetooth.lmp_event;
+
+import android.hardware.bluetooth.lmp_event.Direction;
+import android.hardware.bluetooth.lmp_event.AddressType;
+import android.hardware.bluetooth.lmp_event.LmpEventId;
+import android.hardware.bluetooth.lmp_event.Timestamp;
+
+@VintfStability
+interface IBluetoothLmpEventCallback {
+    /**
+     * Callback when monitored LMP event invoked.
+     *
+     * @param timestamp Timestamp when the LMP event invoked
+     * @param addressType  Type of Bluetooth address.
+     * @param address Remote bluetooth address that invoke LMP event
+     * @param direction Direction of the invoked LMP event
+     * @param lmpEventId LMP event id that bluetooth chip invoked
+     * @param connEventCounter counter incremented by one for each new connection event
+     */
+    void onEventGenerated(in Timestamp timestamp,
+                          in AddressType addressType,
+                          in byte[6] address,
+                          in Direction direction,
+                          in LmpEventId lmpEventId,
+                          in char connEventCounter);
+
+    /**
+     * Callback when registration done.
+     */
+    void onRegistered(in boolean status);
+}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/LmpEventId.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
new file mode 100644
index 0000000..3584b0c
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/LmpEventId.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 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 android.hardware.bluetooth.lmp_event;
+
+/**
+ * LMP event id to be monitored
+ * CONNECT_IND indicator for initiating connection
+ * LL_PHY_UPDATE_IND indicator for PHY update
+ */
+@VintfStability
+@Backing(type="byte")
+enum LmpEventId {
+    CONNECT_IND = 0x00,
+    LL_PHY_UPDATE_IND = 0x01,
+}
diff --git a/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Timestamp.aidl b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Timestamp.aidl
new file mode 100644
index 0000000..e3c991d
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/android/hardware/bluetooth/lmp_event/Timestamp.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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 android.hardware.bluetooth.lmp_event;
+
+/**
+ * Generic structure to return the timestamp
+ */
+@VintfStability
+parcelable Timestamp {
+    /**
+     * Timestamp in microsecond since system boot.
+     *  if systemTimeUs is set to 0, its value is to be ignored
+     */
+    long systemTimeUs;
+    /**
+     * Timestamp in microsecond since Bluetooth controller power up.
+     */
+    long bluetoothTimeUs;
+}
diff --git a/bluetooth/lmp_event/aidl/default/Android.bp b/bluetooth/lmp_event/aidl/default/Android.bp
new file mode 100644
index 0000000..f8ca5e6
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/Android.bp
@@ -0,0 +1,28 @@
+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.bluetooth.lmp_event-service.default",
+    relative_install_path: "hw",
+    init_rc: ["lmp_event-default.rc"],
+    vintf_fragments: [":manifest_android.hardware.bluetooth.lmp_event-service.default.xml"],
+    vendor: true,
+    rustlibs: [
+        "liblogger",
+        "liblog_rust",
+        "libbinder_rs",
+        "android.hardware.bluetooth.lmp_event-V1-rust",
+    ],
+    srcs: [ "src/main.rs" ],
+}
+
+filegroup {
+    name: "manifest_android.hardware.bluetooth.lmp_event-service.default.xml",
+    srcs: [ "lmp_event-default.xml" ],
+}
diff --git a/bluetooth/lmp_event/aidl/default/lmp_event-default.rc b/bluetooth/lmp_event/aidl/default/lmp_event-default.rc
new file mode 100644
index 0000000..845e04d
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/lmp_event-default.rc
@@ -0,0 +1,6 @@
+service vendor.bluetooth.lmp_event-default /vendor/bin/hw/android.hardware.bluetooth.lmp_event-service.default
+    class hal
+    capabilities BLOCK_SUSPEND NET_ADMIN SYS_NICE
+    user bluetooth
+    group bluetooth
+    task_profiles HighPerformance
diff --git a/bluetooth/lmp_event/aidl/default/lmp_event-default.xml b/bluetooth/lmp_event/aidl/default/lmp_event-default.xml
new file mode 100644
index 0000000..24d93f8
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/lmp_event-default.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.bluetooth.lmp_event</name>
+        <version>1</version>
+        <interface>
+            <name>IBluetoothLmpEvent</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/bluetooth/lmp_event/aidl/default/src/lmp_event.rs b/bluetooth/lmp_event/aidl/default/src/lmp_event.rs
new file mode 100644
index 0000000..f016c3f
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/src/lmp_event.rs
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+//! Implements LMP Event AIDL Interface.
+
+use android_hardware_bluetooth_lmp_event::aidl::android::hardware::bluetooth::lmp_event::{
+    Direction::Direction, AddressType::AddressType, IBluetoothLmpEvent::IBluetoothLmpEvent,
+    IBluetoothLmpEventCallback::IBluetoothLmpEventCallback, LmpEventId::LmpEventId,
+    Timestamp::Timestamp,
+};
+
+use binder::{Interface, Result, Strong};
+
+use log::info;
+use std::thread;
+use std::time;
+
+
+pub struct LmpEvent;
+
+impl LmpEvent {
+    pub fn new() -> Self {
+        Self
+    }
+}
+
+impl Interface for LmpEvent {}
+
+impl IBluetoothLmpEvent for LmpEvent {
+    fn registerForLmpEvents(&self,
+                            callback: &Strong<dyn IBluetoothLmpEventCallback>,
+                            address_type: AddressType,
+                            address: &[u8; 6],
+                            lmp_event_ids: &[LmpEventId]
+    ) -> Result<()> {
+        info!("registerForLmpEvents");
+
+        let cb = callback.clone();
+        let addr_type = address_type;
+        let addr = address.clone();
+        let lmp_event = lmp_event_ids.to_vec();
+
+        let thread_handle = thread::spawn(move || {
+            let ts = Timestamp {
+                bluetoothTimeUs: 1000000,
+                systemTimeUs: 2000000,
+            };
+
+            info!("sleep for 1000 ms");
+            thread::sleep(time::Duration::from_millis(1000));
+
+            info!("callback event");
+            cb.onEventGenerated(&ts, addr_type, &addr, Direction::RX, lmp_event[0], 1)
+                .expect("onEventGenerated failed");
+        });
+
+        info!("callback register");
+        callback.onRegistered(true)?;
+
+        thread_handle.join().expect("join failed");
+        Ok(())
+    }
+    fn unregisterLmpEvents(&self, _address_type: AddressType, _address: &[u8; 6]) -> Result<()> {
+        info!("unregisterLmpEvents");
+
+        Ok(())
+    }
+}
diff --git a/bluetooth/lmp_event/aidl/default/src/main.rs b/bluetooth/lmp_event/aidl/default/src/main.rs
new file mode 100644
index 0000000..cbdd4d1
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/default/src/main.rs
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+//! Implements LMP Event Example Service.
+
+
+use android_hardware_bluetooth_lmp_event::aidl::android::hardware::bluetooth::lmp_event::IBluetoothLmpEvent::{
+    IBluetoothLmpEvent, BnBluetoothLmpEvent
+};
+
+use binder::BinderFeatures;
+use log::{info, Level};
+
+mod lmp_event;
+
+const LOG_TAG: &str = "lmp_event_service_example";
+
+fn main() {
+    info!("{LOG_TAG}: starting service");
+    let logger_success = logger::init(
+        logger::Config::default().with_tag_on_device(LOG_TAG).with_min_level(Level::Trace)
+    );
+    if !logger_success {
+        panic!("{LOG_TAG}: Failed to start logger");
+    }
+
+    binder::ProcessState::set_thread_pool_max_thread_count(0);
+
+    let lmp_event_service = lmp_event::LmpEvent::new();
+    let lmp_event_service_binder = BnBluetoothLmpEvent::new_binder(lmp_event_service, BinderFeatures::default());
+
+    binder::add_service(
+        &format!("{}/default", lmp_event::LmpEvent::get_descriptor()),
+        lmp_event_service_binder.as_binder(),
+    ).expect("Failed to register service");
+
+    binder::ProcessState::join_thread_pool()
+}
diff --git a/bluetooth/lmp_event/aidl/vts/Android.bp b/bluetooth/lmp_event/aidl/vts/Android.bp
new file mode 100644
index 0000000..b89351e
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/vts/Android.bp
@@ -0,0 +1,20 @@
+cc_test {
+    name: "VtsHalLmpEventTargetTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: ["VtsHalLmpEventTargetTest.cpp"],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk"
+    ],
+    static_libs: [
+        "android.hardware.bluetooth.lmp_event-V1-ndk",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ]
+}
+
diff --git a/bluetooth/lmp_event/aidl/vts/VtsHalLmpEventTargetTest.cpp b/bluetooth/lmp_event/aidl/vts/VtsHalLmpEventTargetTest.cpp
new file mode 100644
index 0000000..c49f60b
--- /dev/null
+++ b/bluetooth/lmp_event/aidl/vts/VtsHalLmpEventTargetTest.cpp
@@ -0,0 +1,176 @@
+/*
+ * 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 std::shared_ptrecific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "lmp_event_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+
+#include <aidl/android/hardware/bluetooth/lmp_event/BnBluetoothLmpEvent.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/BnBluetoothLmpEventCallback.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/Direction.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/AddressType.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/LmpEventId.h>
+#include <aidl/android/hardware/bluetooth/lmp_event/Timestamp.h>
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <log/log.h>
+
+#include <chrono>
+#include <condition_variable>
+#include <cinttypes>
+#include <thread>
+
+using ::aidl::android::hardware::bluetooth::lmp_event::BnBluetoothLmpEventCallback;
+using ::aidl::android::hardware::bluetooth::lmp_event::IBluetoothLmpEvent;
+using ::aidl::android::hardware::bluetooth::lmp_event::IBluetoothLmpEventCallback;
+using ::aidl::android::hardware::bluetooth::lmp_event::Direction;
+using ::aidl::android::hardware::bluetooth::lmp_event::AddressType;
+using ::aidl::android::hardware::bluetooth::lmp_event::LmpEventId;
+using ::aidl::android::hardware::bluetooth::lmp_event::Timestamp;
+
+using ::android::ProcessState;
+using ::ndk::SpAIBinder;
+
+namespace {
+    static constexpr std::chrono::milliseconds kEventTimeoutMs(10000);
+}
+
+class BluetoothLmpEventTest : public testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        ALOGI("%s", __func__);
+
+        ibt_lmp_event_ = IBluetoothLmpEvent::fromBinder(SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+        ASSERT_NE(ibt_lmp_event_, nullptr);
+
+        ibt_lmp_event_cb_ = ndk::SharedRefBase::make<BluetoothLmpEventCallback>(*this);
+        ASSERT_NE(ibt_lmp_event_cb_, nullptr);
+    }
+
+    virtual void TearDown() override {
+        ALOGI("%s", __func__);
+        ibt_lmp_event_->unregisterLmpEvents(address_type, address);
+
+        ibt_lmp_event_cb_ = nullptr;
+    }
+
+    class BluetoothLmpEventCallback : public BnBluetoothLmpEventCallback {
+        public:
+            BluetoothLmpEventTest& parent_;
+            BluetoothLmpEventCallback(BluetoothLmpEventTest& parent)
+                : parent_(parent) {}
+            ~BluetoothLmpEventCallback() = default;
+
+            ::ndk::ScopedAStatus onEventGenerated(const Timestamp& timestamp, AddressType address_type,
+                    const std::array<uint8_t, 6>& address, Direction direction,
+                    LmpEventId lmp_event_id, char16_t conn_event_counter) override {
+                for (auto t: address) {
+                    ALOGD("%s: 0x%02x", __func__, t);
+                }
+                if (direction == Direction::TX) {
+                    ALOGD("%s: Transmitting", __func__);
+                } else if (direction == Direction::RX) {
+                    ALOGD("%s: Receiving", __func__);
+                }
+                if (address_type == AddressType::PUBLIC) {
+                    ALOGD("%s: Public address", __func__);
+                } else if (address_type == AddressType::RANDOM) {
+                    ALOGD("%s: Random address", __func__);
+                }
+                if (lmp_event_id == LmpEventId::CONNECT_IND) {
+                    ALOGD("%s: initiating connection", __func__);
+                } else if (lmp_event_id == LmpEventId::LL_PHY_UPDATE_IND) {
+                    ALOGD("%s: PHY update indication", __func__);
+                }
+
+                ALOGD("%s: time: %" PRId64 "counter value: %x", __func__, timestamp.bluetoothTimeUs, conn_event_counter);
+
+                parent_.event_recv = true;
+                parent_.notify();
+
+                return ::ndk::ScopedAStatus::ok();
+            }
+            ::ndk::ScopedAStatus onRegistered(bool status) override {
+                ALOGD("%s: status: %d", __func__, status);
+                parent_.status_recv = status;
+                parent_.notify();
+                return ::ndk::ScopedAStatus::ok();
+            }
+    };
+
+    inline void notify() {
+        std::unique_lock<std::mutex> lock(lmp_event_mtx);
+        lmp_event_cv.notify_one();
+    }
+
+    inline void wait(bool is_register_event) {
+        std::unique_lock<std::mutex> lock(lmp_event_mtx);
+
+
+        if (is_register_event) {
+            lmp_event_cv.wait(lock, [&]() { return status_recv == true; });
+        } else {
+            lmp_event_cv.wait_for(lock, kEventTimeoutMs,
+                    [&](){ return event_recv == true; });
+        }
+
+    }
+
+    std::shared_ptr<IBluetoothLmpEvent> ibt_lmp_event_;
+    std::shared_ptr<IBluetoothLmpEventCallback> ibt_lmp_event_cb_;
+
+    AddressType address_type;
+    std::array<uint8_t, 6> address;
+
+    std::atomic<bool> event_recv;
+    bool status_recv;
+
+    std::mutex lmp_event_mtx;
+    std::condition_variable lmp_event_cv;
+};
+
+TEST_P(BluetoothLmpEventTest, RegisterAndReceive) {
+    address = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+    address_type = AddressType::RANDOM;
+    std::vector<LmpEventId> lmp_event_ids{LmpEventId::CONNECT_IND, LmpEventId::LL_PHY_UPDATE_IND};
+
+    ibt_lmp_event_->registerForLmpEvents(ibt_lmp_event_cb_, address_type, address, lmp_event_ids);
+    wait(true);
+    EXPECT_EQ(true, status_recv);
+
+    /* Wait for event generated here */
+    wait(false);
+    EXPECT_EQ(true, event_recv);
+
+    ibt_lmp_event_->unregisterLmpEvents(address_type, address);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothLmpEventTest);
+INSTANTIATE_TEST_SUITE_P(BluetoothLmpEvent, BluetoothLmpEventTest,
+                         testing::ValuesIn(android::getAidlHalInstanceNames(IBluetoothLmpEvent::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/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index 2668a97..754b05b 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -35,6 +35,7 @@
 #include <broadcastradio-utils-aidl/UtilsV2.h>
 #include <cutils/bitops.h>
 #include <gmock/gmock.h>
+#include <gtest/gtest.h>
 
 #include <chrono>
 #include <condition_variable>
@@ -76,12 +77,6 @@
 constexpr int32_t kAidlVersion1 = 1;
 constexpr int32_t kAidlVersion2 = 2;
 
-void printSkipped(const std::string& msg) {
-    const auto testInfo = testing::UnitTest::GetInstance()->current_test_info();
-    LOG(INFO) << "[  SKIPPED ] " << testInfo->test_case_name() << "." << testInfo->name()
-              << " with message: " << msg;
-}
-
 bool isValidAmFmFreq(int64_t freq, int aidlVersion) {
     ProgramIdentifier id = bcutils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, freq);
     if (aidlVersion == kAidlVersion1) {
@@ -385,7 +380,7 @@
     auto startResult = mModule->startProgramListUpdates(filter);
 
     if (startResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
-        printSkipped("Program list not supported");
+        LOG(WARNING) << "Program list not supported";
         return std::nullopt;
     }
     EXPECT_TRUE(startResult.isOk());
@@ -430,8 +425,7 @@
     bool supported = getAmFmRegionConfig(/* full= */ false, &config);
 
     if (!supported) {
-        printSkipped("AM/FM not supported");
-        return;
+        GTEST_SKIP() << "AM/FM not supported";
     }
 
     EXPECT_LE(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
@@ -459,8 +453,7 @@
     bool supported = getAmFmRegionConfig(/* full= */ false, &config);
 
     if (!supported) {
-        printSkipped("AM/FM not supported");
-        return;
+        GTEST_SKIP() << "AM/FM not supported";
     }
 
     EXPECT_GT(config.ranges.size(), 0u);
@@ -488,7 +481,7 @@
     if (supported && supportsFM(config)) {
         EXPECT_GE(popcountll(static_cast<unsigned long long>(config.fmDeemphasis)), 1);
     } else {
-        printSkipped("FM not supported");
+        GTEST_SKIP() << "FM not supported";
     }
 }
 
@@ -509,8 +502,7 @@
     bool supported = getAmFmRegionConfig(/* full= */ true, &config);
 
     if (!supported) {
-        printSkipped("AM/FM not supported");
-        return;
+        GTEST_SKIP() << "AM/FM not supported";
     }
 
     EXPECT_GT(config.ranges.size(), 0u);
@@ -536,8 +528,7 @@
     auto halResult = mModule->getDabRegionConfig(&config);
 
     if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
-        printSkipped("DAB not supported");
-        return;
+        GTEST_SKIP() << "DAB not supported";
     }
     ASSERT_TRUE(halResult.isOk());
 
@@ -671,7 +662,7 @@
  *  - if it is supported, the method succeeds;
  *  - after a successful tune call, onCurrentProgramInfoChanged callback is
  *    invoked carrying a proper selector;
- *  - program changes exactly to what was requested.
+ *  - program changes to a program info with the program selector requested.
  */
 TEST_P(BroadcastRadioHalTest, FmTune) {
     LOG(DEBUG) << "FmTune Test";
@@ -715,8 +706,7 @@
     LOG(DEBUG) << "HdTune Test";
     auto programList = getProgramList();
     if (!programList) {
-        printSkipped("Empty station list, tune cannot be performed");
-        return;
+        GTEST_SKIP() << "Empty station list, tune cannot be performed";
     }
     ProgramSelector hdSel = {};
     ProgramIdentifier physicallyTunedToExpected = {};
@@ -732,8 +722,7 @@
         break;
     }
     if (!hdStationPresent) {
-        printSkipped("No HD stations in the list, tune cannot be performed");
-        return;
+        GTEST_SKIP() << "No HD stations in the list, tune cannot be performed";
     }
 
     // try tuning
@@ -762,7 +751,7 @@
  *  - if it is supported, the method succeeds;
  *  - after a successful tune call, onCurrentProgramInfoChanged callback is
  *    invoked carrying a proper selector;
- *  - program changes exactly to what was requested.
+ *  - program changes to a program info with the program selector requested.
  */
 TEST_P(BroadcastRadioHalTest, DabTune) {
     LOG(DEBUG) << "DabTune Test";
@@ -771,8 +760,7 @@
     auto halResult = mModule->getDabRegionConfig(&config);
 
     if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
-        printSkipped("DAB not supported");
-        return;
+        GTEST_SKIP() << "DAB not supported";
     }
     ASSERT_TRUE(halResult.isOk());
     ASSERT_NE(config.size(), 0U);
@@ -780,8 +768,7 @@
     auto programList = getProgramList();
 
     if (!programList) {
-        printSkipped("Empty DAB station list, tune cannot be performed");
-        return;
+        GTEST_SKIP() << "Empty DAB station list, tune cannot be performed";
     }
 
     ProgramSelector sel = {};
@@ -811,8 +798,7 @@
     }
 
     if (!dabStationPresent) {
-        printSkipped("No DAB stations in the list, tune cannot be performed");
-        return;
+        GTEST_SKIP() << "No DAB stations in the list, tune cannot be performed";
     }
 
     // try tuning
@@ -844,7 +830,7 @@
  * Verifies that:
  *  - the method succeeds;
  *  - the program info is changed within kTuneTimeoutMs;
- *  - works both directions and with or without skipping sub-channel.
+ *  - works both directions and with or without ing sub-channel.
  */
 TEST_P(BroadcastRadioHalTest, Seek) {
     LOG(DEBUG) << "Seek Test";
@@ -854,8 +840,7 @@
     auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
 
     if (result.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
-        printSkipped("Seek not supported");
-        return;
+        GTEST_SKIP() << "Seek not supported";
     }
 
     EXPECT_TRUE(result.isOk());
@@ -905,8 +890,7 @@
     auto result = mModule->step(/* in_directionUp= */ true);
 
     if (result.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
-        printSkipped("Step not supported");
-        return;
+        GTEST_SKIP() << "Step not supported";
     }
     EXPECT_TRUE(result.isOk());
     EXPECT_TRUE(mCallback->waitOnCurrentProgramInfoChangedCallback());
@@ -957,8 +941,7 @@
         auto result = mModule->seek(/* in_directionUp= */ true, /* in_skipSubChannel= */ true);
 
         if (result.getServiceSpecificError() == notSupportedError) {
-            printSkipped("Cancel is skipped because of seek not supported");
-            return;
+            GTEST_SKIP() << "Cancel is skipped because of seek not supported";
         }
         EXPECT_TRUE(result.isOk());
 
@@ -1152,8 +1135,7 @@
 
     std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
     if (!completeList) {
-        printSkipped("No program list available");
-        return;
+        GTEST_SKIP() << "No program list available";
     }
 
     ProgramFilter amfmFilter = {};
@@ -1178,8 +1160,7 @@
     }
 
     if (expectedResultSize == 0) {
-        printSkipped("No Am/FM programs available");
-        return;
+        GTEST_SKIP() << "No Am/FM programs available";
     }
     std::optional<bcutils::ProgramInfoSet> amfmList = getProgramList(amfmFilter);
     ASSERT_EQ(amfmList->size(), expectedResultSize) << "amfm filter result size is wrong";
@@ -1200,8 +1181,7 @@
 
     std::optional<bcutils::ProgramInfoSet> completeList = getProgramList();
     if (!completeList) {
-        printSkipped("No program list available");
-        return;
+        GTEST_SKIP() << "No program list available";
     }
 
     ProgramFilter dabFilter = {};
@@ -1225,8 +1205,7 @@
     }
 
     if (expectedResultSize == 0) {
-        printSkipped("No DAB programs available");
-        return;
+        GTEST_SKIP() << "No DAB programs available";
     }
     std::optional<bcutils::ProgramInfoSet> dabList = getProgramList(dabFilter);
     ASSERT_EQ(dabList->size(), expectedResultSize) << "dab filter result size is wrong";
@@ -1245,8 +1224,7 @@
 
     std::optional<bcutils::ProgramInfoSet> list = getProgramList();
     if (!list) {
-        printSkipped("No program list");
-        return;
+        GTEST_SKIP() << "No program list";
     }
 
     for (const auto& program : *list) {
@@ -1297,8 +1275,7 @@
 
     if (halResult.getServiceSpecificError() == resultToInt(Result::NOT_SUPPORTED)) {
         ASSERT_EQ(closeHandle.get(), nullptr);
-        printSkipped("Announcements not supported");
-        return;
+        GTEST_SKIP() << "Announcements not supported";
     }
 
     ASSERT_TRUE(halResult.isOk());
diff --git a/broadcastradio/common/utilsaidl/Android.bp b/broadcastradio/common/utilsaidl/Android.bp
index 4ec635b..4814778 100644
--- a/broadcastradio/common/utilsaidl/Android.bp
+++ b/broadcastradio/common/utilsaidl/Android.bp
@@ -26,7 +26,7 @@
 cc_library_static {
     name: "android.hardware.broadcastradio@common-utils-aidl-lib",
     defaults: [
-        "VtsBroadcastRadioDefaults",
+        "BroadcastRadioUtilsDefaults",
     ],
     shared_libs: [
         "android.hardware.broadcastradio-V1-ndk",
@@ -36,7 +36,7 @@
 cc_library_static {
     name: "android.hardware.broadcastradio@common-utils-aidl-lib-V2",
     defaults: [
-        "VtsBroadcastRadioDefaults",
+        "BroadcastRadioUtilsDefaults",
     ],
     srcs: [
         "src/UtilsV2.cpp",
@@ -46,8 +46,23 @@
     ],
 }
 
+cc_test {
+    name: "broadcastradio_utils_aidl_test",
+    defaults: [
+        "BroadcastRadioUtilsDefaults",
+    ],
+    srcs: [
+        "test/*.cpp",
+    ],
+    static_libs: [
+        "android.hardware.broadcastradio@common-utils-aidl-lib-V2",
+        "android.hardware.broadcastradio-V2-ndk",
+    ],
+    test_suites: ["general-tests"],
+}
+
 cc_defaults {
-    name: "VtsBroadcastRadioDefaults",
+    name: "BroadcastRadioUtilsDefaults",
     vendor_available: true,
     relative_install_path: "hw",
     cflags: [
diff --git a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
new file mode 100644
index 0000000..0750949
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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 <broadcastradio-utils-aidl/Utils.h>
+#include <gtest/gtest.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+constexpr int64_t kFmFrequencyKHz = 97900;
+constexpr uint64_t kDabSidExt = 0x0E10000C221u;
+constexpr uint32_t kDabEnsemble = 0xCE15u;
+constexpr uint64_t kDabFrequencyKhz = 225648u;
+constexpr uint64_t kHdStationId = 0xA0000001u;
+constexpr uint64_t kHdSubChannel = 1u;
+constexpr uint64_t kHdFrequency = 97700u;
+}  // namespace
+
+TEST(BroadcastRadioUtilsTest, hasIdWithPrimaryIdType) {
+    ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+    ASSERT_TRUE(utils::hasId(sel, IdentifierType::AMFM_FREQUENCY_KHZ));
+}
+
+TEST(BroadcastRadioUtilsTest, makeIdentifier) {
+    ProgramIdentifier id =
+            utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz);
+
+    ASSERT_EQ(id.type, IdentifierType::AMFM_FREQUENCY_KHZ);
+    ASSERT_EQ(id.value, kFmFrequencyKHz);
+}
+
+TEST(BroadcastRadioUtilsTest, makeSelectorAmfm) {
+    ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+    ASSERT_EQ(sel.primaryId.type, IdentifierType::AMFM_FREQUENCY_KHZ);
+    ASSERT_EQ(sel.primaryId.value, kFmFrequencyKHz);
+    ASSERT_TRUE(sel.secondaryIds.empty());
+}
+
+TEST(BroadcastRadioUtilsTest, makeSelectorHd) {
+    ProgramSelector sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+
+    ASSERT_EQ(sel.primaryId.type, IdentifierType::HD_STATION_ID_EXT);
+    ASSERT_TRUE(sel.secondaryIds.empty());
+    ASSERT_EQ(utils::getHdSubchannel(sel), static_cast<int>(kHdSubChannel));
+    ASSERT_EQ(utils::getHdFrequency(sel), static_cast<uint32_t>(kHdFrequency));
+}
+
+TEST(BroadcastRadioUtilsTest, makeHdRadioStationName) {
+    std::string stationName = "aB1-FM";
+    int64_t expectedIdValue = 0x4D46314241;
+
+    ProgramIdentifier stationNameId = utils::makeHdRadioStationName(stationName);
+
+    ASSERT_EQ(stationNameId.type, IdentifierType::HD_STATION_NAME);
+    ASSERT_EQ(stationNameId.value, expectedIdValue);
+}
+
+TEST(BroadcastRadioUtilsTest, getHdFrequencyWithoutHdId) {
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+    ASSERT_EQ(utils::getHdFrequency(sel), 0u);
+}
+
+TEST(BroadcastRadioUtilsTest, hasAmFmFrequencyWithAmFmSelector) {
+    ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+    ASSERT_TRUE(utils::hasAmFmFrequency(sel));
+}
+
+TEST(BroadcastRadioUtilsTest, hasAmFmFrequencyWithHdSelector) {
+    ProgramSelector sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+
+    ASSERT_TRUE(utils::hasAmFmFrequency(sel));
+}
+
+TEST(BroadcastRadioUtilsTest, hasAmFmFrequencyWithNonAmFmHdSelector) {
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+    ASSERT_FALSE(utils::hasAmFmFrequency(sel));
+}
+
+TEST(BroadcastRadioUtilsTest, getAmFmFrequencyWithAmFmSelector) {
+    ProgramSelector sel = utils::makeSelectorAmfm(kFmFrequencyKHz);
+
+    ASSERT_EQ(utils::getAmFmFrequency(sel), static_cast<uint32_t>(kFmFrequencyKHz));
+}
+
+TEST(BroadcastRadioUtilsTest, getAmFmFrequencyWithHdSelector) {
+    ProgramSelector sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+
+    ASSERT_EQ(utils::getAmFmFrequency(sel), static_cast<uint32_t>(kHdFrequency));
+}
+
+TEST(BroadcastRadioUtilsTest, getAmFmFrequencyWithNonAmFmHdSelector) {
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+    ASSERT_EQ(utils::getAmFmFrequency(sel), 0u);
+}
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index 3a1d762..01009ad 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -444,6 +444,7 @@
      *
      * For Android 15, the characteristics which need to be set are:
      *   - ANDROID_CONTROL_ZOOM_RATIO_RANGE
+     *   - SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
      *
      * A service specific error will be returned on the following conditions
      *     INTERNAL_ERROR:
diff --git a/camera/device/default/ExternalCameraDevice.cpp b/camera/device/default/ExternalCameraDevice.cpp
index 677fb42..649bf43 100644
--- a/camera/device/default/ExternalCameraDevice.cpp
+++ b/camera/device/default/ExternalCameraDevice.cpp
@@ -399,6 +399,10 @@
     const uint8_t hotPixelMode = ANDROID_HOT_PIXEL_MODE_OFF;
     UPDATE(ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES, &hotPixelMode, 1);
 
+    // android.info
+    const uint8_t bufMgrVer = ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5;
+    UPDATE(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION, &bufMgrVer, 1);
+
     // android.jpeg
     const int32_t jpegAvailableThumbnailSizes[] = {0,   0,   176, 144, 240, 144, 256,
                                                    144, 240, 160, 256, 154, 240, 180};
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index 720a9d4..9a5f248 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -283,6 +283,64 @@
     }
 }
 
+TEST_P(CameraAidlTest, getSessionCharacteristics) {
+    if (flags::feature_combination_query()) {
+        std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
+
+        for (const auto& name : cameraDeviceNames) {
+            std::shared_ptr<ICameraDevice> device;
+            ALOGI("getSessionCharacteristics: Testing camera device %s", name.c_str());
+            ndk::ScopedAStatus ret = mProvider->getCameraDeviceInterface(name, &device);
+            ALOGI("getCameraDeviceInterface returns: %d:%d", ret.getExceptionCode(),
+                  ret.getServiceSpecificError());
+            ASSERT_TRUE(ret.isOk());
+            ASSERT_NE(device, nullptr);
+
+            CameraMetadata meta;
+            openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
+                                   &device /*out*/);
+
+            std::vector<AvailableStream> outputStreams;
+            camera_metadata_t* staticMeta =
+                    reinterpret_cast<camera_metadata_t*>(meta.metadata.data());
+            outputStreams.clear();
+            ASSERT_EQ(Status::OK, getAvailableOutputStreams(staticMeta, outputStreams));
+            ASSERT_NE(0u, outputStreams.size());
+
+            AvailableStream sampleStream = outputStreams[0];
+
+            int32_t streamId = 0;
+            Stream stream = {streamId,
+                             StreamType::OUTPUT,
+                             sampleStream.width,
+                             sampleStream.height,
+                             static_cast<PixelFormat>(sampleStream.format),
+                             static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+                                     GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER),
+                             Dataspace::UNKNOWN,
+                             StreamRotation::ROTATION_0,
+                             std::string(),
+                             /*bufferSize*/ 0,
+                             /*groupId*/ -1,
+                             {SensorPixelMode::ANDROID_SENSOR_PIXEL_MODE_DEFAULT},
+                             RequestAvailableDynamicRangeProfilesMap::
+                                     ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD};
+
+            std::vector<Stream> streams = {stream};
+            StreamConfiguration config;
+            createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE, &config);
+
+            CameraMetadata chars;
+            ret = device->getSessionCharacteristics(config, &chars);
+            ASSERT_TRUE(ret.isOk());
+            verifySessionCharacteristics(chars);
+        }
+    } else {
+        ALOGI("getSessionCharacteristics: Test skipped.\n");
+        GTEST_SKIP();
+    }
+}
+
 // Verify that the torch strength level can be set and retrieved successfully.
 TEST_P(CameraAidlTest, turnOnTorchWithStrengthLevel) {
     std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
@@ -531,11 +589,7 @@
             }
 
             if (ret.isOk()) {
-                const camera_metadata_t* metadata = (camera_metadata_t*)rawMetadata.metadata.data();
-                size_t expectedSize = rawMetadata.metadata.size();
-                int result = validate_camera_metadata_structure(metadata, &expectedSize);
-                ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
-                verifyRequestTemplate(metadata, reqTemplate);
+                validateDefaultRequestMetadata(reqTemplate, rawMetadata);
             } else {
                 ASSERT_EQ(0u, rawMetadata.metadata.size());
             }
@@ -546,24 +600,12 @@
                     ndk::ScopedAStatus ret2 =
                             device->constructDefaultRequestSettings(reqTemplate, &rawMetadata2);
 
-                    // TODO: Do not allow OPERATION_NOT_SUPPORTED once HAL
-                    // implementation is in place.
-                    if (static_cast<Status>(ret2.getServiceSpecificError()) !=
-                        Status::OPERATION_NOT_SUPPORTED) {
-                        ASSERT_EQ(ret.isOk(), ret2.isOk());
-                        ASSERT_EQ(ret.getStatus(), ret2.getStatus());
+                    ASSERT_EQ(ret.isOk(), ret2.isOk());
+                    ASSERT_EQ(ret.getStatus(), ret2.getStatus());
 
-                        ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
-                        if (ret2.isOk()) {
-                            const camera_metadata_t* metadata =
-                                    (camera_metadata_t*)rawMetadata2.metadata.data();
-                            size_t expectedSize = rawMetadata2.metadata.size();
-                            int result =
-                                    validate_camera_metadata_structure(metadata, &expectedSize);
-                            ASSERT_TRUE((result == 0) ||
-                                        (result == CAMERA_METADATA_VALIDATION_SHIFTED));
-                            verifyRequestTemplate(metadata, reqTemplate);
-                        }
+                    ASSERT_EQ(rawMetadata.metadata.size(), rawMetadata2.metadata.size());
+                    if (ret2.isOk()) {
+                        validateDefaultRequestMetadata(reqTemplate, rawMetadata2);
                     }
                 }
             }
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index bb9068e..d2a409e 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -1931,6 +1931,55 @@
     }
 }
 
+void CameraAidlTest::verifySessionCharacteristics(const CameraMetadata& chars) {
+    if (flags::feature_combination_query()) {
+        const camera_metadata_t* metadata =
+                reinterpret_cast<const camera_metadata_t*>(chars.metadata.data());
+
+        size_t expectedSize = chars.metadata.size();
+        int result = validate_camera_metadata_structure(metadata, &expectedSize);
+        ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+        size_t entryCount = get_camera_metadata_entry_count(metadata);
+        ASSERT_GT(entryCount, 0u);
+
+        camera_metadata_ro_entry entry;
+        int retcode = 0;
+        float maxDigitalZoom = 1.0;
+
+        retcode = find_camera_metadata_ro_entry(metadata, ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+                                                &entry);
+        // ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM should always be present.
+        if ((0 == retcode) && (entry.count == 1)) {
+            maxDigitalZoom = entry.data.f[0];
+        } else {
+            ADD_FAILURE() << "Get camera scalerAvailableMaxDigitalZoom failed!";
+        }
+
+        retcode = find_camera_metadata_ro_entry(metadata, ANDROID_CONTROL_ZOOM_RATIO_RANGE, &entry);
+        bool hasZoomRatioRange = (0 == retcode && entry.count == 2);
+        if (!hasZoomRatioRange) {
+            return;
+        }
+        float minZoomRatio = entry.data.f[0];
+        float maxZoomRatio = entry.data.f[1];
+        constexpr float FLOATING_POINT_THRESHOLD = 0.00001f;
+        if (abs(maxDigitalZoom - maxZoomRatio) > FLOATING_POINT_THRESHOLD) {
+            ADD_FAILURE() << "Difference between maximum digital zoom " << maxDigitalZoom
+                          << " and maximum zoom ratio " << maxZoomRatio
+                          << " is greater than the threshold " << FLOATING_POINT_THRESHOLD << "!";
+        }
+        if (minZoomRatio > maxZoomRatio) {
+            ADD_FAILURE() << "Maximum zoom ratio is less than minimum zoom ratio!";
+        }
+        if (minZoomRatio > 1.0f) {
+            ADD_FAILURE() << "Minimum zoom ratio is more than 1.0!";
+        }
+        if (maxZoomRatio < 1.0f) {
+            ADD_FAILURE() << "Maximum zoom ratio is less than 1.0!";
+        }
+    }
+}
+
 std::vector<ConcurrentCameraIdCombination> CameraAidlTest::getConcurrentDeviceCombinations(
         std::shared_ptr<ICameraProvider>& provider) {
     std::vector<ConcurrentCameraIdCombination> combinations;
@@ -4044,3 +4093,12 @@
         }
     }
 }
+
+void CameraAidlTest::validateDefaultRequestMetadata(RequestTemplate reqTemplate,
+                                                    const CameraMetadata& rawMetadata) {
+    const camera_metadata_t* metadata = (camera_metadata_t*)rawMetadata.metadata.data();
+    size_t expectedSize = rawMetadata.metadata.size();
+    int result = validate_camera_metadata_structure(metadata, &expectedSize);
+    ASSERT_TRUE((result == 0) || (result == CAMERA_METADATA_VALIDATION_SHIFTED));
+    verifyRequestTemplate(metadata, reqTemplate);
+}
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index 86f0c9b..507a637 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -290,6 +290,8 @@
     static void verifyStreamCombination(const std::shared_ptr<ICameraDevice>& device,
                                         const StreamConfiguration& config, bool expectedStatus);
 
+    static void verifySessionCharacteristics(const CameraMetadata& chars);
+
     static void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
                                           const std::vector<uint8_t>& resultMetadata);
 
@@ -597,6 +599,9 @@
     static void waitForReleaseFence(
             std::vector<InFlightRequest::StreamBufferAndTimestamp>& resultOutputBuffers);
 
+    static void validateDefaultRequestMetadata(RequestTemplate reqTemplate,
+                                               const CameraMetadata& rawMetadata);
+
     // Map from frame number to the in-flight request state
     typedef std::unordered_map<uint32_t, std::shared_ptr<InFlightRequest>> InFlightMap;
 
diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml
index 328f1c8..90dd414 100644
--- a/compatibility_matrices/compatibility_matrix.9.xml
+++ b/compatibility_matrices/compatibility_matrix.9.xml
@@ -1,22 +1,4 @@
 <compatibility-matrix version="1.0" type="framework" level="9">
-    <hal format="hidl" optional="true">
-        <name>android.hardware.audio</name>
-        <version>6.0</version>
-        <version>7.0-1</version>
-        <interface>
-            <name>IDevicesFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-    <hal format="hidl" optional="true">
-        <name>android.hardware.audio.effect</name>
-        <version>6.0</version>
-        <version>7.0</version>
-        <interface>
-            <name>IEffectsFactory</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
     <hal format="aidl" optional="true">
         <name>android.hardware.audio.core</name>
         <version>1-2</version>
@@ -173,6 +155,14 @@
         </interface>
     </hal>
     <hal format="aidl" optional="true">
+        <name>android.hardware.bluetooth.lmp_event</name>
+        <version>1</version>
+        <interface>
+            <name>IBluetoothLmpEvent</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+    <hal format="aidl" optional="true">
         <name>android.hardware.boot</name>
         <interface>
             <name>IBootControl</name>
@@ -325,6 +315,7 @@
         <version>1</version>
         <interface>
             <name>ISecretkeeper</name>
+            <instance>default</instance>
             <instance>nonsecure</instance>
         </interface>
     </hal>
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index b67cfc2..a1992b9 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -315,6 +315,8 @@
  * required client targets.
  */
 TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport) {
+    ASSERT_NO_FATAL_FAILURE(
+            mComposerClient->setPowerMode(mPrimaryDisplay, IComposerClient::PowerMode::ON));
     std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
     for (auto config : configs) {
         int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
index 2bd287b..cd4cb58 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2TargetTest.cpp
@@ -256,6 +256,8 @@
  * required client targets.
  */
 TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
+    ASSERT_NO_FATAL_FAILURE(
+            mComposerClient->setPowerMode_2_2(mPrimaryDisplay, IComposerClient::PowerMode::ON));
     std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
     for (auto config : configs) {
         int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
diff --git a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
index c072ef0..f99c72d 100644
--- a/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
+++ b/graphics/composer/2.3/vts/functional/VtsHalGraphicsComposerV2_3TargetTest.cpp
@@ -274,6 +274,8 @@
  * Test IComposerClient::getClientTargetSupport_2_3
  */
 TEST_P(GraphicsComposerHidlTest, GetClientTargetSupport_2_3) {
+    ASSERT_NO_FATAL_FAILURE(
+            mComposerClient->setPowerMode_2_2(mPrimaryDisplay, IComposerClient::PowerMode::ON));
     std::vector<V2_1::Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
     for (auto config : configs) {
         int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
index bb2569f..7377b4b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/VrrConfig.aidl
@@ -42,7 +42,7 @@
     int averageRefreshPeriodNs;
   }
   parcelable NotifyExpectedPresentConfig {
-    int notifyExpectedPresentHeadsUpNs;
-    int notifyExpectedPresentTimeoutNs;
+    int headsUpNs;
+    int timeoutNs;
   }
 }
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 725c947..213e8e9 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -895,9 +895,9 @@
      *
      * The framework will call this function based on the parameters specified in
      * DisplayConfiguration.VrrConfig:
-     * - notifyExpectedPresentTimeoutNs specifies the idle time from the previous present command
-     * where the framework must send the early hint for the next frame.
-     * - notifyExpectedPresentHeadsUpNs specifies minimal time that framework must send
+     * - notifyExpectedPresentConfig.timeoutNs specifies the idle time from the previous
+     * present command where the framework must send the early hint for the next frame.
+     * - notifyExpectedPresentConfig.headsUpNs specifies minimal time that framework must send
      * the early hint before the next frame.
      *
      * The framework can omit calling this API when the next present command matches
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
index 3b241ba..99c1c62 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/VrrConfig.aidl
@@ -45,15 +45,16 @@
          * The minimal time in nanoseconds that IComposerClient.notifyExpectedPresent needs to be
          * called ahead of an expectedPresentTime provided on a presentDisplay command.
          */
-        int notifyExpectedPresentHeadsUpNs;
+        int headsUpNs;
 
         /**
          * The time in nanoseconds that represents a timeout from the previous presentDisplay, which
          * after this point the display needs a call to IComposerClient.notifyExpectedPresent before
-         * sending the next frame. If set to 0, there is no need to call
+         * sending the next frame.
+         * If set to 0, hint is sent for every frame.
          * IComposerClient.notifyExpectedPresent for timeout.
          */
-        int notifyExpectedPresentTimeoutNs;
+        int timeoutNs;
     }
 
     /**
diff --git a/graphics/composer/aidl/vts/ReadbackVts.cpp b/graphics/composer/aidl/vts/ReadbackVts.cpp
index 8605628..c72ec69 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/vts/ReadbackVts.cpp
@@ -293,8 +293,8 @@
 TestBufferLayer::TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
                                  TestRenderEngine& renderEngine, int64_t display, uint32_t width,
                                  uint32_t height, common::PixelFormat format,
-                                 Composition composition)
-    : TestLayer{client, display}, mRenderEngine(renderEngine) {
+                                 ComposerClientWriter& writer, Composition composition)
+    : TestLayer{client, display, writer}, mRenderEngine(renderEngine) {
     mComposition = composition;
     mWidth = width;
     mHeight = height;
diff --git a/graphics/composer/aidl/vts/ReadbackVts.h b/graphics/composer/aidl/vts/ReadbackVts.h
index ee20573..8ac0f4b 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.h
+++ b/graphics/composer/aidl/vts/ReadbackVts.h
@@ -50,9 +50,10 @@
 
 class TestLayer {
   public:
-    TestLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display)
+    TestLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display,
+              ComposerClientWriter& writer)
         : mDisplay(display) {
-        const auto& [status, layer] = client->createLayer(display, kBufferSlotCount);
+        const auto& [status, layer] = client->createLayer(display, kBufferSlotCount, &writer);
         EXPECT_TRUE(status.isOk());
         mLayer = layer;
     }
@@ -108,8 +109,9 @@
 
 class TestColorLayer : public TestLayer {
   public:
-    TestColorLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display)
-        : TestLayer{client, display} {}
+    TestColorLayer(const std::shared_ptr<VtsComposerClient>& client, int64_t display,
+                   ComposerClientWriter& writer)
+        : TestLayer{client, display, writer} {}
 
     void write(ComposerClientWriter& writer) override;
 
@@ -125,7 +127,7 @@
   public:
     TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
                     TestRenderEngine& renderEngine, int64_t display, uint32_t width,
-                    uint32_t height, common::PixelFormat format,
+                    uint32_t height, common::PixelFormat format, ComposerClientWriter& writer,
                     Composition composition = Composition::DEVICE);
 
     void write(ComposerClientWriter& writer) override;
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.cpp b/graphics/composer/aidl/vts/VtsComposerClient.cpp
index ac08cd1..2c24bfb 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.cpp
+++ b/graphics/composer/aidl/vts/VtsComposerClient.cpp
@@ -33,6 +33,14 @@
         mComposer = IComposer::fromBinder(binder);
         ALOGE_IF(mComposer == nullptr, "Failed to acquire the composer from the binder");
     }
+
+    const auto& [status, capabilities] = getCapabilities();
+    EXPECT_TRUE(status.isOk());
+    if (std::any_of(capabilities.begin(), capabilities.end(), [&](const Capability& cap) {
+            return cap == Capability::LAYER_LIFECYCLE_BATCH_COMMAND;
+        })) {
+        mSupportsBatchedCreateLayer = true;
+    }
 }
 
 ScopedAStatus VtsComposerClient::createClient() {
@@ -54,8 +62,8 @@
     return mComposerClient->registerCallback(mComposerCallback);
 }
 
-bool VtsComposerClient::tearDown() {
-    return verifyComposerCallbackParams() && destroyAllLayers();
+bool VtsComposerClient::tearDown(ComposerClientWriter* writer) {
+    return verifyComposerCallbackParams() && destroyAllLayers(writer);
 }
 
 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getInterfaceVersion() const {
@@ -86,7 +94,16 @@
 }
 
 std::pair<ScopedAStatus, int64_t> VtsComposerClient::createLayer(int64_t display,
-                                                                 int32_t bufferSlotCount) {
+                                                                 int32_t bufferSlotCount,
+                                                                 ComposerClientWriter* writer) {
+    if (mSupportsBatchedCreateLayer) {
+        int64_t layer = mNextLayerHandle++;
+        writer->setLayerLifecycleBatchCommandType(display, layer,
+                                                  LayerLifecycleBatchCommandType::CREATE);
+        writer->setNewBufferSlotCount(display, layer, bufferSlotCount);
+        return {addLayerToDisplayResources(display, layer), layer};
+    }
+
     int64_t outLayer;
     auto status = mComposerClient->createLayer(display, bufferSlotCount, &outLayer);
 
@@ -96,14 +113,20 @@
     return {addLayerToDisplayResources(display, outLayer), outLayer};
 }
 
-ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer) {
-    auto status = mComposerClient->destroyLayer(display, layer);
-
-    if (!status.isOk()) {
-        return status;
+ScopedAStatus VtsComposerClient::destroyLayer(int64_t display, int64_t layer,
+                                              ComposerClientWriter* writer) {
+    if (mSupportsBatchedCreateLayer) {
+        writer->setLayerLifecycleBatchCommandType(display, layer,
+                                                  LayerLifecycleBatchCommandType::DESTROY);
+    } else {
+        auto status = mComposerClient->destroyLayer(display, layer);
+        if (!status.isOk()) {
+            return status;
+        }
     }
+
     removeLayerFromDisplayResources(display, layer);
-    return status;
+    return ScopedAStatus::ok();
 }
 
 std::pair<ScopedAStatus, int32_t> VtsComposerClient::getActiveConfig(int64_t display) {
@@ -632,7 +655,7 @@
     return interfaceVersion >= 3;
 }
 
-bool VtsComposerClient::destroyAllLayers() {
+bool VtsComposerClient::destroyAllLayers(ComposerClientWriter* writer) {
     std::unordered_map<int64_t, DisplayResource> physicalDisplays;
     while (!mDisplayResources.empty()) {
         const auto& it = mDisplayResources.begin();
@@ -640,7 +663,7 @@
 
         while (!resource.layers.empty()) {
             auto layer = *resource.layers.begin();
-            const auto status = destroyLayer(display, layer);
+            const auto status = destroyLayer(display, layer, writer);
             if (!status.isOk()) {
                 ALOGE("Unable to destroy all the layers, failed at layer %" PRId64 " with error %s",
                       layer, status.getDescription().c_str());
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index 292bc40..fabc82a 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -25,6 +25,7 @@
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <android/hardware/graphics/composer3/ComposerClientReader.h>
+#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
 #include <binder/ProcessState.h>
 #include <gtest/gtest.h>
 #include <ui/Fence.h>
@@ -59,7 +60,7 @@
 
     ScopedAStatus createClient();
 
-    bool tearDown();
+    bool tearDown(ComposerClientWriter*);
 
     std::pair<ScopedAStatus, int32_t> getInterfaceVersion() const;
 
@@ -69,9 +70,10 @@
 
     ScopedAStatus destroyVirtualDisplay(int64_t display);
 
-    std::pair<ScopedAStatus, int64_t> createLayer(int64_t display, int32_t bufferSlotCount);
+    std::pair<ScopedAStatus, int64_t> createLayer(int64_t display, int32_t bufferSlotCount,
+                                                  ComposerClientWriter*);
 
-    ScopedAStatus destroyLayer(int64_t display, int64_t layer);
+    ScopedAStatus destroyLayer(int64_t display, int64_t layer, ComposerClientWriter*);
 
     std::pair<ScopedAStatus, int32_t> getActiveConfig(int64_t display);
 
@@ -211,7 +213,7 @@
 
     void removeLayerFromDisplayResources(int64_t display, int64_t layer);
 
-    bool destroyAllLayers();
+    bool destroyAllLayers(ComposerClientWriter*);
 
     bool verifyComposerCallbackParams();
 
@@ -229,6 +231,8 @@
     std::shared_ptr<IComposerClient> mComposerClient;
     std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
     std::unordered_map<int64_t, DisplayResource> mDisplayResources;
+    bool mSupportsBatchedCreateLayer = false;
+    std::atomic<int64_t> mNextLayerHandle = 1;
 };
 
 class VtsDisplay {
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 2e3f4df..164e6d5 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -86,7 +86,7 @@
 
     void TearDown() override {
         ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
-        ASSERT_TRUE(mComposerClient->tearDown());
+        ASSERT_TRUE(mComposerClient->tearDown(mWriter.get()));
         mComposerClient.reset();
         const auto errors = mReader.takeErrors();
         ASSERT_TRUE(mReader.takeErrors().empty());
@@ -201,7 +201,8 @@
             return;
         }
 
-        auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto layer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setColor(BLUE);
         layer->setDisplayFrame(coloredSquare);
@@ -270,7 +271,7 @@
 
         auto layer = std::make_shared<TestBufferLayer>(
                 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
-                getDisplayHeight(), common::PixelFormat::RGBA_8888);
+                getDisplayHeight(), common::PixelFormat::RGBA_8888, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -315,7 +316,8 @@
             return;
         }
 
-        auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto layer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setColor(BLUE);
         layer->setDisplayFrame(coloredSquare);
@@ -454,9 +456,9 @@
                 expectedColors, getDisplayWidth(),
                 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
-                                                       getPrimaryDisplayId(), getDisplayWidth(),
-                                                       getDisplayHeight(), PixelFormat::RGBA_FP16);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), PixelFormat::RGBA_FP16, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -550,7 +552,7 @@
 
         auto deviceLayer = std::make_shared<TestBufferLayer>(
                 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
-                getDisplayHeight() / 2, PixelFormat::RGBA_8888);
+                getDisplayHeight() / 2, PixelFormat::RGBA_8888, *mWriter);
         std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
         ReadbackHelper::fillColorsArea(deviceColors, static_cast<int32_t>(deviceLayer->getWidth()),
                                        {0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
@@ -574,7 +576,7 @@
 
         auto clientLayer = std::make_shared<TestBufferLayer>(
                 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), clientWidth,
-                clientHeight, PixelFormat::RGBA_FP16, Composition::DEVICE);
+                clientHeight, PixelFormat::RGBA_FP16, *mWriter, Composition::DEVICE);
         common::Rect clientFrame = {0, getDisplayHeight() / 2, getDisplayWidth(),
                                     getDisplayHeight()};
         clientLayer->setDisplayFrame(clientFrame);
@@ -643,9 +645,9 @@
                 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
         ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
-                                                       getPrimaryDisplayId(), getDisplayWidth(),
-                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -714,7 +716,8 @@
             return;
         }
 
-        auto layer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto layer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         layer->setColor(RED);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
@@ -774,9 +777,9 @@
                 expectedColors, getDisplayWidth(),
                 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
-                                                       getPrimaryDisplayId(), getDisplayWidth(),
-                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
@@ -828,11 +831,13 @@
 
         common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
         common::Rect blueRect = {0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight()};
-        auto redLayer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto redLayer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         redLayer->setColor(RED);
         redLayer->setDisplayFrame(redRect);
 
-        auto blueLayer = std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+        auto blueLayer =
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         blueLayer->setColor(BLUE);
         blueLayer->setDisplayFrame(blueRect);
         blueLayer->setZOrder(5);
@@ -914,14 +919,14 @@
         static constexpr float kMaxBrightnessNits = 300.f;
 
         const auto redLayer =
-                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         redLayer->setColor(RED);
         redLayer->setDisplayFrame(redRect);
         redLayer->setWhitePointNits(kMaxBrightnessNits);
         redLayer->setBrightness(1.f);
 
         const auto dimmerRedLayer =
-                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         dimmerRedLayer->setColor(RED);
         dimmerRedLayer->setDisplayFrame(dimmerRedRect);
         // Intentionally use a small dimming ratio as some implementations may be more likely to
@@ -992,14 +997,14 @@
                                        mTopLayerColor);
 
         auto backgroundLayer =
-                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         backgroundLayer->setZOrder(0);
         backgroundLayer->setColor(mBackgroundColor);
 
-        auto layer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
-                                                       getPrimaryDisplayId(), getDisplayWidth(),
-                                                       getDisplayHeight(), PixelFormat::RGBA_8888);
+        auto layer = std::make_shared<TestBufferLayer>(
+                mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+                getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
         layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         layer->setZOrder(10);
         layer->setDataspace(Dataspace::UNKNOWN);
@@ -1190,7 +1195,7 @@
         GraphicsCompositionTest::SetUp();
 
         auto backgroundLayer =
-                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId());
+                std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
         backgroundLayer->setColor({0.0f, 0.0f, 0.0f, 0.0f});
         backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         backgroundLayer->setZOrder(0);
@@ -1202,7 +1207,7 @@
 
         mLayer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
                                                    getPrimaryDisplayId(), mSideLength, mSideLength,
-                                                   PixelFormat::RGBA_8888);
+                                                   PixelFormat::RGBA_8888, *mWriter);
         mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
         mLayer->setZOrder(10);
 
@@ -1388,7 +1393,7 @@
     void makeLayer() {
         mLayer = std::make_shared<TestBufferLayer>(
                 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
-                getDisplayHeight(), common::PixelFormat::RGBA_8888);
+                getDisplayHeight(), common::PixelFormat::RGBA_8888, *mWriter);
         mLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
         mLayer->setZOrder(10);
         mLayer->setAlpha(1.f);
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index 2bbaf29..5ff420a 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -70,7 +70,7 @@
     }
 
     void TearDown() override {
-        ASSERT_TRUE(mComposerClient->tearDown());
+        ASSERT_TRUE(mComposerClient->tearDown(nullptr));
         mComposerClient.reset();
     }
 
@@ -832,36 +832,58 @@
 }
 
 TEST_P(GraphicsComposerAidlTest, CreateLayer) {
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+        return;
+    }
+
     const auto& [status, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
 
     EXPECT_TRUE(status.isOk());
-    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
 }
 
 TEST_P(GraphicsComposerAidlTest, CreateLayer_BadDisplay) {
-    const auto& [status, _] = mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount);
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "Create layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+        return;
+    }
+
+    const auto& [status, _] =
+            mComposerClient->createLayer(getInvalidDisplayId(), kBufferSlotCount, nullptr);
 
     EXPECT_FALSE(status.isOk());
     EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
 }
 
 TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadDisplay) {
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+        return;
+    }
+
     const auto& [status, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, nullptr);
     EXPECT_TRUE(status.isOk());
 
-    const auto& destroyStatus = mComposerClient->destroyLayer(getInvalidDisplayId(), layer);
+    const auto& destroyStatus =
+            mComposerClient->destroyLayer(getInvalidDisplayId(), layer, nullptr);
 
     EXPECT_FALSE(destroyStatus.isOk());
     EXPECT_NO_FATAL_FAILURE(
             assertServiceSpecificError(destroyStatus, IComposerClient::EX_BAD_DISPLAY));
-    ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+    ASSERT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, nullptr).isOk());
 }
 
 TEST_P(GraphicsComposerAidlTest, DestroyLayer_BadLayerError) {
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "Destroy layer will be tested in GraphicsComposerAidlBatchedCommandTest";
+        return;
+    }
+
     // We haven't created any layers yet, so any id should be invalid
-    const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1);
+    const auto& status = mComposerClient->destroyLayer(getPrimaryDisplayId(), /*layer*/ 1, nullptr);
 
     EXPECT_FALSE(status.isOk());
     EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_LAYER));
@@ -1171,6 +1193,12 @@
     }
 }
 
+TEST_P(GraphicsComposerAidlTest, LayerLifecycleCapabilityNotSupportedOnOldVersions) {
+    if (hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        EXPECT_GE(getInterfaceVersion(), 3);
+    }
+}
+
 class GraphicsComposerAidlV2Test : public GraphicsComposerAidlTest {
   protected:
     void SetUp() override {
@@ -1275,8 +1303,8 @@
                 if (vrrConfig.notifyExpectedPresentConfig) {
                     const auto& notifyExpectedPresentConfig =
                             *vrrConfig.notifyExpectedPresentConfig;
-                    EXPECT_GT(0, notifyExpectedPresentConfig.notifyExpectedPresentHeadsUpNs);
-                    EXPECT_GE(0, notifyExpectedPresentConfig.notifyExpectedPresentTimeoutNs);
+                    EXPECT_GE(notifyExpectedPresentConfig.headsUpNs, 0);
+                    EXPECT_GE(notifyExpectedPresentConfig.timeoutNs, 0);
                 }
             }
         }
@@ -1376,6 +1404,7 @@
         ASSERT_TRUE(mReader.takeErrors().empty());
         ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
 
+        ASSERT_TRUE(mComposerClient->tearDown(&getWriter(getPrimaryDisplayId())));
         ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
     }
 
@@ -1463,10 +1492,10 @@
                                            RenderIntent::COLORIMETRIC)
                             .isOk());
 
-        const auto& [status, layer] =
-                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount);
-        EXPECT_TRUE(status.isOk());
         auto& writer = getWriter(display.getDisplayId());
+        const auto& [status, layer] =
+                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
+        EXPECT_TRUE(status.isOk());
         {
             const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
             ASSERT_NE(nullptr, buffer);
@@ -1506,7 +1535,7 @@
             execute();
         }
 
-        EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer).isOk());
+        EXPECT_TRUE(mComposerClient->destroyLayer(display.getDisplayId(), layer, &writer).isOk());
     }
 
     sp<::android::Fence> presentAndGetFence(
@@ -1541,15 +1570,16 @@
     }
 
     int64_t createOnScreenLayer(Composition composition = Composition::DEVICE) {
+        auto& writer = getWriter(getPrimaryDisplayId());
         const auto& [status, layer] =
-                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
         EXPECT_TRUE(status.isOk());
         Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
                           getPrimaryDisplay().getDisplayHeight()};
         FRect cropRect{0, 0, (float)getPrimaryDisplay().getDisplayWidth(),
                        (float)getPrimaryDisplay().getDisplayHeight()};
         configureLayer(getPrimaryDisplay(), layer, composition, displayFrame, cropRect);
-        auto& writer = getWriter(getPrimaryDisplayId());
+
         writer.setLayerDataspace(getPrimaryDisplayId(), layer, common::Dataspace::UNKNOWN);
         return layer;
     }
@@ -1758,10 +1788,10 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerColorTransform) {
-    const auto& [status, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-    EXPECT_TRUE(status.isOk());
     auto& writer = getWriter(getPrimaryDisplayId());
+    const auto& [status, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(status.isOk());
     writer.setLayerColorTransform(getPrimaryDisplayId(), layer, kIdentity.data());
     execute();
 
@@ -1773,6 +1803,7 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetDisplayBrightness) {
+    EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
     const auto& [status, capabilities] =
             mComposerClient->getDisplayCapabilities(getPrimaryDisplayId());
     ASSERT_TRUE(status.isOk());
@@ -1899,7 +1930,7 @@
         ASSERT_NE(nullptr, handle);
 
         const auto& [layerStatus, layer] =
-                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+                mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
         EXPECT_TRUE(layerStatus.isOk());
 
         Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
@@ -1936,15 +1967,15 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerCursorPosition) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
     const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
 
     Rect displayFrame{0, 0, getPrimaryDisplay().getDisplayWidth(),
@@ -1980,19 +2011,19 @@
     const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
-    const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-    EXPECT_TRUE(layerStatus.isOk());
     auto& writer = getWriter(getPrimaryDisplayId());
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(layerStatus.isOk());
     writer.setLayerBuffer(getPrimaryDisplayId(), layer, /*slot*/ 0, handle, /*acquireFence*/ -1);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBufferMultipleTimes) {
-    const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-    EXPECT_TRUE(layerStatus.isOk());
     auto& writer = getWriter(getPrimaryDisplayId());
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(layerStatus.isOk());
 
     // Setup 3 buffers in the buffer cache, with the last buffer being active. Then, emulate the
     // Android platform code that clears all 3 buffer slots by setting all but the active buffer
@@ -2040,14 +2071,14 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerSurfaceDamage) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerSurfaceDamage(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2062,14 +2093,14 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlockingRegion) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerBlockingRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2084,11 +2115,11 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerBlendMode) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerBlendMode(getPrimaryDisplayId(), layer, BlendMode::NONE);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2103,11 +2134,11 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerColor) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerColor(getPrimaryDisplayId(), layer, Color{1.0f, 1.0f, 1.0f, 1.0f});
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2118,11 +2149,11 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerCompositionType) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerCompositionType(getPrimaryDisplayId(), layer, Composition::CLIENT);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2141,8 +2172,9 @@
 
 TEST_P(GraphicsComposerAidlCommandTest, DisplayDecoration) {
     for (VtsDisplay& display : mDisplays) {
+        auto& writer = getWriter(display.getDisplayId());
         const auto [layerStatus, layer] =
-                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount);
+                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
         EXPECT_TRUE(layerStatus.isOk());
 
         const auto [error, support] =
@@ -2165,8 +2197,7 @@
         }
 
         configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
-                          display.getCrop());
-        auto& writer = getWriter(display.getDisplayId());
+                       display.getCrop());
         writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
                               /*acquireFence*/ -1);
         writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
@@ -2183,31 +2214,31 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerDataspace) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerDataspace(getPrimaryDisplayId(), layer, Dataspace::UNKNOWN);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerDisplayFrame) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerDisplayFrame(getPrimaryDisplayId(), layer, Rect{0, 0, 1, 1});
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerPlaneAlpha) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerPlaneAlpha(getPrimaryDisplayId(), layer, /*alpha*/ 0.0f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2227,31 +2258,31 @@
     const auto handle = buffer->handle;
     ASSERT_NE(nullptr, handle);
 
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerSidebandStream(getPrimaryDisplayId(), layer, handle);
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerSourceCrop) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerSourceCrop(getPrimaryDisplayId(), layer, FRect{0.0f, 0.0f, 1.0f, 1.0f});
     execute();
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerTransform) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerTransform(getPrimaryDisplayId(), layer, static_cast<Transform>(0));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2290,14 +2321,14 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerVisibleRegion) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     Rect empty{0, 0, 0, 0};
     Rect unit{0, 0, 1, 1};
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerVisibleRegion(getPrimaryDisplayId(), layer, std::vector<Rect>(1, empty));
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2312,11 +2343,12 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerZOrder) {
+    auto& writer = getWriter(getPrimaryDisplayId());
+
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     writer.setLayerZOrder(getPrimaryDisplayId(), layer, /*z*/ 10);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2327,8 +2359,9 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, SetLayerPerFrameMetadata) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
 
     /**
@@ -2343,7 +2376,6 @@
      *  white (D65)     0.3127  0.3290
      */
 
-    auto& writer = getWriter(getPrimaryDisplayId());
     std::vector<PerFrameMetadata> aidlMetadata;
     aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680f});
     aidlMetadata.push_back({PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320f});
@@ -2363,18 +2395,19 @@
     const auto errors = mReader.takeErrors();
     if (errors.size() == 1 && errors[0].errorCode == EX_UNSUPPORTED_OPERATION) {
         GTEST_SUCCEED() << "SetLayerPerFrameMetadata is not supported";
-        EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+        EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
         return;
     }
 
-    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer).isOk());
+    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
 }
 
 TEST_P(GraphicsComposerAidlCommandTest, setLayerBrightness) {
-    const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
-
     auto& writer = getWriter(getPrimaryDisplayId());
+
+    const auto& [layerStatus, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+
     writer.setLayerBrightness(getPrimaryDisplayId(), layer, 0.2f);
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
@@ -2603,12 +2636,12 @@
 }
 
 TEST_P(GraphicsComposerAidlCommandV2Test, SetLayerBufferSlotsToClear) {
+    auto& writer = getWriter(getPrimaryDisplayId());
     // Older HAL versions use a backwards compatible way of clearing buffer slots
     // HAL at version 1 or lower does not have LayerCommand::bufferSlotsToClear
     const auto& [layerStatus, layer] =
-            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount);
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
     EXPECT_TRUE(layerStatus.isOk());
-    auto& writer = getWriter(getPrimaryDisplayId());
 
     // setup 3 buffers in the buffer cache, with the last buffer being active
     // then emulate the Android platform code that clears all 3 buffer slots
@@ -2867,7 +2900,8 @@
 
         EXPECT_TRUE(mComposerClient->setPowerMode(displayId, PowerMode::ON).isOk());
 
-        const auto& [status, layer] = mComposerClient->createLayer(displayId, kBufferSlotCount);
+        const auto& [status, layer] =
+                mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
         const auto buffer = allocate(::android::PIXEL_FORMAT_RGBA_8888);
         ASSERT_NE(nullptr, buffer);
         ASSERT_EQ(::android::OK, buffer->initCheck());
@@ -2917,7 +2951,8 @@
     }
 
     for (auto& [displayId, layer] : layers) {
-        EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer).isOk());
+        auto& writer = getWriter(displayId);
+        EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
     }
 
     std::lock_guard guard{readersMutex};
@@ -2927,22 +2962,22 @@
     }
 }
 
-class GraphicsComposerAidlBatchedCommandTest : public GraphicsComposerAidlCommandTest {
+class GraphicsComposerAidlCommandV3Test : public GraphicsComposerAidlCommandTest {
   protected:
     void SetUp() override {
-        GraphicsComposerAidlCommandTest::SetUp();
+        GraphicsComposerAidlTest::SetUp();
         if (getInterfaceVersion() <= 2) {
             GTEST_SKIP() << "Device interface version is expected to be >= 3";
         }
     }
-    void TearDown() override {
-        const auto errors = mReader.takeErrors();
-        ASSERT_TRUE(mReader.takeErrors().empty());
-        ASSERT_NO_FATAL_FAILURE(GraphicsComposerAidlTest::TearDown());
-    }
 };
 
-TEST_P(GraphicsComposerAidlBatchedCommandTest, CreateBatchedCommand) {
+TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
     auto& writer = getWriter(getPrimaryDisplayId());
     int64_t layer = 5;
     writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
@@ -2954,7 +2989,30 @@
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
-TEST_P(GraphicsComposerAidlBatchedCommandTest, DestroyBatchedCommand) {
+TEST_P(GraphicsComposerAidlCommandV3Test, CreateBatchedCommand_BadDisplay) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
+    auto& writer = getWriter(getPrimaryDisplayId());
+    int64_t layer = 5;
+    writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+                                             LayerLifecycleBatchCommandType::CREATE);
+    writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+                           VtsComposerClient::kNoFrameIntervalNs);
+    execute();
+    const auto errors = mReader.takeErrors();
+    ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
     auto& writer = getWriter(getPrimaryDisplayId());
     int64_t layer = 5;
     writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
@@ -2972,10 +3030,42 @@
     writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
 
     execute();
+    const auto errors = mReader.takeErrors();
+    ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
+}
+
+TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand_BadDisplay) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
+    auto& writer = getWriter(getPrimaryDisplayId());
+    int64_t layer = 5;
+    writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
+                                             LayerLifecycleBatchCommandType::CREATE);
+    writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+                           VtsComposerClient::kNoFrameIntervalNs);
+    execute();
+    ASSERT_TRUE(mReader.takeErrors().empty());
+    writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+                                             LayerLifecycleBatchCommandType::DESTROY);
+    layer++;
+    writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+                                             LayerLifecycleBatchCommandType::CREATE);
+    writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
+
+    execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
-TEST_P(GraphicsComposerAidlBatchedCommandTest, NoCreateDestroyBatchedCommandIncorrectLayer) {
+TEST_P(GraphicsComposerAidlCommandV3Test, NoCreateDestroyBatchedCommandIncorrectLayer) {
+    if (!hasCapability(Capability::LAYER_LIFECYCLE_BATCH_COMMAND)) {
+        GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
+        return;
+    }
+
     auto& writer = getWriter(getPrimaryDisplayId());
     int64_t layer = 5;
     writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
@@ -2985,11 +3075,6 @@
     ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_LAYER);
 }
 
-GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlBatchedCommandTest);
-INSTANTIATE_TEST_SUITE_P(
-        PerInstance, GraphicsComposerAidlBatchedCommandTest,
-        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
-        ::android::PrintInstanceNameToString);
 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandTest);
 INSTANTIATE_TEST_SUITE_P(
         PerInstance, GraphicsComposerAidlCommandTest,
@@ -3015,6 +3100,11 @@
         PerInstance, GraphicsComposerAidlCommandV2Test,
         testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
         ::android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlCommandV3Test);
+INSTANTIATE_TEST_SUITE_P(
+        PerInstance, GraphicsComposerAidlCommandV3Test,
+        testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
+        ::android::PrintInstanceNameToString);
 }  // namespace aidl::android::hardware::graphics::composer3::vts
 
 int main(int argc, char** argv) {
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
index e9777d8..0e249d5 100644
--- a/media/bufferpool/aidl/default/BufferPoolClient.cpp
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -297,7 +297,7 @@
       mLastEvictCacheMs(::android::elapsedRealtime()) {
     IAccessor::ConnectionInfo conInfo;
     bool valid = false;
-    if(accessor->connect(observer, &conInfo).isOk()) {
+    if (accessor && accessor->connect(observer, &conInfo).isOk()) {
         auto channel = std::make_unique<BufferStatusChannel>(conInfo.toFmqDesc);
         auto observer = std::make_unique<BufferInvalidationListener>(conInfo.fromFmqDesc);
 
diff --git a/media/c2/aidl/Android.bp b/media/c2/aidl/Android.bp
index 3c0915d..84cb382 100644
--- a/media/c2/aidl/Android.bp
+++ b/media/c2/aidl/Android.bp
@@ -42,11 +42,8 @@
             ],
         },
         rust: {
-            min_sdk_version: "31",
-            enabled: true,
-            additional_rustlibs: [
-                "libnativewindow_rs",
-            ],
+            // No users, and no rust implementation of android.os.Surface yet
+            enabled: false,
         },
     },
 }
diff --git a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
index 32f5abd..04e776e 100644
--- a/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
+++ b/media/c2/aidl/aidl_api/android.hardware.media.c2/current/android/hardware/media/c2/IConfigurable.aidl
@@ -37,12 +37,23 @@
   android.hardware.media.c2.IConfigurable.ConfigResult config(in android.hardware.media.c2.Params inParams, in boolean mayBlock);
   int getId();
   String getName();
-  android.hardware.media.c2.Params query(in int[] indices, in boolean mayBlock);
+  android.hardware.media.c2.IConfigurable.QueryResult query(in int[] indices, in boolean mayBlock);
   android.hardware.media.c2.ParamDescriptor[] querySupportedParams(in int start, in int count);
-  android.hardware.media.c2.FieldSupportedValuesQueryResult[] querySupportedValues(in android.hardware.media.c2.FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
+  android.hardware.media.c2.IConfigurable.QuerySupportedValuesResult querySupportedValues(in android.hardware.media.c2.FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
   @VintfStability
   parcelable ConfigResult {
     android.hardware.media.c2.Params params;
     android.hardware.media.c2.SettingResult[] failures;
+    android.hardware.media.c2.Status status;
+  }
+  @VintfStability
+  parcelable QueryResult {
+    android.hardware.media.c2.Params params;
+    android.hardware.media.c2.Status status;
+  }
+  @VintfStability
+  parcelable QuerySupportedValuesResult {
+    android.hardware.media.c2.FieldSupportedValuesQueryResult[] values;
+    android.hardware.media.c2.Status status;
   }
 }
diff --git a/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl b/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
index 7fdb825..1481c15 100644
--- a/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
+++ b/media/c2/aidl/android/hardware/media/c2/IConfigurable.aidl
@@ -21,6 +21,7 @@
 import android.hardware.media.c2.ParamDescriptor;
 import android.hardware.media.c2.Params;
 import android.hardware.media.c2.SettingResult;
+import android.hardware.media.c2.Status;
 
 /**
  * Generic configuration interface presented by all configurable Codec2 objects.
@@ -34,12 +35,42 @@
      * Return parcelable for config() interface.
      *
      * This includes the successful config settings along with the failure reasons of
-     * the specified setting.
+     * the specified setting. @p status is for the compatibility with HIDL interface.
+     * (The value is defined in Status.aidl, and possible values are enumerated
+     * in config() interface definition)
      */
     @VintfStability
     parcelable ConfigResult {
         Params params;
         SettingResult[] failures;
+        Status status;
+    }
+
+    /**
+     * Return parcelable for query() interface.
+     *
+     * @p params is the parameter descripion for queried configuration indices.
+     * @p status is for the compatibility with HIDL interface. (The value is defined in
+     * Status.aidl, and possible values are enumerated in query() interface definition)
+     */
+    @VintfStability
+    parcelable QueryResult {
+        Params params;
+        Status status;
+    }
+
+    /**
+     * Return parcelable for querySupportedValues() interface.
+     *
+     * @p values is the value descripion for queried configuration fields.
+     * @p status is for the compatibility with HIDL interface. (The value is defined in
+     * Status.aidl, and possible values are enumerated in querySupportedValues()
+     * interface definition)
+     */
+    @VintfStability
+    parcelable QuerySupportedValuesResult {
+        FieldSupportedValuesQueryResult[] values;
+        Status status;
     }
 
     /**
@@ -82,7 +113,8 @@
      * @param mayBlock Whether this call may block or not.
      * @return result of config. Params in the result should be in same order
      *     with @p inParams.
-     * @throws ServiceSpecificException with one of the following values:
+     *
+     *     Returned @p status will be one of the following.
      *   - `Status::NO_MEMORY` - Some supported parameters could not be updated
      *                   successfully because they contained unsupported values.
      *                   These are returned in @p failures.
@@ -146,17 +178,22 @@
      *
      * @param indices List of C2Param structure indices to query.
      * @param mayBlock Whether this call may block or not.
-     * @return Flattened representation of std::vector<C2Param> object.
-     *     Unsupported settings are skipped in the results. The order in @p indices
-     *     still be preserved except skipped settings.
-     * @throws ServiceSpecificException with one of the following values:
+     * @return @p params is the flattened representation of std::vector<C2Param> object.
+     *     Technically unsupported settings can be either skipped or invalidated.
+     *     (Invalidated params will be skipped during unflattening to make these identical.)
+     *     In the future we will want these to be invalidated to make it easier
+     *     for the framework code.
+     *
+     *     The order in @p indices still be preserved except skipped settings.
+     *
+     *     Returned @p status will be one of the following.
      *   - `Status::NO_MEMORY` - Could not allocate memory for a supported parameter.
      *   - `Status::BLOCKING`  - Querying some parameters requires blocking, but
      *                   @p mayBlock is false.
      *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
      *   - `Status::CORRUPTED` - Some unknown error occurred.
      */
-    Params query(in int[] indices, in boolean mayBlock);
+    QueryResult query(in int[] indices, in boolean mayBlock);
 
     /**
      * Returns a list of supported parameters within a selected range of C2Param
@@ -197,9 +234,10 @@
      *
      * @param inFields List of field queries.
      * @param mayBlock Whether this call may block or not.
-     * @return List of supported values and results for the
+     * @return @p values is the list of supported values and results for the
      *     supplied queries.
-     * @throws ServiceSpecificException with one of the following values:
+     *
+     *     Returned @p status will be one of the following.
      *   - `Status::BLOCKING`  - Querying some parameters requires blocking, but
      *                   @p mayBlock is false.
      *   - `Status::NO_MEMORY` - Not enough memory to complete this method.
@@ -208,6 +246,6 @@
      *   - `Status::TIMED_OUT` - The operation cannot be finished in a timely manner.
      *   - `Status::CORRUPTED` - Some unknown error occurred.
      */
-    FieldSupportedValuesQueryResult[] querySupportedValues(
+    QuerySupportedValuesResult querySupportedValues(
             in FieldSupportedValuesQuery[] inFields, in boolean mayBlock);
 }
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
index 1664501..c590d2b 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -57,6 +57,7 @@
   NEA1 = 56,
   NEA2 = 57,
   NEA3 = 58,
+  IMS_NULL = 67,
   SIP_NULL = 68,
   AES_GCM = 69,
   AES_GMAC = 70,
@@ -64,9 +65,8 @@
   DES_EDE3_CBC = 72,
   AES_EDE3_CBC = 73,
   HMAC_SHA1_96 = 74,
-  HMAC_SHA1_96_null = 75,
-  HMAC_MD5_96 = 76,
-  HMAC_MD5_96_null = 77,
+  HMAC_MD5_96 = 75,
+  SRTP_NULL = 86,
   SRTP_AES_COUNTER = 87,
   SRTP_AES_F8 = 88,
   SRTP_HMAC_SHA1 = 89,
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
index 9c2502d..da82b78 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkIndication.aidl
@@ -231,16 +231,24 @@
 
     /*
      * Indicates that a new ciphering or integrity algorithm was used for a particular voice,
-     * signaling, or data connection attempt for a given PLMN and/or access network. Due to
-     * power concerns, once a connection type has been reported on, follow-up reports about that
-     * connection type are only generated if there is any change to the previously reported
-     * encryption or integrity. Thus the AP is only to be notified when there is new information.
-     * List is reset upon rebooting thus info about initial connections is always passed to the
-     * AP after a reboot. List is also reset if the SIM is changed or if there has been a change
-     * in the access network.
+     * signaling, or data connection for a given PLMN and/or access network. Due to power
+     * concerns, once a connection type has been reported on, follow-up reports about that
+     * connection type are only generated if there is any change to the most-recently reported
+     * encryption or integrity, or if the value of SecurityAlgorithmUpdate#isUnprotectedEmergency
+     * changes. A change only in cell ID should not trigger an update, as the design is intended
+     * to be agnostic to dual connectivity ("secondary serving cells").
      *
-     * Note: a change only in cell ID should not trigger an update, as the design is intended to
-     * be agnostic to dual connectivity ("secondary serving cells").
+     * Sample scenario to further clarify "most-recently reported":
+     *
+     * 1. Modem reports user is connected to a null-ciphered 3G network.
+     * 2. User then moves and connects to a well-ciphered 5G network, and modem reports this.
+     * 3. User returns to original location and reconnects to the null-ciphered 3G network. Modem
+     *    should report this as it's different than the most-recently reported data from step (2).
+     *
+     * State is reset when (1) RadioState is transitioned to ON from any other state (e.g. radio
+     * is turned on during device boot, or modem boot), and (2) when CardState is transitioned
+     * to PRESENT from any other state (e.g. when SIM is inserted), or (3) if there is a change in
+     * access network (PLMN).
      *
      * @param type Type of radio indication
      * @param securityAlgorithmUpdate SecurityAlgorithmUpdate encapsulates details of security
diff --git a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
index 71c654c..19feeef 100644
--- a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -59,7 +59,8 @@
     NEA2 = 57,
     NEA3 = 58,
 
-    // SIP layer security (See 3GPP TS 33.203)
+    // IMS and SIP layer security (See 3GPP TS 33.203)
+    IMS_NULL = 67,
     SIP_NULL = 68,
     AES_GCM = 69,
     AES_GMAC = 70,
@@ -67,16 +68,15 @@
     DES_EDE3_CBC = 72,
     AES_EDE3_CBC = 73,
     HMAC_SHA1_96 = 74,
-    HMAC_SHA1_96_null = 75,
-    HMAC_MD5_96 = 76,
-    HMAC_MD5_96_null = 77,
+    HMAC_MD5_96 = 75,
 
     // RTP (see 3GPP TS 33.328)
+    SRTP_NULL = 86,
     SRTP_AES_COUNTER = 87,
     SRTP_AES_F8 = 88,
     SRTP_HMAC_SHA1 = 89,
 
-    // ePDG (3GPP TS 33.402)
+    // ePDG (3GPP TS 33.402) (reserved for future use)
     ENCR_AES_GCM_16 = 99,
     ENCR_AES_CBC = 100,
     AUTH_HMAC_SHA2_256_128 = 101,
diff --git a/radio/aidl/compat/libradiocompat/CallbackManager.cpp b/radio/aidl/compat/libradiocompat/CallbackManager.cpp
index c2eaed1..96aaebc 100644
--- a/radio/aidl/compat/libradiocompat/CallbackManager.cpp
+++ b/radio/aidl/compat/libradiocompat/CallbackManager.cpp
@@ -53,6 +53,10 @@
     return *mRadioResponse;
 }
 
+RadioIndication& CallbackManager::indication() const {
+    return *mRadioIndication;
+}
+
 void CallbackManager::setResponseFunctionsDelayed() {
     std::unique_lock<std::mutex> lock(mDelayedSetterGuard);
     mDelayedSetterDeadline = std::chrono::steady_clock::now() + kDelayedSetterDelay;
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
index f1a7b49..34ab5d7 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/CallbackManager.h
@@ -46,6 +46,7 @@
     ~CallbackManager();
 
     RadioResponse& response() const;
+    RadioIndication& indication() const;
 
     template <typename ResponseType, typename IndicationType>
     void setResponseFunctions(const std::shared_ptr<ResponseType>& response,
diff --git a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
index 63c2eca..1623960 100644
--- a/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
+++ b/secure_element/1.0/vts/functional/VtsHalSecureElementV1_0TargetTest.cpp
@@ -75,6 +75,7 @@
         se_->init(se_cb_);
         auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
         EXPECT_TRUE(res.no_timeout);
+        ASSERT_TRUE(res.args);
         EXPECT_TRUE(res.args->state_);
     }
 
diff --git a/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp b/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
index 234c33c..d7e4546 100644
--- a/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
+++ b/secure_element/1.1/vts/functional/VtsHalSecureElementV1_1TargetTest.cpp
@@ -72,6 +72,7 @@
         se_->init_1_1(se_cb_);
         auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
         EXPECT_TRUE(res.no_timeout);
+        ASSERT_TRUE(res.args);
         EXPECT_TRUE(res.args->state_);
         EXPECT_NE(res.args->reason_, "");
     }
diff --git a/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp b/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
index 66d581e..26b2ded 100644
--- a/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
+++ b/secure_element/1.2/vts/functional/VtsHalSecureElementV1_2TargetTest.cpp
@@ -73,6 +73,7 @@
         se_->init_1_1(se_cb_);
         auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
         EXPECT_TRUE(res.no_timeout);
+        ASSERT_TRUE(res.args);
         EXPECT_TRUE(res.args->state_);
         EXPECT_NE(res.args->reason_, "");
     }
@@ -93,10 +94,12 @@
 
     auto res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
     EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.args);
     EXPECT_FALSE(res.args->state_);
 
     res = se_cb_->WaitForCallback(kCallbackNameOnStateChange);
     EXPECT_TRUE(res.no_timeout);
+    ASSERT_TRUE(res.args);
     EXPECT_TRUE(res.args->state_);
 }
 
diff --git a/security/authgraph/default/src/lib.rs b/security/authgraph/default/src/lib.rs
index 1f851b2..1d6ffb3 100644
--- a/security/authgraph/default/src/lib.rs
+++ b/security/authgraph/default/src/lib.rs
@@ -22,6 +22,7 @@
     ta::{AuthGraphTa, Role},
 };
 use authgraph_hal::channel::SerializedChannel;
+use log::error;
 use std::cell::RefCell;
 use std::rc::Rc;
 use std::sync::{mpsc, Mutex};
@@ -57,10 +58,23 @@
             );
             // Loop forever processing request messages.
             loop {
-                let req_data: Vec<u8> = in_rx.recv().expect("failed to receive next req");
+                let req_data: Vec<u8> = match in_rx.recv() {
+                    Ok(data) => data,
+                    Err(_) => {
+                        error!("local TA failed to receive request!");
+                        break;
+                    }
+                };
                 let rsp_data = ta.process(&req_data);
-                out_tx.send(rsp_data).expect("failed to send out rsp");
+                match out_tx.send(rsp_data) {
+                    Ok(_) => {}
+                    Err(_) => {
+                        error!("local TA failed to send out response");
+                        break;
+                    }
+                }
             }
+            error!("local TA terminating!");
         });
         Ok(Self {
             channels: Mutex::new(Channels { in_tx, out_rx }),
diff --git a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
index 7ccd246..c2509b8 100644
--- a/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyBlobUpgradeTest.cpp
@@ -258,7 +258,8 @@
 
                 if (upgraded_keyblob.empty()) {
                     std::cerr << "Keyblob '" << name << "' did not require upgrade\n";
-                    EXPECT_TRUE(!expectUpgrade) << "Keyblob '" << name << "' unexpectedly upgraded";
+                    EXPECT_FALSE(expectUpgrade)
+                            << "Keyblob '" << name << "' unexpectedly left as-is";
                 } else {
                     // Ensure the old format keyblob is deleted (so any secure deletion data is
                     // cleaned up).
@@ -275,8 +276,7 @@
                     save_keyblob(subdir, name, upgraded_keyblob, key_characteristics);
                     // Cert file is left unchanged.
                     std::cerr << "Keyblob '" << name << "' upgraded\n";
-                    EXPECT_TRUE(expectUpgrade)
-                            << "Keyblob '" << name << "' unexpectedly left as-is";
+                    EXPECT_TRUE(expectUpgrade) << "Keyblob '" << name << "' unexpectedly upgraded";
                 }
             }
         }
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index d4adab5..a2e20dc 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -8796,10 +8796,11 @@
 
 }  // namespace aidl::android::hardware::security::keymint::test
 
+using aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase;
+
 int main(int argc, char** argv) {
     std::cout << "Testing ";
-    auto halInstances =
-            aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::build_params();
+    auto halInstances = KeyMintAidlTestBase::build_params();
     std::cout << "HAL instances:\n";
     for (auto& entry : halInstances) {
         std::cout << "    " << entry << '\n';
@@ -8809,12 +8810,10 @@
     for (int i = 1; i < argc; ++i) {
         if (argv[i][0] == '-') {
             if (std::string(argv[i]) == "--arm_deleteAllKeys") {
-                aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::
-                        arm_deleteAllKeys = true;
+                KeyMintAidlTestBase::arm_deleteAllKeys = true;
             }
             if (std::string(argv[i]) == "--dump_attestations") {
-                aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::
-                        dump_Attestations = true;
+                KeyMintAidlTestBase::dump_Attestations = true;
             } else {
                 std::cout << "NOT dumping attestations" << std::endl;
             }
@@ -8829,8 +8828,7 @@
                     std::cerr << "Missing argument for --keyblob_dir\n";
                     return 1;
                 }
-                aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::keyblob_dir =
-                        std::string(argv[i + 1]);
+                KeyMintAidlTestBase::keyblob_dir = std::string(argv[i + 1]);
                 ++i;
             }
             if (std::string(argv[i]) == "--expect_upgrade") {
@@ -8839,11 +8837,17 @@
                     return 1;
                 }
                 std::string arg = argv[i + 1];
-                aidl::android::hardware::security::keymint::test::KeyMintAidlTestBase::
-                        expect_upgrade =
-                                arg == "yes"
-                                        ? true
-                                        : (arg == "no" ? false : std::optional<bool>(std::nullopt));
+                KeyMintAidlTestBase::expect_upgrade =
+                        arg == "yes" ? true
+                                     : (arg == "no" ? false : std::optional<bool>(std::nullopt));
+                if (KeyMintAidlTestBase::expect_upgrade.has_value()) {
+                    std::cout << "expect_upgrade = "
+                              << (KeyMintAidlTestBase::expect_upgrade.value() ? "true" : "false")
+                              << std::endl;
+                } else {
+                    std::cerr << "Error! Option --expect_upgrade " << arg << " unrecognized"
+                              << std::endl;
+                }
                 ++i;
             }
         }
diff --git a/security/rkp/README.md b/security/rkp/README.md
index 2180d0f..2d00b83 100644
--- a/security/rkp/README.md
+++ b/security/rkp/README.md
@@ -210,10 +210,10 @@
    describes an RKP VM. If there are further certificates without the RKP VM
    marker, then the chain does not describe an RKP VM.
 
-   Implementations must include the first RPK VM marker as early as possible
+   Implementations must include the first RKP VM marker as early as possible
    after the point of divergence between TEE and non-TEE components in the DICE
    chain, prior to loading the Android Bootloader (ABL).
 2. "widevine" or "keymint": If there are no certificates with the RKP VM
    marker then it describes a TEE component.
 3. None: Any component described by a DICE chain that does not match the above
-   two categories.
\ No newline at end of file
+   two categories.
diff --git a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index a1de93e..68b966c 100644
--- a/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/rkp/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -402,7 +402,7 @@
         for (auto& key : keysToSign_) {
             bytevec privateKeyBlob;
             auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &key, &privateKeyBlob);
-            ASSERT_TRUE(status.isOk()) << status.getMessage();
+            ASSERT_TRUE(status.isOk()) << status.getDescription();
 
             vector<uint8_t> payload_value;
             check_maced_pubkey(key, testMode, &payload_value);
@@ -447,7 +447,7 @@
         auto status = provisionable_->generateCertificateRequest(
                 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
                 &protectedData, &keysToSignMac);
-        ASSERT_TRUE(status.isOk()) << status.getMessage();
+        ASSERT_TRUE(status.isOk()) << status.getDescription();
 
         auto result = verifyProductionProtectedData(
                 deviceInfo, cppbor::Array(), keysToSignMac, protectedData, testEekChain_, eekId_,
@@ -472,7 +472,7 @@
     auto status = provisionable_->generateCertificateRequest(
             testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
-    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    ASSERT_TRUE(status.isOk()) << status.getDescription();
 
     auto firstBcc = verifyProductionProtectedData(
             deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
@@ -482,7 +482,7 @@
     status = provisionable_->generateCertificateRequest(
             testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
-    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    ASSERT_TRUE(status.isOk()) << status.getDescription();
 
     auto secondBcc = verifyProductionProtectedData(
             deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
@@ -532,7 +532,7 @@
         auto status = provisionable_->generateCertificateRequest(
                 testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
                 &keysToSignMac);
-        ASSERT_TRUE(status.isOk()) << status.getMessage();
+        ASSERT_TRUE(status.isOk()) << status.getDescription();
 
         auto result = verifyProductionProtectedData(
                 deviceInfo, cborKeysToSign_, keysToSignMac, protectedData, testEekChain_, eekId_,
@@ -576,7 +576,7 @@
     auto status = provisionable_->generateCertificateRequest(
             testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
-    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    ASSERT_FALSE(status.isOk()) << status.getDescription();
     EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
 }
 
@@ -596,7 +596,7 @@
     auto status = provisionable_->generateCertificateRequest(
             testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
             challenge_, &deviceInfo, &protectedData, &keysToSignMac);
-    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    ASSERT_FALSE(status.isOk()) << status.getDescription();
     EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
 }
 
@@ -722,7 +722,7 @@
         auto challenge = randomBytes(size);
         auto status =
                 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
-        ASSERT_TRUE(status.isOk()) << status.getMessage();
+        ASSERT_TRUE(status.isOk()) << status.getDescription();
 
         auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge);
         ASSERT_TRUE(result) << result.message();
@@ -743,7 +743,7 @@
         SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
         auto challenge = randomBytes(size);
         auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr);
-        ASSERT_TRUE(status.isOk()) << status.getMessage();
+        ASSERT_TRUE(status.isOk()) << status.getDescription();
 
         auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge);
         ASSERT_TRUE(result) << result.message();
@@ -758,7 +758,7 @@
 
     auto status = provisionable_->generateCertificateRequestV2(
             /* keysToSign */ {}, randomBytes(MAX_CHALLENGE_SIZE + 1), &csr);
-    EXPECT_FALSE(status.isOk()) << status.getMessage();
+    EXPECT_FALSE(status.isOk()) << status.getDescription();
     EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_FAILED);
 }
 
@@ -773,13 +773,13 @@
     bytevec csr;
 
     auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
-    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    ASSERT_TRUE(status.isOk()) << status.getDescription();
 
     auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
     ASSERT_TRUE(firstCsr) << firstCsr.message();
 
     status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
-    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    ASSERT_TRUE(status.isOk()) << status.getDescription();
 
     auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
     ASSERT_TRUE(secondCsr) << secondCsr.message();
@@ -797,7 +797,7 @@
     bytevec csr;
 
     auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
-    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    ASSERT_TRUE(status.isOk()) << status.getDescription();
 
     auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
     ASSERT_TRUE(result) << result.message();
@@ -815,7 +815,7 @@
     bytevec csr;
     auto status =
             provisionable_->generateCertificateRequestV2({keyWithCorruptMac}, challenge_, &csr);
-    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    ASSERT_FALSE(status.isOk()) << status.getDescription();
     EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
 }
 
@@ -829,7 +829,7 @@
     auto status = provisionable_->generateCertificateRequest(
             false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
-    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    ASSERT_FALSE(status.isOk()) << status.getDescription();
     EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
 }
 
@@ -843,7 +843,7 @@
     auto status = provisionable_->generateCertificateRequest(
             true /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
             &protectedData, &keysToSignMac);
-    ASSERT_FALSE(status.isOk()) << status.getMessage();
+    ASSERT_FALSE(status.isOk()) << status.getDescription();
     EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
 }
 
@@ -927,7 +927,7 @@
     bytevec csr;
     irpcStatus =
             provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
-    ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getMessage();
+    ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getDescription();
 
     auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_);
     ASSERT_TRUE(result) << result.message();
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl
index 87d0233..9887066 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/SecretId.aidl
@@ -35,5 +35,5 @@
 /* @hide */
 @VintfStability
 parcelable SecretId {
-  byte[] id;
+  byte[64] id;
 }
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index 49c3446..b07dba8 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -39,9 +39,14 @@
 
     /**
      * Retrieve the instance of the `IAuthGraphKeyExchange` HAL that should be used for shared
-     * session key establishment.  These keys are used to perform encryption of messages as
+     * session key establishment. These keys are used to perform encryption of messages as
      * described in SecretManagement.cddl, allowing the client and Secretkeeper to have a
-     * cryptographically secure channel.
+     * cryptographically secure channel. In the key exchange protocol the client acts as P1
+     * (source) and Secretkeeper as P2 (sink). The interface returned here can be used to invoke
+     * methods on the sink.
+     *
+     * The client's identity is its DICE chain; Secretkeeper's identity is a
+     * per-boot key pair.
      */
     IAuthGraphKeyExchange getAuthGraphKe();
 
@@ -56,8 +61,8 @@
      * ProtectedRequestPacket & ProtectedResponsePacket using symmetric keys agreed between
      * the client & service. This cryptographic protection is required because the messages are
      * ferried via Android, which is allowed to be outside the TCB of clients (for example protected
-     * Virtual Machines). For this, service (& client) must implement a key exchange protocol, which
-     * is critical for establishing the secure channel.
+     * Virtual Machines). For this, service (& client) must implement the AuthGraph key exchange
+     * protocol to establish a secure channel between them.
      *
      * If an encrypted response cannot be generated, then a service-specific Binder error using one
      * of the ERROR_ codes above will be returned.
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
index bd982e7..b17917f 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretId.aidl
@@ -25,5 +25,5 @@
     /**
      * 64-byte identifier for a secret.
      */
-    byte[] id;
+    byte[64] id;
 }
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
index 3d08078..6a824c9 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/SecretManagement.cddl
@@ -3,10 +3,11 @@
 ; The input parameter to the `processSecretManagementRequest` operation in
 ; `ISecretkeeper.aidl` is always an encrypted request message, CBOR-encoded as a
 ; COSE_Encrypt0 object.  The encryption uses the first of the keys agreed using
-; the associated AuthGraph instance, referred to as `KeySourceToSink`.
-ProtectedRequestPacket = CryptoPayload<RequestPacket, KeySourceToSink>
+; the associated AuthGraph instance, referred to as `KeySourceToSink`. Additionally,
+; an external aad is used - RequestSeqNum.
+ProtectedRequestPacket = CryptoPayload<RequestPacket, KeySourceToSink, RequestSeqNum>
 
-CryptoPayload<Payload, Key> = [ ; COSE_Encrypt0 (untagged), [RFC 9052 s5.2]
+CryptoPayload<Payload, Key, SeqNum> = [ ; COSE_Encrypt0 (untagged), [RFC 9052 s5.2]
     protected: bstr .cbor {
         1 : 3,                  ; Algorithm: AES-GCM mode w/ 256-bit key, 128-bit tag
         4 : bstr                ; key identifier set to session ID produced
@@ -17,7 +18,7 @@
     },
     ciphertext : bstr           ; AES-GCM-256(Key, bstr .cbor Payload)
                                 ; AAD for the encryption is CBOR-serialized
-                                ; Enc_structure (RFC 9052 s5.3) with empty external_aad.
+                                ; Enc_structure (RFC 9052 s5.3) with SeqNum as the external_aad.
 ]
 
 ; Once decrypted, the request packet is an encoded CBOR array holding:
@@ -58,10 +59,18 @@
 SecretId = bstr .size 64        ; Unique identifier of the secret.
 Secret = bstr .size 32          ; The secret value.
 
+; A monotonically incrementing number is associated with each RequestPacket to prevent replay
+; of messages within a session. This starts with 0 and is incremented (by 1) for each request
+; in a session. Secretkeeper implementation must maintain an expected RequestSeqNum for each
+; session (increasing it by 1 for each SecretManagement request received). This will be used in
+; in decryption (external_aad).
+RequestSeqNum = bstr .cbor uint     ; Encoded in accordance with Core Deterministic Encoding
+                                    ; Requirements [RFC 8949 s4.2.1]
+
 ; The return value from a successful `processSecretManagementRequest` operation is a
 ; response message encrypted with the second of the keys agreed using the associated
 ; AuthGraph instance, referred to as `KeySinkToSource`.
-ProtectedResponsePacket = CryptoPayload<ResponsePacket, KeySinkToSource>
+ProtectedResponsePacket = CryptoPayload<ResponsePacket, KeySinkToSource, ResponseSeqNum>
 
 ; Once decrypted, the inner response message is encoded as a CBOR array holding:
 ; - An initial integer return code value.
@@ -82,7 +91,7 @@
     ; Requested Entry not found.
     ErrorCode_EntryNotFound: 3,
     ; Error happened while serialization or deserialization.
-    SerializationError: 4,
+    ErrorCode_SerializationError: 4,
     ; Indicates that Dice Policy matching did not succeed & hence access not granted.
     ErrorCode_DicePolicyError: 5,
 )
@@ -95,8 +104,13 @@
     GetSecretResult,
 )
 
-GetVersionResult = (version : uint)
+GetVersionResult = (1)
 
 StoreSecretResult = ()
 
 GetSecretResult = (secret : Secret)
+
+; Analogous to RequestSeqNum, Secretkeeper must maintain ResponseSeqNum for each session.
+; This will be input to the encryption (ProtectedResponsePacket) as external_aad.
+ResponseSeqNum = bstr .cbor uint    ; Encoded in accordance with Core Deterministic Encoding
+                                    ; Requirements [RFC 8949 s4.2.1]
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index 7fc7a70..7de9d6a 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -27,6 +27,7 @@
     ],
     test_config: "AndroidTest.xml",
     rustlibs: [
+        "libsecretkeeper_client",
         "libsecretkeeper_comm_nostd",
         "libsecretkeeper_core_nostd",
         "android.hardware.security.secretkeeper-V1-rust",
diff --git a/security/secretkeeper/aidl/vts/rustfmt.toml b/security/secretkeeper/aidl/vts/rustfmt.toml
new file mode 120000
index 0000000..ed2086b
--- /dev/null
+++ b/security/secretkeeper/aidl/vts/rustfmt.toml
@@ -0,0 +1 @@
+../../../../../../build/soong/scripts/rustfmt.toml
\ No newline at end of file
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index 6a70d02..c457d24 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -24,18 +24,19 @@
 use binder::StatusCode;
 use coset::{CborSerializable, CoseEncrypt0};
 use log::{info, warn};
+use secretkeeper_client::SkSession;
 use secretkeeper_core::cipher;
 use secretkeeper_comm::data_types::error::SecretkeeperError;
 use secretkeeper_comm::data_types::request::Request;
 use secretkeeper_comm::data_types::request_response_impl::{
     GetVersionRequest, GetVersionResponse, GetSecretRequest, GetSecretResponse, StoreSecretRequest,
     StoreSecretResponse };
-use secretkeeper_comm::data_types::{Id, Secret};
+use secretkeeper_comm::data_types::{Id, Secret, SeqNum};
 use secretkeeper_comm::data_types::response::Response;
 use secretkeeper_comm::data_types::packet::{ResponsePacket, ResponseType};
 
 const SECRETKEEPER_SERVICE: &str = "android.hardware.security.secretkeeper.ISecretkeeper";
-const SECRETKEEPER_INSTANCES: [&'static str; 2] = ["nonsecure", "default"];
+const SECRETKEEPER_INSTANCES: [&'static str; 2] = ["default", "nonsecure"];
 const CURRENT_VERSION: u64 = 1;
 
 // TODO(b/291238565): This will change once libdice_policy switches to Explicit-key DiceCertChain
@@ -75,9 +76,16 @@
     // Initialize logging (which is OK to call multiple times).
     logger::init(logger::Config::default().with_min_level(log::Level::Debug));
 
+    // Determine which instances are available.
+    let available = binder::get_declared_instances(SECRETKEEPER_SERVICE).unwrap_or_default();
+
     // TODO: replace this with a parameterized set of tests that run for each available instance of
     // ISecretkeeper (rather than having a fixed set of instance names to look for).
     for instance in &SECRETKEEPER_INSTANCES {
+        if available.iter().find(|s| s == instance).is_none() {
+            // Skip undeclared instances.
+            continue;
+        }
         let name = format!("{SECRETKEEPER_SERVICE}/{instance}");
         match binder::get_interface(&name) {
             Ok(sk) => {
@@ -88,10 +96,14 @@
                 info!("No /{instance} instance of ISecretkeeper present");
             }
             Err(e) => {
-                panic!("unexpected error while fetching connection to Secretkeeper {:?}", e);
+                panic!(
+                    "unexpected error while fetching connection to Secretkeeper {:?}",
+                    e
+                );
             }
         }
     }
+    info!("no Secretkeeper instances in {SECRETKEEPER_INSTANCES:?} are declared and present");
     None
 }
 
@@ -112,8 +124,7 @@
 struct SkClient {
     sk: binder::Strong<dyn ISecretkeeper>,
     name: String,
-    aes_keys: [key::AesKey; 2],
-    session_id: Vec<u8>,
+    session: SkSession,
 }
 
 impl Drop for SkClient {
@@ -126,27 +137,58 @@
 impl SkClient {
     fn new() -> Option<Self> {
         let (sk, name) = get_connection()?;
-        let (aes_keys, session_id) = authgraph_key_exchange(sk.clone());
-        Some(Self { sk, name, aes_keys, session_id })
+        Some(Self {
+            sk: sk.clone(),
+            name,
+            session: SkSession::new(sk).unwrap(),
+        })
     }
 
-    /// Wrapper around `ISecretkeeper::processSecretManagementRequest` that handles
+    /// This method is wrapper that use `SkSession::secret_management_request` which handles
     /// encryption and decryption.
-    fn secret_management_request(&self, req_data: &[u8]) -> Vec<u8> {
+    fn secret_management_request(&mut self, req_data: &[u8]) -> Vec<u8> {
+        self.session.secret_management_request(req_data).unwrap()
+    }
+
+    /// Unlike the method [`secret_management_request`], this method directly uses
+    /// `cipher::encrypt_message` & `cipher::decrypt_message`, allowing finer control of request
+    /// & response aad.
+    fn secret_management_request_custom_aad(
+        &self,
+        req_data: &[u8],
+        req_aad: &[u8],
+        expected_res_aad: &[u8],
+    ) -> Vec<u8> {
         let aes_gcm = boring::BoringAes;
         let rng = boring::BoringRng;
-        let request_bytes =
-            cipher::encrypt_message(&aes_gcm, &rng, &self.aes_keys[0], &self.session_id, &req_data)
-                .unwrap();
+        let request_bytes = cipher::encrypt_message(
+            &aes_gcm,
+            &rng,
+            self.session.encryption_key(),
+            self.session.session_id(),
+            &req_data,
+            req_aad,
+        )
+        .unwrap();
 
-        let response_bytes = self.sk.processSecretManagementRequest(&request_bytes).unwrap();
+        // Binder call!
+        let response_bytes = self
+            .sk
+            .processSecretManagementRequest(&request_bytes)
+            .unwrap();
 
         let response_encrypt0 = CoseEncrypt0::from_slice(&response_bytes).unwrap();
-        cipher::decrypt_message(&aes_gcm, &self.aes_keys[1], &response_encrypt0).unwrap()
+        cipher::decrypt_message(
+            &aes_gcm,
+            self.session.decryption_key(),
+            &response_encrypt0,
+            expected_res_aad,
+        )
+        .unwrap()
     }
 
     /// Helper method to store a secret.
-    fn store(&self, id: &Id, secret: &Secret) {
+    fn store(&mut self, id: &Id, secret: &Secret) {
         let store_request = StoreSecretRequest {
             id: id.clone(),
             secret: secret.clone(),
@@ -157,14 +199,20 @@
         let store_response = self.secret_management_request(&store_request);
         let store_response = ResponsePacket::from_slice(&store_response).unwrap();
 
-        assert_eq!(store_response.response_type().unwrap(), ResponseType::Success);
+        assert_eq!(
+            store_response.response_type().unwrap(),
+            ResponseType::Success
+        );
         // Really just checking that the response is indeed StoreSecretResponse
         let _ = StoreSecretResponse::deserialize_from_packet(store_response).unwrap();
     }
 
     /// Helper method to get a secret.
-    fn get(&self, id: &Id) -> Option<Secret> {
-        let get_request = GetSecretRequest { id: id.clone(), updated_sealing_policy: None };
+    fn get(&mut self, id: &Id) -> Option<Secret> {
+        let get_request = GetSecretRequest {
+            id: id.clone(),
+            updated_sealing_policy: None,
+        };
         let get_request = get_request.serialize_to_packet().to_vec().unwrap();
 
         let get_response = self.secret_management_request(&get_request);
@@ -183,7 +231,10 @@
 
     /// Helper method to delete secrets.
     fn delete(&self, ids: &[&Id]) {
-        let ids: Vec<SecretId> = ids.iter().map(|id| SecretId { id: id.0.to_vec() }).collect();
+        let ids: Vec<SecretId> = ids
+            .iter()
+            .map(|id| SecretId { id: id.0 })
+            .collect();
         self.sk.deleteIds(&ids).unwrap();
     }
 
@@ -251,7 +302,7 @@
 
 #[test]
 fn secret_management_get_version() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     let request = GetVersionRequest {};
     let request_packet = request.serialize_to_packet();
@@ -260,7 +311,10 @@
     let response_bytes = sk_client.secret_management_request(&request_bytes);
 
     let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
-    assert_eq!(response_packet.response_type().unwrap(), ResponseType::Success);
+    assert_eq!(
+        response_packet.response_type().unwrap(),
+        ResponseType::Success
+    );
     let get_version_response =
         *GetVersionResponse::deserialize_from_packet(response_packet).unwrap();
     assert_eq!(get_version_response.version, CURRENT_VERSION);
@@ -268,7 +322,7 @@
 
 #[test]
 fn secret_management_malformed_request() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     let request = GetVersionRequest {};
     let request_packet = request.serialize_to_packet();
@@ -280,14 +334,17 @@
     let response_bytes = sk_client.secret_management_request(&request_bytes);
 
     let response_packet = ResponsePacket::from_slice(&response_bytes).unwrap();
-    assert_eq!(response_packet.response_type().unwrap(), ResponseType::Error);
+    assert_eq!(
+        response_packet.response_type().unwrap(),
+        ResponseType::Error
+    );
     let err = *SecretkeeperError::deserialize_from_packet(response_packet).unwrap();
     assert_eq!(err, SecretkeeperError::RequestMalformed);
 }
 
 #[test]
 fn secret_management_store_get_secret_found() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
 
@@ -297,7 +354,7 @@
 
 #[test]
 fn secret_management_store_get_secret_not_found() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     // Store a secret (corresponding to an id).
     sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
@@ -308,7 +365,7 @@
 
 #[test]
 fn secretkeeper_store_delete_ids() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
     sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
@@ -325,7 +382,7 @@
 
 #[test]
 fn secretkeeper_store_delete_multiple_ids() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
     sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
@@ -337,7 +394,7 @@
 
 #[test]
 fn secretkeeper_store_delete_duplicate_ids() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
     sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
@@ -350,7 +407,7 @@
 
 #[test]
 fn secretkeeper_store_delete_nonexistent() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     sk_client.store(&ID_EXAMPLE, &SECRET_EXAMPLE);
     sk_client.store(&ID_EXAMPLE_2, &SECRET_EXAMPLE);
@@ -363,7 +420,7 @@
 
 #[test]
 fn secretkeeper_store_delete_all() {
-    let sk_client = setup_client!();
+    let mut sk_client = setup_client!();
 
     if sk_client.name != "nonsecure" {
         // Don't run deleteAll() on a secure device, as it might affect
@@ -389,3 +446,107 @@
     // (Try to) Get the secret that was never stored
     assert_eq!(sk_client.get(&ID_NOT_STORED), None);
 }
+
+// This test checks that Secretkeeper uses the expected [`RequestSeqNum`] as aad while
+// decrypting requests and the responses are encrypted with correct [`ResponseSeqNum`] for the
+// first few messages.
+#[test]
+fn secret_management_replay_protection_seq_num() {
+    let sk_client = setup_client!();
+    // Construct encoded request packets for the test
+    let (req_1, req_2, req_3) = construct_secret_management_requests();
+
+    // Lets now construct the seq_numbers(in request & expected in response)
+    let mut seq_a = SeqNum::new();
+    let [seq_0, seq_1, seq_2] = std::array::from_fn(|_| seq_a.get_then_increment().unwrap());
+
+    // Check first request/response is successful
+    let res = ResponsePacket::from_slice(
+        &sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
+    )
+    .unwrap();
+    assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+
+    // Check 2nd request/response is successful
+    let res = ResponsePacket::from_slice(
+        &sk_client.secret_management_request_custom_aad(&req_2, &seq_1, &seq_1),
+    )
+    .unwrap();
+    assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+
+    // Check 3rd request/response is successful
+    let res = ResponsePacket::from_slice(
+        &sk_client.secret_management_request_custom_aad(&req_3, &seq_2, &seq_2),
+    )
+    .unwrap();
+    assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+}
+
+// This test checks that Secretkeeper uses fresh [`RequestSeqNum`] & [`ResponseSeqNum`]
+// for new sessions.
+#[test]
+fn secret_management_replay_protection_seq_num_per_session() {
+    let sk_client = setup_client!();
+
+    // Construct encoded request packets for the test
+    let (req_1, _, _) = construct_secret_management_requests();
+
+    // Lets now construct the seq_number (in request & expected in response)
+    let mut seq_a = SeqNum::new();
+    let seq_0 = seq_a.get_then_increment().unwrap();
+    // Check first request/response is successful
+    let res = ResponsePacket::from_slice(
+        &sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
+    )
+    .unwrap();
+    assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+
+    // Start another session
+    let sk_client_diff = setup_client!();
+    // Check first request/response is with seq_0 is successful
+    let res = ResponsePacket::from_slice(
+        &sk_client_diff.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0),
+    )
+    .unwrap();
+    assert_eq!(res.response_type().unwrap(), ResponseType::Success);
+}
+
+// This test checks that Secretkeeper rejects requests with out of order [`RequestSeqNum`]
+#[test]
+// TODO(b/317416663): This test fails, when HAL is not present in the device. Refactor to fix this.
+#[ignore]
+#[should_panic]
+fn secret_management_replay_protection_out_of_seq_req_not_accepted() {
+    let sk_client = setup_client!();
+
+    // Construct encoded request packets for the test
+    let (req_1, req_2, _) = construct_secret_management_requests();
+
+    // Lets now construct the seq_numbers(in request & expected in response)
+    let mut seq_a = SeqNum::new();
+    let [seq_0, seq_1, seq_2] = std::array::from_fn(|_| seq_a.get_then_increment().unwrap());
+
+    // Assume First request/response is successful
+    sk_client.secret_management_request_custom_aad(&req_1, &seq_0, &seq_0);
+
+    // Check 2nd request/response with skipped seq_num in request is a binder error
+    // This should panic!
+    sk_client.secret_management_request_custom_aad(&req_2, /*Skipping seq_1*/ &seq_2, &seq_1);
+}
+
+fn construct_secret_management_requests() -> (Vec<u8>, Vec<u8>, Vec<u8>) {
+    let version_request = GetVersionRequest {};
+    let version_request = version_request.serialize_to_packet().to_vec().unwrap();
+    let store_request = StoreSecretRequest {
+        id: ID_EXAMPLE,
+        secret: SECRET_EXAMPLE,
+        sealing_policy: HYPOTHETICAL_DICE_POLICY.to_vec(),
+    };
+    let store_request = store_request.serialize_to_packet().to_vec().unwrap();
+    let get_request = GetSecretRequest {
+        id: ID_EXAMPLE,
+        updated_sealing_policy: None,
+    };
+    let get_request = get_request.serialize_to_packet().to_vec().unwrap();
+    (version_request, store_request, get_request)
+}
diff --git a/security/secretkeeper/default/Android.bp b/security/secretkeeper/default/Android.bp
index 08cc67a..1d75c74 100644
--- a/security/secretkeeper/default/Android.bp
+++ b/security/secretkeeper/default/Android.bp
@@ -18,6 +18,28 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+rust_library {
+    name: "libsecretkeeper_nonsecure",
+    crate_name: "secretkeeper_nonsecure",
+    srcs: [
+        "src/lib.rs",
+    ],
+    vendor_available: true,
+    defaults: [
+        "authgraph_use_latest_hal_aidl_rust",
+    ],
+    rustlibs: [
+        "android.hardware.security.secretkeeper-V1-rust",
+        "libauthgraph_boringssl",
+        "libauthgraph_core",
+        "libauthgraph_hal",
+        "libbinder_rs",
+        "liblog_rust",
+        "libsecretkeeper_core_nostd",
+        "libsecretkeeper_comm_nostd",
+    ],
+}
+
 rust_binary {
     name: "android.hardware.security.secretkeeper-service.nonsecure",
     relative_install_path: "hw",
@@ -30,20 +52,34 @@
     rustlibs: [
         "android.hardware.security.secretkeeper-V1-rust",
         "libandroid_logger",
-        "libauthgraph_boringssl",
-        "libauthgraph_core",
-        "libauthgraph_hal",
         "libbinder_rs",
         "liblog_rust",
-        "libsecretkeeper_comm_nostd",
-        "libsecretkeeper_core_nostd",
         "libsecretkeeper_hal",
+        "libsecretkeeper_nonsecure",
     ],
     srcs: [
         "src/main.rs",
     ],
 }
 
+rust_fuzz {
+    name: "android.hardware.security.secretkeeper-service.nonsecure_fuzzer",
+    rustlibs: [
+        "libsecretkeeper_hal",
+        "libsecretkeeper_nonsecure",
+        "libbinder_random_parcel_rs",
+        "libbinder_rs",
+    ],
+    srcs: ["src/fuzzer.rs"],
+    fuzz_config: {
+        cc: [
+            "alanstokes@google.com",
+            "drysdale@google.com",
+            "shikhapanwar@google.com",
+        ],
+    },
+}
+
 prebuilt_etc {
     name: "secretkeeper.rc",
     src: "secretkeeper.rc",
diff --git a/security/secretkeeper/default/src/fuzzer.rs b/security/secretkeeper/default/src/fuzzer.rs
new file mode 100644
index 0000000..914ebe6
--- /dev/null
+++ b/security/secretkeeper/default/src/fuzzer.rs
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#![allow(missing_docs)]
+#![no_main]
+extern crate libfuzzer_sys;
+
+use binder_random_parcel_rs::fuzz_service;
+use libfuzzer_sys::fuzz_target;
+use secretkeeper_hal::SecretkeeperService;
+use secretkeeper_nonsecure::{AuthGraphChannel, LocalTa, SecretkeeperChannel};
+use std::sync::{Arc, Mutex};
+
+fuzz_target!(|data: &[u8]| {
+    let ta = Arc::new(Mutex::new(LocalTa::new()));
+    let ag_channel = AuthGraphChannel(ta.clone());
+    let sk_channel = SecretkeeperChannel(ta.clone());
+
+    let service = SecretkeeperService::new_as_binder(sk_channel, ag_channel);
+    fuzz_service(&mut service.as_binder(), data);
+});
diff --git a/security/secretkeeper/default/src/lib.rs b/security/secretkeeper/default/src/lib.rs
new file mode 100644
index 0000000..412ad45
--- /dev/null
+++ b/security/secretkeeper/default/src/lib.rs
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+//! Non-secure implementation of a local Secretkeeper TA.
+
+use authgraph_boringssl as boring;
+use authgraph_core::keyexchange::{AuthGraphParticipant, MAX_OPENED_SESSIONS};
+use authgraph_core::ta::{AuthGraphTa, Role};
+use authgraph_hal::channel::SerializedChannel;
+use log::error;
+use secretkeeper_core::ta::SecretkeeperTa;
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::sync::mpsc;
+use std::sync::{Arc, Mutex};
+
+mod store;
+
+/// Implementation of the Secrekeeper TA that runs locally in-process (and which is therefore
+/// insecure).
+pub struct LocalTa {
+    in_tx: mpsc::Sender<Vec<u8>>,
+    out_rx: mpsc::Receiver<Vec<u8>>,
+}
+
+/// Prefix byte for messages intended for the AuthGraph TA.
+const AG_MESSAGE_PREFIX: u8 = 0x00;
+/// Prefix byte for messages intended for the Secretkeeper TA.
+const SK_MESSAGE_PREFIX: u8 = 0x01;
+
+impl LocalTa {
+    /// Create a new instance.
+    pub fn new() -> Self {
+        // Create a pair of channels to communicate with the TA thread.
+        let (in_tx, in_rx) = mpsc::channel();
+        let (out_tx, out_rx) = mpsc::channel();
+
+        // The TA code expects to run single threaded, so spawn a thread to run it in.
+        std::thread::spawn(move || {
+            let mut crypto_impls = boring::crypto_trait_impls();
+            let storage_impl = Box::new(store::InMemoryStore::default());
+            let sk_ta = Rc::new(RefCell::new(
+                SecretkeeperTa::new(&mut crypto_impls, storage_impl)
+                    .expect("Failed to create local Secretkeeper TA"),
+            ));
+            let mut ag_ta = AuthGraphTa::new(
+                AuthGraphParticipant::new(crypto_impls, sk_ta.clone(), MAX_OPENED_SESSIONS)
+                    .expect("Failed to create local AuthGraph TA"),
+                Role::Sink,
+            );
+
+            // Loop forever processing request messages.
+            loop {
+                let req_data: Vec<u8> = match in_rx.recv() {
+                    Ok(data) => data,
+                    Err(_) => {
+                        error!("local TA failed to receive request!");
+                        break;
+                    }
+                };
+                let rsp_data = match req_data[0] {
+                    AG_MESSAGE_PREFIX => ag_ta.process(&req_data[1..]),
+                    SK_MESSAGE_PREFIX => {
+                        // It's safe to `borrow_mut()` because this code is not a callback
+                        // from AuthGraph (the only other holder of an `Rc`), and so there
+                        // can be no live `borrow()`s in this (single) thread.
+                        sk_ta.borrow_mut().process(&req_data[1..])
+                    }
+                    prefix => panic!("unexpected messageprefix {prefix}!"),
+                };
+                match out_tx.send(rsp_data) {
+                    Ok(_) => {}
+                    Err(_) => {
+                        error!("local TA failed to send out response");
+                        break;
+                    }
+                }
+            }
+            error!("local TA terminating!");
+        });
+        Self { in_tx, out_rx }
+    }
+
+    fn execute_for(&mut self, prefix: u8, req_data: &[u8]) -> Vec<u8> {
+        let mut prefixed_req = Vec::with_capacity(req_data.len() + 1);
+        prefixed_req.push(prefix);
+        prefixed_req.extend_from_slice(req_data);
+        self.in_tx
+            .send(prefixed_req)
+            .expect("failed to send in request");
+        self.out_rx.recv().expect("failed to receive response")
+    }
+}
+
+pub struct AuthGraphChannel(pub Arc<Mutex<LocalTa>>);
+
+impl SerializedChannel for AuthGraphChannel {
+    const MAX_SIZE: usize = usize::MAX;
+    fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+        Ok(self
+            .0
+            .lock()
+            .unwrap()
+            .execute_for(AG_MESSAGE_PREFIX, req_data))
+    }
+}
+
+pub struct SecretkeeperChannel(pub Arc<Mutex<LocalTa>>);
+
+impl SerializedChannel for SecretkeeperChannel {
+    const MAX_SIZE: usize = usize::MAX;
+    fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+        Ok(self
+            .0
+            .lock()
+            .unwrap()
+            .execute_for(SK_MESSAGE_PREFIX, req_data))
+    }
+}
diff --git a/security/secretkeeper/default/src/main.rs b/security/secretkeeper/default/src/main.rs
index c8c1521..436f9a7 100644
--- a/security/secretkeeper/default/src/main.rs
+++ b/security/secretkeeper/default/src/main.rs
@@ -15,112 +15,14 @@
  */
 
 //! Non-secure implementation of the Secretkeeper HAL.
-mod store;
 
-use authgraph_boringssl as boring;
-use authgraph_core::keyexchange::{AuthGraphParticipant, MAX_OPENED_SESSIONS};
-use authgraph_core::ta::{AuthGraphTa, Role};
-use authgraph_hal::channel::SerializedChannel;
 use log::{error, info, Level};
-use secretkeeper_core::ta::SecretkeeperTa;
 use secretkeeper_hal::SecretkeeperService;
-use std::sync::Arc;
-use std::sync::Mutex;
-use store::InMemoryStore;
-
+use secretkeeper_nonsecure::{AuthGraphChannel, SecretkeeperChannel, LocalTa};
+use std::sync::{Arc, Mutex};
 use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{
     BpSecretkeeper, ISecretkeeper,
 };
-use std::cell::RefCell;
-use std::rc::Rc;
-use std::sync::mpsc;
-
-/// Implementation of the Secrekeeper TA that runs locally in-process (and which is therefore
-/// insecure).
-pub struct LocalTa {
-    in_tx: mpsc::Sender<Vec<u8>>,
-    out_rx: mpsc::Receiver<Vec<u8>>,
-}
-
-/// Prefix byte for messages intended for the AuthGraph TA.
-const AG_MESSAGE_PREFIX: u8 = 0x00;
-/// Prefix byte for messages intended for the Secretkeeper TA.
-const SK_MESSAGE_PREFIX: u8 = 0x01;
-
-impl LocalTa {
-    /// Create a new instance.
-    pub fn new() -> Self {
-        // Create a pair of channels to communicate with the TA thread.
-        let (in_tx, in_rx) = mpsc::channel();
-        let (out_tx, out_rx) = mpsc::channel();
-
-        // The TA code expects to run single threaded, so spawn a thread to run it in.
-        std::thread::spawn(move || {
-            let mut crypto_impls = boring::crypto_trait_impls();
-            let storage_impl = Box::new(InMemoryStore::default());
-            let sk_ta = Rc::new(RefCell::new(
-                SecretkeeperTa::new(&mut crypto_impls, storage_impl)
-                    .expect("Failed to create local Secretkeeper TA"),
-            ));
-            let mut ag_ta = AuthGraphTa::new(
-                AuthGraphParticipant::new(crypto_impls, sk_ta.clone(), MAX_OPENED_SESSIONS)
-                    .expect("Failed to create local AuthGraph TA"),
-                Role::Sink,
-            );
-
-            // Loop forever processing request messages.
-            loop {
-                let req_data: Vec<u8> = in_rx.recv().expect("failed to receive next req");
-                let rsp_data = match req_data[0] {
-                    AG_MESSAGE_PREFIX => ag_ta.process(&req_data[1..]),
-                    SK_MESSAGE_PREFIX => {
-                        // It's safe to `borrow_mut()` because this code is not a callback
-                        // from AuthGraph (the only other holder of an `Rc`), and so there
-                        // can be no live `borrow()`s in this (single) thread.
-                        sk_ta.borrow_mut().process(&req_data[1..])
-                    }
-                    prefix => panic!("unexpected messageprefix {prefix}!"),
-                };
-                out_tx.send(rsp_data).expect("failed to send out rsp");
-            }
-        });
-        Self { in_tx, out_rx }
-    }
-
-    fn execute_for(&mut self, prefix: u8, req_data: &[u8]) -> Vec<u8> {
-        let mut prefixed_req = Vec::with_capacity(req_data.len() + 1);
-        prefixed_req.push(prefix);
-        prefixed_req.extend_from_slice(req_data);
-        self.in_tx
-            .send(prefixed_req)
-            .expect("failed to send in request");
-        self.out_rx.recv().expect("failed to receive response")
-    }
-}
-
-pub struct AuthGraphChannel(Arc<Mutex<LocalTa>>);
-impl SerializedChannel for AuthGraphChannel {
-    const MAX_SIZE: usize = usize::MAX;
-    fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
-        Ok(self
-            .0
-            .lock()
-            .unwrap()
-            .execute_for(AG_MESSAGE_PREFIX, req_data))
-    }
-}
-
-pub struct SecretkeeperChannel(Arc<Mutex<LocalTa>>);
-impl SerializedChannel for SecretkeeperChannel {
-    const MAX_SIZE: usize = usize::MAX;
-    fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
-        Ok(self
-            .0
-            .lock()
-            .unwrap()
-            .execute_for(SK_MESSAGE_PREFIX, req_data))
-    }
-}
 
 fn main() {
     // Initialize Android logging.
diff --git a/security/secretkeeper/default/src/store.rs b/security/secretkeeper/default/src/store.rs
index a7fb3b7..6c7dba1 100644
--- a/security/secretkeeper/default/src/store.rs
+++ b/security/secretkeeper/default/src/store.rs
@@ -13,12 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+//! In-memory store for nonsecure Secretkeeper.
+
 use secretkeeper_comm::data_types::error::Error;
 use secretkeeper_core::store::KeyValueStore;
 use std::collections::HashMap;
 
-/// An in-memory implementation of KeyValueStore. Please note that this is entirely for
-/// testing purposes. Refer to the documentation of `PolicyGatedStorage` & Secretkeeper HAL for
+/// An in-memory implementation of [`KeyValueStore`]. Please note that this is entirely for testing
+/// purposes. Refer to the documentation of `PolicyGatedStorage` and Secretkeeper HAL for
 /// persistence requirements.
 #[derive(Default)]
 pub struct InMemoryStore(HashMap<Vec<u8>, Vec<u8>>);
diff --git a/sensors/aidl/default/multihal/Android.bp b/sensors/aidl/default/multihal/Android.bp
index a20d6d7..40cb2d9 100644
--- a/sensors/aidl/default/multihal/Android.bp
+++ b/sensors/aidl/default/multihal/Android.bp
@@ -45,11 +45,6 @@
         "HalProxyAidl.cpp",
         "ConvertUtils.cpp",
     ],
-    visibility: [
-        ":__subpackages__",
-        "//hardware/interfaces/sensors/aidl/multihal:__subpackages__",
-        "//hardware/interfaces/tests/extension/sensors:__subpackages__",
-    ],
     static_libs: [
         "android.hardware.sensors@1.0-convert",
         "android.hardware.sensors@2.X-multihal",
diff --git a/tetheroffload/config/1.0/Android.bp b/tetheroffload/config/1.0/Android.bp
index 116c9b6..b5c4185 100644
--- a/tetheroffload/config/1.0/Android.bp
+++ b/tetheroffload/config/1.0/Android.bp
@@ -19,4 +19,8 @@
         "android.hidl.base@1.0",
     ],
     gen_java: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.tethering",
+    ],
 }
diff --git a/tetheroffload/control/1.0/Android.bp b/tetheroffload/control/1.0/Android.bp
index acb5ee8..6589ee2 100644
--- a/tetheroffload/control/1.0/Android.bp
+++ b/tetheroffload/control/1.0/Android.bp
@@ -21,4 +21,8 @@
         "android.hidl.base@1.0",
     ],
     gen_java: true,
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.tethering",
+    ],
 }
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
index dff3c4c..7e1aed7 100644
--- a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/CoolingDevice.aidl
@@ -38,4 +38,7 @@
   android.hardware.thermal.CoolingType type;
   String name;
   long value;
+  long powerLimitMw;
+  long powerMw;
+  long timeWindowMs;
 }
diff --git a/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl
new file mode 100644
index 0000000..ea75b1c
--- /dev/null
+++ b/thermal/aidl/aidl_api/android.hardware.thermal/current/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.thermal;
+/* @hide */
+@VintfStability
+interface ICoolingDeviceChangedCallback {
+  oneway void notifyCoolingDeviceChanged(in android.hardware.thermal.CoolingDevice coolingDevice);
+}
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 c9b6cab..904496c 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
@@ -44,4 +44,6 @@
   void registerThermalChangedCallback(in android.hardware.thermal.IThermalChangedCallback callback);
   void registerThermalChangedCallbackWithType(in android.hardware.thermal.IThermalChangedCallback callback, in android.hardware.thermal.TemperatureType type);
   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);
 }
diff --git a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
index 0c5c17d..406733b 100644
--- a/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
+++ b/thermal/aidl/android/hardware/thermal/CoolingDevice.aidl
@@ -40,4 +40,16 @@
      * means deeper throttling.
      */
     long value;
+    /**
+     * Power budget (mW) of the cooling device.
+     */
+    long powerLimitMw;
+    /**
+     * Target cooling device's AVG power for the last time_window_ms.
+     */
+    long powerMw;
+    /**
+     * The time window (millisecond) to calculate the power consumption
+     */
+    long timeWindowMs;
 }
diff --git a/thermal/aidl/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl b/thermal/aidl/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl
new file mode 100644
index 0000000..e6bb9fe
--- /dev/null
+++ b/thermal/aidl/android/hardware/thermal/ICoolingDeviceChangedCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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 android.hardware.thermal;
+
+import android.hardware.thermal.CoolingDevice;
+import android.hardware.thermal.Temperature;
+
+/**
+ * ICoolingDeviceChangedCallback send cooling device change notification to clients.
+ * @hide
+ */
+@VintfStability
+interface ICoolingDeviceChangedCallback {
+    /**
+     * Send a cooling device change event to all ThermalHAL
+     * cooling device event listeners.
+     *
+     * @param cooling_device The cooling device information associated with the
+     *     change event.
+     */
+    oneway void notifyCoolingDeviceChanged(in CoolingDevice coolingDevice);
+}
diff --git a/thermal/aidl/android/hardware/thermal/IThermal.aidl b/thermal/aidl/android/hardware/thermal/IThermal.aidl
index c94edcd..4aa4090 100644
--- a/thermal/aidl/android/hardware/thermal/IThermal.aidl
+++ b/thermal/aidl/android/hardware/thermal/IThermal.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.thermal.CoolingDevice;
 import android.hardware.thermal.CoolingType;
+import android.hardware.thermal.ICoolingDeviceChangedCallback;
 import android.hardware.thermal.IThermalChangedCallback;
 import android.hardware.thermal.Temperature;
 import android.hardware.thermal.TemperatureThreshold;
@@ -188,4 +189,40 @@
      *         getMessage() must be populated with human-readable error message.
      */
     void unregisterThermalChangedCallback(in IThermalChangedCallback callback);
+
+    /**
+     * Register an ICoolingDeviceChangedCallback for a given CoolingType, used by
+     * the Thermal HAL to receive CDEV events when cooling device status
+     * changed.
+     * Multiple registrations with different ICoolingDeviceChangedCallback must be allowed.
+     * Multiple registrations with same ICoolingDeviceChangedCallback is not allowed, client
+     * should unregister the given ICoolingDeviceChangedCallback first.
+     *
+     * @param callback the ICoolingChangedCallback to use for receiving
+     *    cooling device events. If nullptr callback is given, the status code will be
+     *    STATUS_BAD_VALUE and the operation will fail.
+     * @param type the type to be filtered.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or already registered. And the
+     *         getMessage() must be populated with human-readable error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    void registerCoolingDeviceChangedCallbackWithType(
+            in ICoolingDeviceChangedCallback callback, in CoolingType type);
+
+    /**
+     * Unregister an ICoolingDeviceChangedCallback, used by the Thermal HAL
+     * to receive CDEV events when cooling device status changed.
+     *
+     * @param callback the ICoolingDeviceChangedCallback to use for receiving
+     *    cooling device events. if nullptr callback is given, the status code will be
+     *    STATUS_BAD_VALUE and the operation will fail.
+     *
+     * @throws EX_ILLEGAL_ARGUMENT If the callback is given nullptr or not previously registered.
+     *         And the getMessage() must be populated with human-readable error message.
+     * @throws EX_ILLEGAL_STATE If the Thermal HAL is not initialized successfully. And the
+     *         getMessage() must be populated with human-readable error message.
+     */
+    void unregisterCoolingDeviceChangedCallback(in ICoolingDeviceChangedCallback callback);
 }
diff --git a/thermal/aidl/default/Thermal.cpp b/thermal/aidl/default/Thermal.cpp
index f643d22..41d0be8 100644
--- a/thermal/aidl/default/Thermal.cpp
+++ b/thermal/aidl/default/Thermal.cpp
@@ -142,4 +142,53 @@
     return ScopedAStatus::ok();
 }
 
+ScopedAStatus Thermal::registerCoolingDeviceChangedCallbackWithType(
+        const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback, CoolingType in_type) {
+    LOG(VERBOSE) << __func__ << " ICoolingDeviceChangedCallback: " << in_callback
+                 << ", CoolingType: " << static_cast<int32_t>(in_type);
+    if (in_callback == nullptr) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid nullptr callback");
+    }
+    {
+        std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
+        if (std::any_of(cdev_callbacks_.begin(), cdev_callbacks_.end(),
+                        [&](const std::shared_ptr<ICoolingDeviceChangedCallback>& c) {
+                            return interfacesEqual(c, in_callback);
+                        })) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Callback already registered");
+        }
+        cdev_callbacks_.push_back(in_callback);
+    }
+    return ScopedAStatus::ok();
+}
+
+ScopedAStatus Thermal::unregisterCoolingDeviceChangedCallback(
+        const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback) {
+    LOG(VERBOSE) << __func__ << " ICoolingDeviceChangedCallback: " << in_callback;
+    if (in_callback == nullptr) {
+        return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                "Invalid nullptr callback");
+    }
+    {
+        std::lock_guard<std::mutex> _lock(cdev_callback_mutex_);
+        bool removed = false;
+        cdev_callbacks_.erase(
+                std::remove_if(cdev_callbacks_.begin(), cdev_callbacks_.end(),
+                               [&](const std::shared_ptr<ICoolingDeviceChangedCallback>& c) {
+                                   if (interfacesEqual(c, in_callback)) {
+                                       removed = true;
+                                       return true;
+                                   }
+                                   return false;
+                               }),
+                cdev_callbacks_.end());
+        if (!removed) {
+            return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                                    "Callback wasn't registered");
+        }
+    }
+    return ScopedAStatus::ok();
+}
 }  // namespace aidl::android::hardware::thermal::impl::example
diff --git a/thermal/aidl/default/Thermal.h b/thermal/aidl/default/Thermal.h
index 8885e63..d3d8874 100644
--- a/thermal/aidl/default/Thermal.h
+++ b/thermal/aidl/default/Thermal.h
@@ -46,6 +46,7 @@
 
     ndk::ScopedAStatus registerThermalChangedCallback(
             const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
+
     ndk::ScopedAStatus registerThermalChangedCallbackWithType(
             const std::shared_ptr<IThermalChangedCallback>& in_callback,
             TemperatureType in_type) override;
@@ -53,9 +54,18 @@
     ndk::ScopedAStatus unregisterThermalChangedCallback(
             const std::shared_ptr<IThermalChangedCallback>& in_callback) override;
 
+    ndk::ScopedAStatus registerCoolingDeviceChangedCallbackWithType(
+            const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback,
+            CoolingType in_type) override;
+
+    ndk::ScopedAStatus unregisterCoolingDeviceChangedCallback(
+            const std::shared_ptr<ICoolingDeviceChangedCallback>& in_callback) override;
+
   private:
     std::mutex thermal_callback_mutex_;
     std::vector<std::shared_ptr<IThermalChangedCallback>> thermal_callbacks_;
+    std::mutex cdev_callback_mutex_;
+    std::vector<std::shared_ptr<ICoolingDeviceChangedCallback>> cdev_callbacks_;
 };
 
 }  // namespace example
diff --git a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
index 4b0eb65..403c6c8 100644
--- a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
+++ b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
@@ -26,6 +26,7 @@
 
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
+#include <aidl/android/hardware/thermal/BnCoolingDeviceChangedCallback.h>
 #include <aidl/android/hardware/thermal/BnThermal.h>
 #include <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
 #include <android-base/logging.h>
@@ -59,6 +60,15 @@
         .throttlingStatus = ThrottlingSeverity::CRITICAL,
 };
 
+static const CoolingDevice kCoolingDevice = {
+        .type = CoolingType::CPU,
+        .name = "test cooling device",
+        .value = 1,
+        .powerLimitMw = 300,
+        .powerMw = 500,
+        .timeWindowMs = 7000,
+};
+
 // Callback class for receiving thermal event notifications from main class
 class ThermalCallback : public BnThermalChangedCallback {
   public:
@@ -85,6 +95,33 @@
     bool mInvoke = false;
 };
 
+// Callback class for receiving cooling device event notifications from main class
+class CoolingDeviceCallback : public BnCoolingDeviceChangedCallback {
+  public:
+    ndk::ScopedAStatus notifyCoolingDeviceChanged(const CoolingDevice&) override {
+        {
+            std::lock_guard<std::mutex> lock(mMutex);
+            mInvoke = true;
+        }
+        mNotifyCoolingDeviceChanged.notify_all();
+        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);
+        bool r = mNotifyCoolingDeviceChanged.wait_for(lock, duration,
+                                                      [this] { return this->mInvoke; });
+        mInvoke = false;
+        return r;
+    }
+
+  private:
+    std::mutex mMutex;
+    std::condition_variable mNotifyCoolingDeviceChanged;
+    bool mInvoke = false;
+};
+
 // The main test class for THERMAL HIDL HAL.
 class ThermalAidlTest : public testing::TestWithParam<std::string> {
   public:
@@ -97,19 +134,42 @@
         ASSERT_NE(mThermalCallback, nullptr);
         ::ndk::ScopedAStatus status = mThermal->registerThermalChangedCallback(mThermalCallback);
         ASSERT_TRUE(status.isOk()) << status.getMessage();
+
+        auto ret = mThermal->getInterfaceVersion(&thermal_version);
+        ASSERT_TRUE(ret.isOk()) << ret;
+        if (thermal_version > 1) {
+            mCoolingDeviceCallback = ndk::SharedRefBase::make<CoolingDeviceCallback>();
+            ASSERT_NE(mCoolingDeviceCallback, nullptr);
+            status = mThermal->registerCoolingDeviceChangedCallbackWithType(mCoolingDeviceCallback,
+                                                                            kCoolingDevice.type);
+            ASSERT_TRUE(status.isOk()) << status.getMessage();
+        }
     }
 
     void TearDown() override {
         ::ndk::ScopedAStatus status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
         ASSERT_TRUE(status.isOk()) << status.getMessage();
+
         // Expect to fail if unregister again
         status = mThermal->unregisterThermalChangedCallback(mThermalCallback);
         ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+
+        auto ret = mThermal->getInterfaceVersion(&thermal_version);
+        ASSERT_TRUE(ret.isOk()) << ret;
+        if (thermal_version > 1) {
+            status = mThermal->unregisterCoolingDeviceChangedCallback(mCoolingDeviceCallback);
+            ASSERT_TRUE(status.isOk()) << status.getMessage();
+            status = mThermal->unregisterCoolingDeviceChangedCallback(mCoolingDeviceCallback);
+            ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+        }
     }
+    // Stores thermal version
+    int32_t thermal_version;
 
   protected:
     std::shared_ptr<IThermal> mThermal;
     std::shared_ptr<ThermalCallback> mThermalCallback;
+    std::shared_ptr<CoolingDeviceCallback> mCoolingDeviceCallback;
 };
 
 // Test ThermalChangedCallback::notifyThrottling().
@@ -121,6 +181,21 @@
     ASSERT_TRUE(thermalCallback->waitForCallback(200ms));
 }
 
+// Test CoolingDeviceChangedCallback::notifyCoolingDeviceChanged().
+// This just calls into and back from our local CoolingDeviceChangedCallback impl.
+TEST_P(ThermalAidlTest, NotifyCoolingDeviceChangedTest) {
+    auto ret = mThermal->getInterfaceVersion(&thermal_version);
+    ASSERT_TRUE(ret.isOk()) << ret;
+    if (thermal_version < 2) {
+        return;
+    }
+    std::shared_ptr<CoolingDeviceCallback> cdevCallback =
+            ndk::SharedRefBase::make<CoolingDeviceCallback>();
+    ::ndk::ScopedAStatus status = cdevCallback->notifyCoolingDeviceChanged(kCoolingDevice);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    ASSERT_TRUE(cdevCallback->waitForCallback(200ms));
+}
+
 // Test Thermal->registerThermalChangedCallback.
 TEST_P(ThermalAidlTest, RegisterThermalChangedCallbackTest) {
     // Expect to fail with same callback
@@ -169,6 +244,37 @@
         || status.getExceptionCode() == EX_NULL_POINTER);
 }
 
+// Test Thermal->registerCoolingDeviceChangedCallbackWithType.
+TEST_P(ThermalAidlTest, RegisterCoolingDeviceChangedCallbackWithTypeTest) {
+    auto ret = mThermal->getInterfaceVersion(&thermal_version);
+    ASSERT_TRUE(ret.isOk()) << ret;
+    if (thermal_version < 2) {
+        return;
+    }
+
+    // Expect to fail with same callback
+    ::ndk::ScopedAStatus status = mThermal->registerCoolingDeviceChangedCallbackWithType(
+            mCoolingDeviceCallback, CoolingType::CPU);
+    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
+    // Expect to fail with null callback
+    status = mThermal->registerCoolingDeviceChangedCallbackWithType(nullptr, CoolingType::CPU);
+    ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT ||
+                status.getExceptionCode() == EX_NULL_POINTER);
+    std::shared_ptr<CoolingDeviceCallback> localCoolingDeviceCallback =
+            ndk::SharedRefBase::make<CoolingDeviceCallback>();
+    // Expect to succeed with different callback
+    status = mThermal->registerCoolingDeviceChangedCallbackWithType(localCoolingDeviceCallback,
+                                                                    CoolingType::CPU);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    // Remove the local callback
+    status = mThermal->unregisterCoolingDeviceChangedCallback(localCoolingDeviceCallback);
+    ASSERT_TRUE(status.isOk()) << status.getMessage();
+    // Expect to fail with null callback
+    status = mThermal->unregisterCoolingDeviceChangedCallback(nullptr);
+    ASSERT_TRUE(status.getExceptionCode() == EX_ILLEGAL_ARGUMENT ||
+                status.getExceptionCode() == EX_NULL_POINTER);
+}
+
 // Test Thermal->getCurrentTemperatures().
 TEST_P(ThermalAidlTest, TemperatureTest) {
     std::vector<Temperature> ret;
diff --git a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
index fccd2ed..3d60e89 100644
--- a/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
+++ b/tv/tuner/1.1/vts/functional/VtsHalTvTunerV1_1TargetTest.cpp
@@ -35,6 +35,7 @@
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
     ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFrontendTests.setDemux(demux);
     mFilterTests.setDemux(demux);
     ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.config1_0.type,
                                                filterConf.config1_0.bufferSize));
diff --git a/tv/tuner/aidl/vts/functional/Android.bp b/tv/tuner/aidl/vts/functional/Android.bp
index 513007b..09e63fc 100644
--- a/tv/tuner/aidl/vts/functional/Android.bp
+++ b/tv/tuner/aidl/vts/functional/Android.bp
@@ -37,6 +37,7 @@
         "FrontendTests.cpp",
         "LnbTests.cpp",
         "VtsHalTvTunerTargetTest.cpp",
+        "utils/IpStreamer.cpp",
     ],
     generated_headers: [
         "tuner_testing_dynamic_configuration_V1_0_enums",
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index b0f614e..b7b0185 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -475,6 +475,10 @@
             << "FrontendConfig does not match the frontend info of the given id.";
 
     mIsSoftwareFe = config.isSoftwareFe;
+    std::unique_ptr<IpStreamer> ipThread = std::make_unique<IpStreamer>();
+    if (config.type == FrontendType::IPTV) {
+        ipThread->startIpStream();
+    }
     if (mIsSoftwareFe && testWithDemux) {
         if (getDvrTests()->openDvrInDemux(mDvrConfig.type, mDvrConfig.bufferSize) != success()) {
             ALOGW("[vts] Software frontend dvr configure openDvr failed.");
@@ -494,6 +498,9 @@
         getDvrTests()->startDvrPlayback();
     }
     mFrontendCallback->tuneTestOnLock(mFrontend, config.settings);
+    if (config.type == FrontendType::IPTV) {
+        ipThread->stopIpStream();
+    }
     return AssertionResult(true);
 }
 
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.h b/tv/tuner/aidl/vts/functional/FrontendTests.h
index 1746c8e..9c2ffc0 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.h
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.h
@@ -27,6 +27,7 @@
 
 #include "DvrTests.h"
 #include "VtsHalTvTunerTestConfigurations.h"
+#include "utils/IpStreamer.h"
 
 #define WAIT_TIMEOUT 3000000000
 #define INVALID_ID -1
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 3664b6c..671d079 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -48,6 +48,7 @@
     ASSERT_TRUE(mFrontendTests.setFrontendCallback());
     ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
     ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFrontendTests.setDemux(demux);
     mFilterTests.setDemux(demux);
     ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
     ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
@@ -683,6 +684,10 @@
     if (!live.hasFrontendConnection) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     auto live_configs = generateLiveConfigurations();
     for (auto& configuration : live_configs) {
         live = configuration;
@@ -779,6 +784,10 @@
     if (!live.hasFrontendConnection) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     // TODO use parameterized tests
     auto live_configs = generateLiveConfigurations();
     for (auto& configuration : live_configs) {
@@ -793,6 +802,10 @@
     if (!live.hasFrontendConnection) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     auto live_configs = generateLiveConfigurations();
     for (auto& configuration : live_configs) {
         live = configuration;
@@ -808,6 +821,10 @@
     if (!live.hasFrontendConnection) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     // TODO use parameterized tests
     auto live_configs = generateLiveConfigurations();
     for (auto& configuration : live_configs) {
@@ -1111,6 +1128,10 @@
     if (!record.support) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     auto record_configs = generateRecordConfigurations();
     for (auto& configuration : record_configs) {
         record = configuration;
@@ -1125,6 +1146,10 @@
     if (!record.support) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     auto record_configs = generateRecordConfigurations();
     for (auto& configuration : record_configs) {
         record = configuration;
@@ -1157,6 +1182,10 @@
     if (!record.support) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     auto record_configs = generateRecordConfigurations();
     for (auto& configuration : record_configs) {
         record = configuration;
@@ -1194,9 +1223,17 @@
     if (!scan.hasFrontendConnection) {
         return;
     }
+    // Blind scan is not applicable for IPTV frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
     for (auto& configuration : scan_configs) {
         scan = configuration;
+        // Skip test if the frontend implementation doesn't support blind scan
+        if (!frontendMap[scan.frontendId].supportBlindScan) {
+            continue;
+        }
         mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
     }
 }
@@ -1218,9 +1255,17 @@
     if (!scan.hasFrontendConnection) {
         return;
     }
+    // Blind scan is not application for IPTV frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     vector<ScanHardwareConnections> scan_configs = generateScanConfigurations();
     for (auto& configuration : scan_configs) {
         scan = configuration;
+        // Skip test if the frontend implementation doesn't support blind scan
+        if (!frontendMap[scan.frontendId].supportBlindScan) {
+            continue;
+        }
         mFrontendTests.scanTest(frontendMap[scan.frontendId], FrontendScanType::SCAN_BLIND);
     }
 }
@@ -1242,6 +1287,10 @@
 
 TEST_P(TunerFrontendAidlTest, getHardwareInfo) {
     description("Test Frontend get hardware info");
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     if (!live.hasFrontendConnection) {
         return;
     }
@@ -1289,6 +1338,10 @@
     if (!live.hasFrontendConnection) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     auto live_configs = generateLiveConfigurations();
     for (auto& configuration : live_configs) {
         live = configuration;
@@ -1316,6 +1369,10 @@
     if (!live.hasFrontendConnection) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     auto live_configs = generateLiveConfigurations();
     for (auto& configuration : live_configs) {
         live = configuration;
@@ -1345,6 +1402,10 @@
     if (!live.hasFrontendConnection) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     auto live_configs = generateLiveConfigurations();
     for (auto& configuration : live_configs) {
         live = configuration;
@@ -1358,6 +1419,10 @@
     if (!descrambling.support) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     vector<DescramblingHardwareConnections> descrambling_configs =
             generateDescramblingConfigurations();
     if (descrambling_configs.empty()) {
@@ -1394,6 +1459,10 @@
     if (!descrambling.support) {
         return;
     }
+    // Do not execute tests for IPTV Frontend
+    if (frontendMap[live.frontendId].type == FrontendType::IPTV) {
+        return;
+    }
     vector<DescramblingHardwareConnections> descrambling_configs =
             generateDescramblingConfigurations();
     if (descrambling_configs.empty()) {
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
index 516cb62..5c13ed0 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTestConfigurations.h
@@ -612,6 +612,7 @@
     frontendMap[defaultFeId].isSoftwareFe = true;
     frontendMap[defaultFeId].canConnectToCiCam = true;
     frontendMap[defaultFeId].ciCamId = 0;
+    frontendMap[defaultFeId].supportBlindScan = true;
     FrontendDvbtSettings dvbt;
     dvbt.transmissionMode = FrontendDvbtTransmissionMode::MODE_8K_E;
     frontendMap[defaultFeId].settings.set<FrontendSettings::Tag::dvbt>(dvbt);
diff --git a/tv/tuner/aidl/vts/functional/utils/IpStreamer.cpp b/tv/tuner/aidl/vts/functional/utils/IpStreamer.cpp
new file mode 100644
index 0000000..02b2633
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/utils/IpStreamer.cpp
@@ -0,0 +1,57 @@
+#include "IpStreamer.h"
+
+IpStreamer::IpStreamer() {}
+
+IpStreamer::~IpStreamer() {}
+
+void IpStreamer::startIpStream() {
+    ALOGI("Starting IP Stream thread");
+    mFp = fopen(mFilePath.c_str(), "rb");
+    if (mFp == nullptr) {
+        ALOGE("Failed to open file at path: %s", mFilePath.c_str());
+        return;
+    }
+    mIpStreamerThread = std::thread(&IpStreamer::ipStreamThreadLoop, this, mFp);
+}
+
+void IpStreamer::stopIpStream() {
+    ALOGI("Stopping IP Stream thread");
+    close(mSockfd);
+    if (mFp != nullptr) fclose(mFp);
+    if (mIpStreamerThread.joinable()) {
+        mIpStreamerThread.join();
+    }
+}
+
+void IpStreamer::ipStreamThreadLoop(FILE* fp) {
+    mSockfd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (mSockfd < 0) {
+        ALOGE("IpStreamer::ipStreamThreadLoop: Socket creation failed (%s)", strerror(errno));
+        exit(1);
+    }
+
+    if (mFp == NULL) {
+        ALOGE("IpStreamer::ipStreamThreadLoop: Cannot open file %s: (%s)", mFilePath.c_str(),
+              strerror(errno));
+        exit(1);
+    }
+
+    struct sockaddr_in destaddr;
+    memset(&destaddr, 0, sizeof(destaddr));
+    destaddr.sin_family = mIsIpV4 ? AF_INET : AF_INET6;
+    destaddr.sin_port = htons(mPort);
+    destaddr.sin_addr.s_addr = inet_addr(mIpAddress.c_str());
+
+    char buf[mBufferSize];
+    int n;
+    while (1) {
+        if (fp == nullptr) break;
+        n = fread(buf, 1, mBufferSize, fp);
+        ALOGI("IpStreamer::ipStreamThreadLoop: Bytes read from fread(): %d\n", n);
+        if (n <= 0) {
+            break;
+        }
+        sendto(mSockfd, buf, n, 0, (struct sockaddr*)&destaddr, sizeof(destaddr));
+        sleep(mSleepTime);
+    }
+}
diff --git a/tv/tuner/aidl/vts/functional/utils/IpStreamer.h b/tv/tuner/aidl/vts/functional/utils/IpStreamer.h
new file mode 100644
index 0000000..d073003
--- /dev/null
+++ b/tv/tuner/aidl/vts/functional/utils/IpStreamer.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <log/log.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string>
+#include <thread>
+
+/**
+ * IP Streamer class to send TS data to a specified socket for testing IPTV frontend functions
+ * e.g. tuning and playback.
+ */
+
+class IpStreamer {
+  public:
+    // Constructor for IP Streamer object
+    IpStreamer();
+
+    // Destructor for IP Streamer object
+    ~IpStreamer();
+
+    // Starts a thread to read data from a socket
+    void startIpStream();
+
+    // Stops the reading thread started by startIpStream
+    void stopIpStream();
+
+    // Thread function that consumes data from a socket
+    void ipStreamThreadLoop(FILE* fp);
+
+    std::string getFilePath() { return mFilePath; };
+
+  private:
+    int mSockfd = -1;
+    FILE* mFp;
+    bool mIsIpV4 = true;                                         // By default, set to IPV4
+    int mPort = 12345;                                           // default port
+    int mBufferSize = 188;                                       // bytes
+    int mSleepTime = 1;                                          // second
+    std::string mIpAddress = "127.0.0.1";                        // default IP address
+    std::string mFilePath = "/data/local/tmp/segment000000.ts";  // default path for TS file
+    std::thread mIpStreamerThread;
+};
\ No newline at end of file
diff --git a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
index 9517520..5ffb38f 100644
--- a/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
+++ b/tv/tuner/config/TunerTestingConfigAidlReaderV1_0.h
@@ -114,6 +114,7 @@
     FrontendSettings settings;
     vector<FrontendStatusType> tuneStatusTypes;
     vector<FrontendStatus> expectTuneStatuses;
+    bool supportBlindScan;
 };
 
 struct FilterConfig {
@@ -354,6 +355,11 @@
                 } else {
                     hasHwFe = true;
                 }
+                if (feConfig.hasSupportBlindScan()) {
+                    frontendMap[id].supportBlindScan = feConfig.getSupportBlindScan();
+                } else {
+                    frontendMap[id].supportBlindScan = true;
+                }
                 // TODO: b/182519645 complete the tune status config
                 frontendMap[id].tuneStatusTypes = types;
                 frontendMap[id].expectTuneStatuses = statuses;
diff --git a/tv/tuner/config/api/current.txt b/tv/tuner/config/api/current.txt
index dbd3486..ff2df90 100644
--- a/tv/tuner/config/api/current.txt
+++ b/tv/tuner/config/api/current.txt
@@ -369,6 +369,7 @@
     method @Nullable public android.media.tuner.testing.configuration.V1_0.IsdbsFrontendSettings getIsdbsFrontendSettings_optional();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.IsdbtFrontendSettings getIsdbtFrontendSettings_optional();
     method @Nullable public java.math.BigInteger getRemoveOutputPid();
+    method @Nullable public boolean getSupportBlindScan();
     method @Nullable public android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum getType();
     method public void setAtscFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.AtscFrontendSettings);
     method public void setConnectToCicamId(@Nullable java.math.BigInteger);
@@ -381,6 +382,7 @@
     method public void setIsdbsFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IsdbsFrontendSettings);
     method public void setIsdbtFrontendSettings_optional(@Nullable android.media.tuner.testing.configuration.V1_0.IsdbtFrontendSettings);
     method public void setRemoveOutputPid(@Nullable java.math.BigInteger);
+    method public void setSupportBlindScan(@Nullable boolean);
     method public void setType(@Nullable android.media.tuner.testing.configuration.V1_0.FrontendTypeEnum);
   }
 
diff --git a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
index c51ac51..eafaca9 100644
--- a/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
+++ b/tv/tuner/config/tuner_testing_dynamic_configuration.xsd
@@ -162,6 +162,7 @@
         <xs:attribute name="connectToCicamId" type="xs:nonNegativeInteger" use="optional"/>
         <xs:attribute name="removeOutputPid" type="xs:nonNegativeInteger" use="optional"/>
         <xs:attribute name="endFrequency" type="xs:nonNegativeInteger" use="optional"/>
+        <xs:attribute name="supportBlindScan" type="xs:boolean" use="optional"/>
     </xs:complexType>
 
     <!-- FILTER SESSION -->
diff --git a/uwb/aidl/default/src/uwb_chip.rs b/uwb/aidl/default/src/uwb_chip.rs
index d749147..d1c3c67 100644
--- a/uwb/aidl/default/src/uwb_chip.rs
+++ b/uwb/aidl/default/src/uwb_chip.rs
@@ -61,6 +61,20 @@
             callbacks.as_binder().unlink_to_death(death_recipient)?;
             token.cancel();
             handle.await.unwrap();
+            let packet: UciControlPacket = DeviceResetCmdBuilder {
+                reset_config: ResetConfig::UwbsReset,
+            }
+            .build()
+            .into();
+            // DeviceResetCmd need to be send to reset the device to stop all running
+            // activities on UWBS.
+            let packet_vec: Vec<UciControlPacketHal> = packet.into();
+            for hal_packet in packet_vec.into_iter() {
+                serial
+                    .write(&hal_packet.to_vec())
+                    .map(|written| written as i32)
+                    .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
+            }
             consume_device_reset_rsp_and_ntf(
                 &mut serial
                     .try_clone()
@@ -238,21 +252,7 @@
 
         let mut state = self.state.lock().await;
 
-        if let State::Opened { ref mut serial, .. } = *state {
-            let packet: UciControlPacket = DeviceResetCmdBuilder {
-                reset_config: ResetConfig::UwbsReset,
-            }
-            .build()
-            .into();
-            // DeviceResetCmd need to be send to reset the device to stop all running
-            // activities on UWBS.
-            let packet_vec: Vec<UciControlPacketHal> = packet.into();
-            for hal_packet in packet_vec.into_iter() {
-                serial
-                    .write(&hal_packet.to_vec())
-                    .map(|written| written as i32)
-                    .map_err(|_| binder::StatusCode::UNKNOWN_ERROR)?;
-            }
+        if let State::Opened { .. } = *state {
             state.close().await
         } else {
             Err(binder::ExceptionCode::ILLEGAL_STATE.into())
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 83f3f7e..6c64084 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
@@ -42,8 +42,9 @@
   android.hardware.wifi.RttPreamble preambleSupport;
   android.hardware.wifi.RttBw bwSupport;
   byte mcVersion;
-  android.hardware.wifi.RttPreamble azPreambleSupport;
-  android.hardware.wifi.RttBw azBwSupport;
+  int azPreambleSupport;
+  int azBwSupport;
   boolean ntbInitiatorSupported;
   boolean ntbResponderSupported;
+  @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
 }
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 b53ff9b..3613616 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
@@ -50,4 +50,5 @@
   android.hardware.wifi.RttBw bw;
   long ntbMinMeasurementTime;
   long ntbMaxMeasurementTime;
+  @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
 }
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 9c6ad26..13202ba 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
@@ -63,4 +63,7 @@
   byte r2iTxLtfRepetitionCount;
   long ntbMinMeasurementTime;
   long ntbMaxMeasurementTime;
+  byte numTxSpatialStreams;
+  byte numRxSpatialStreams;
+  @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
index d6ed62e..75f3e83 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtCapabilities.aidl
@@ -38,8 +38,8 @@
   boolean isTwtResponderSupported;
   boolean isBroadcastTwtSupported;
   boolean isFlexibleTwtScheduleSupported;
-  int minWakeDurationMicros;
-  int maxWakeDurationMicros;
-  long minWakeIntervalMicros;
-  long maxWakeIntervalMicros;
+  int minWakeDurationUs;
+  int maxWakeDurationUs;
+  long minWakeIntervalUs;
+  long maxWakeIntervalUs;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
index 06c7ae2..1e1c39a 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtRequest.aidl
@@ -35,8 +35,8 @@
 @VintfStability
 parcelable TwtRequest {
   int mloLinkId;
-  int minWakeDurationMicros;
-  int maxWakeDurationMicros;
-  long minWakeIntervalMicros;
-  long maxWakeIntervalMicros;
+  int minWakeDurationUs;
+  int maxWakeDurationUs;
+  long minWakeIntervalUs;
+  long maxWakeIntervalUs;
 }
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
index 4e5ca44..0b88d8e 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSession.aidl
@@ -36,8 +36,8 @@
 parcelable TwtSession {
   int sessionId;
   int mloLinkId;
-  int wakeDurationMicros;
-  long wakeIntervalMicros;
+  int wakeDurationUs;
+  long wakeIntervalUs;
   android.hardware.wifi.TwtSession.TwtNegotiationType negotiationType;
   boolean isTriggerEnabled;
   boolean isAnnounced;
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl
index 528444a..f62b614 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/TwtSessionStats.aidl
@@ -38,6 +38,6 @@
   int avgRxPktCount;
   int avgTxPktSize;
   int avgRxPktSize;
-  int avgEospDurationMicros;
+  int avgEospDurationUs;
   int eospCount;
 }
diff --git a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
index c4b7d24..c193924 100644
--- a/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttCapabilities.aidl
@@ -18,6 +18,7 @@
 
 import android.hardware.wifi.RttBw;
 import android.hardware.wifi.RttPreamble;
+import android.hardware.wifi.common.OuiKeyedData;
 
 /**
  * RTT Capabilities.
@@ -64,12 +65,12 @@
      * Bit mask indicating what preamble is supported by IEEE 802.11az initiator.
      * Combination of |RttPreamble| values.
      */
-    RttPreamble azPreambleSupport;
+    int azPreambleSupport;
     /**
      * Bit mask indicating what BW is supported by IEEE 802.11az initiator.
      * Combination of |RttBw| values.
      */
-    RttBw azBwSupport;
+    int azBwSupport;
     /**
      * Whether the initiator supports IEEE 802.11az Non-Trigger-based (non-TB) measurement.
      */
@@ -78,4 +79,9 @@
      * Whether IEEE 802.11az Non-Trigger-based (non-TB) responder mode is supported.
      */
     boolean ntbResponderSupported;
+    /**
+     * Optional vendor-specific parameters. Null value indicates
+     * that no vendor data is provided.
+     */
+    @nullable OuiKeyedData[] vendorData;
 }
diff --git a/wifi/aidl/android/hardware/wifi/RttConfig.aidl b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
index 7b18708..496ffd2 100644
--- a/wifi/aidl/android/hardware/wifi/RttConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttConfig.aidl
@@ -21,6 +21,7 @@
 import android.hardware.wifi.RttPreamble;
 import android.hardware.wifi.RttType;
 import android.hardware.wifi.WifiChannelInfo;
+import android.hardware.wifi.common.OuiKeyedData;
 
 /**
  * RTT configuration.
@@ -134,4 +135,9 @@
      * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
      */
     long ntbMaxMeasurementTime;
+    /**
+     * Optional vendor-specific parameters. Null value indicates
+     * that no vendor data is provided.
+     */
+    @nullable OuiKeyedData[] vendorData;
 }
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
index ab9abb5..2f9aefe 100644
--- a/wifi/aidl/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -21,6 +21,7 @@
 import android.hardware.wifi.RttType;
 import android.hardware.wifi.WifiInformationElement;
 import android.hardware.wifi.WifiRateInfo;
+import android.hardware.wifi.common.OuiKeyedData;
 
 /**
  * RTT results.
@@ -148,11 +149,15 @@
     /**
      * Multiple transmissions of HE-LTF symbols in an HE (I2R) Ranging NDP. An HE-LTF repetition
      * value of 1 indicates no repetitions.
+     *
+     * Note: A required field for IEEE 802.11az result.
      */
     byte i2rTxLtfRepetitionCount;
     /**
      * Multiple transmissions of HE-LTF symbols in an HE (R2I) Ranging NDP. An HE-LTF repetition
      * value of 1 indicates no repetitions.
+     *
+     * Note: A required field for IEEE 802.11az result.
      */
     byte r2iTxLtfRepetitionCount;
     /**
@@ -168,6 +173,8 @@
      * |RttResult.timestamp|.
      *
      * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
+     *
+     * Note: A required field for IEEE 802.11az result.
      */
     long ntbMinMeasurementTime;
     /**
@@ -183,6 +190,27 @@
      * non-TB ranging negotiation.
      *
      * Reference: IEEE Std 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element.
+     *
+     * Note: A required field for IEEE 802.11az result.
      */
     long ntbMaxMeasurementTime;
+    /**
+     * Number of transmit space-time streams used. Value is in the range 1 to 8.
+     *
+     * Note: Maximum limit is ultimately defined by the number of antennas that can be supported.
+     * A required field for IEEE 802.11az result.
+     */
+    byte numTxSpatialStreams;
+    /**
+     * Number of receive space-time streams used. Value is in the range 1 to 8.
+     *
+     * Note: Maximum limit is ultimately defined by the number of antennas that can be supported.
+     * A required field for IEEE 802.11az result.
+     */
+    byte numRxSpatialStreams;
+    /**
+     * Optional vendor-specific parameters. Null value indicates
+     * that no vendor data is provided.
+     */
+    @nullable OuiKeyedData[] vendorData;
 }
diff --git a/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl b/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
index 4012c3e..28d16f0 100644
--- a/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
+++ b/wifi/aidl/android/hardware/wifi/TwtCapabilities.aidl
@@ -18,6 +18,14 @@
 
 /**
  * Target Wake Time (TWT) Capabilities supported.
+ *
+ * TWT allows Wi-Fi stations to manage activity in a network by scheduling to operate at different
+ * times. This minimizes the contention and reduces the required amount of time that a station
+ * utilizing a power management mode needs to be awake.
+ *
+ * IEEE 802.11ax standard defines two modes of TWT operation:
+ *  - Individual TWT (default mode of operation if TWT requester is supported)
+ *  - Broadcast TWT
  */
 @VintfStability
 parcelable TwtCapabilities {
@@ -40,17 +48,17 @@
     /**
      * Minimum TWT wake duration in microseconds.
      */
-    int minWakeDurationMicros;
+    int minWakeDurationUs;
     /**
      * Maximum TWT wake duration in microseconds.
      */
-    int maxWakeDurationMicros;
+    int maxWakeDurationUs;
     /**
      * Minimum TWT wake interval in microseconds.
      */
-    long minWakeIntervalMicros;
+    long minWakeIntervalUs;
     /**
      * Maximum TWT wake interval in microseconds.
      */
-    long maxWakeIntervalMicros;
+    long maxWakeIntervalUs;
 }
diff --git a/wifi/aidl/android/hardware/wifi/TwtRequest.aidl b/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
index b063da3..6964a39 100644
--- a/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
+++ b/wifi/aidl/android/hardware/wifi/TwtRequest.aidl
@@ -28,17 +28,23 @@
     /**
      * Minimum TWT wake duration in microseconds.
      */
-    int minWakeDurationMicros;
+    int minWakeDurationUs;
     /**
      * Maximum TWT wake duration in microseconds.
+     *
+     * As per IEEE 802.11ax spec, section 9.4.2.199 TWT element, the maximum wake duration is
+     * 65280 microseconds.
      */
-    int maxWakeDurationMicros;
+    int maxWakeDurationUs;
     /**
      * Minimum TWT wake interval in microseconds.
      */
-    long minWakeIntervalMicros;
+    long minWakeIntervalUs;
     /**
      * Maximum TWT wake interval in microseconds.
+     *
+     * As per IEEE 802.11ax spec, section 9.4.2.199 TWT element, the maximum wake interval is
+     * 65535 * 2^31 microseconds.
      */
-    long maxWakeIntervalMicros;
+    long maxWakeIntervalUs;
 }
diff --git a/wifi/aidl/android/hardware/wifi/TwtSession.aidl b/wifi/aidl/android/hardware/wifi/TwtSession.aidl
index 6b780f8..2d7e819 100644
--- a/wifi/aidl/android/hardware/wifi/TwtSession.aidl
+++ b/wifi/aidl/android/hardware/wifi/TwtSession.aidl
@@ -41,12 +41,12 @@
     /**
      * TWT service period in microseconds.
      */
-    int wakeDurationMicros;
+    int wakeDurationUs;
 
     /**
      * Time interval in microseconds between two successive TWT service periods.
      */
-    long wakeIntervalMicros;
+    long wakeIntervalUs;
 
     /**
      * TWT negotiation type.
diff --git a/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl b/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl
index e2e2d12..ba70426 100644
--- a/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl
+++ b/wifi/aidl/android/hardware/wifi/TwtSessionStats.aidl
@@ -44,7 +44,7 @@
     /**
      * Average End of Service period in microseconds.
      */
-    int avgEospDurationMicros;
+    int avgEospDurationUs;
 
     /**
      * Count of early terminations.
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index 7e7929d..0f0c77e 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -2886,8 +2886,8 @@
     aidl_capabilities->bwSupport = convertLegacyRttBwBitmapToAidl(legacy_capabilities.bw_support);
     aidl_capabilities->mcVersion = legacy_capabilities.mc_version;
     // Initialize 11az parameters to default
-    aidl_capabilities->azPreambleSupport = RttPreamble::INVALID;
-    aidl_capabilities->azBwSupport = RttBw::BW_UNSPECIFIED;
+    aidl_capabilities->azPreambleSupport = (int)RttPreamble::INVALID;
+    aidl_capabilities->azBwSupport = (int)RttBw::BW_UNSPECIFIED;
     aidl_capabilities->ntbInitiatorSupported = false;
     aidl_capabilities->ntbResponderSupported = false;
     return true;
@@ -2912,9 +2912,9 @@
             convertLegacyRttBwBitmapToAidl(legacy_capabilities_v3.rtt_capab.bw_support);
     aidl_capabilities->mcVersion = legacy_capabilities_v3.rtt_capab.mc_version;
     aidl_capabilities->azPreambleSupport =
-            convertLegacyRttPreambleBitmapToAidl(legacy_capabilities_v3.az_preamble_support);
+            (int)convertLegacyRttPreambleBitmapToAidl(legacy_capabilities_v3.az_preamble_support);
     aidl_capabilities->azBwSupport =
-            convertLegacyRttBwBitmapToAidl(legacy_capabilities_v3.az_bw_support);
+            (int)convertLegacyRttBwBitmapToAidl(legacy_capabilities_v3.az_bw_support);
     aidl_capabilities->ntbInitiatorSupported = legacy_capabilities_v3.ntb_initiator_supported;
     aidl_capabilities->ntbResponderSupported = legacy_capabilities_v3.ntb_responder_supported;
     return true;
@@ -2995,6 +2995,8 @@
         aidl_result.r2iTxLtfRepetitionCount = 0;
         aidl_result.ntbMinMeasurementTime = 0;
         aidl_result.ntbMaxMeasurementTime = 0;
+        aidl_result.numTxSpatialStreams = 0;
+        aidl_result.numRxSpatialStreams = 0;
         aidl_results->push_back(aidl_result);
     }
     return true;
@@ -3019,6 +3021,8 @@
         aidl_result.r2iTxLtfRepetitionCount = 0;
         aidl_result.ntbMinMeasurementTime = 0;
         aidl_result.ntbMaxMeasurementTime = 0;
+        aidl_result.numTxSpatialStreams = 0;
+        aidl_result.numRxSpatialStreams = 0;
         aidl_results->push_back(aidl_result);
     }
     return true;
@@ -3044,6 +3048,8 @@
         aidl_result.r2iTxLtfRepetitionCount = legacy_result->r2i_tx_ltf_repetition_count;
         aidl_result.ntbMinMeasurementTime = legacy_result->ntb_min_measurement_time;
         aidl_result.ntbMaxMeasurementTime = legacy_result->ntb_max_measurement_time;
+        aidl_result.numTxSpatialStreams = legacy_result->num_tx_sts;
+        aidl_result.numRxSpatialStreams = legacy_result->num_rx_sts;
         aidl_results->push_back(aidl_result);
     }
     return true;
@@ -3587,13 +3593,13 @@
     if (legacy_twt_capabs.min_wake_duration_micros > legacy_twt_capabs.max_wake_duration_micros) {
         return false;
     }
-    aidl_twt_capabs->minWakeDurationMicros = legacy_twt_capabs.min_wake_duration_micros;
-    aidl_twt_capabs->maxWakeDurationMicros = legacy_twt_capabs.max_wake_duration_micros;
+    aidl_twt_capabs->minWakeDurationUs = legacy_twt_capabs.min_wake_duration_micros;
+    aidl_twt_capabs->maxWakeDurationUs = legacy_twt_capabs.max_wake_duration_micros;
     if (legacy_twt_capabs.min_wake_interval_micros > legacy_twt_capabs.max_wake_interval_micros) {
         return false;
     }
-    aidl_twt_capabs->minWakeIntervalMicros = legacy_twt_capabs.min_wake_interval_micros;
-    aidl_twt_capabs->maxWakeIntervalMicros = legacy_twt_capabs.max_wake_interval_micros;
+    aidl_twt_capabs->minWakeIntervalUs = legacy_twt_capabs.min_wake_interval_micros;
+    aidl_twt_capabs->maxWakeIntervalUs = legacy_twt_capabs.max_wake_interval_micros;
     return true;
 }
 
@@ -3603,16 +3609,16 @@
         return false;
     }
     legacy_twt_request->mlo_link_id = aidl_twt_request.mloLinkId;
-    if (aidl_twt_request.minWakeDurationMicros > aidl_twt_request.maxWakeDurationMicros) {
+    if (aidl_twt_request.minWakeDurationUs > aidl_twt_request.maxWakeDurationUs) {
         return false;
     }
-    legacy_twt_request->min_wake_duration_micros = aidl_twt_request.minWakeDurationMicros;
-    legacy_twt_request->max_wake_duration_micros = aidl_twt_request.maxWakeDurationMicros;
-    if (aidl_twt_request.minWakeIntervalMicros > aidl_twt_request.maxWakeIntervalMicros) {
+    legacy_twt_request->min_wake_duration_micros = aidl_twt_request.minWakeDurationUs;
+    legacy_twt_request->max_wake_duration_micros = aidl_twt_request.maxWakeDurationUs;
+    if (aidl_twt_request.minWakeIntervalUs > aidl_twt_request.maxWakeIntervalUs) {
         return false;
     }
-    legacy_twt_request->min_wake_interval_micros = aidl_twt_request.minWakeIntervalMicros;
-    legacy_twt_request->max_wake_interval_micros = aidl_twt_request.maxWakeIntervalMicros;
+    legacy_twt_request->min_wake_interval_micros = aidl_twt_request.minWakeIntervalUs;
+    legacy_twt_request->max_wake_interval_micros = aidl_twt_request.maxWakeIntervalUs;
     return true;
 }
 
@@ -3664,8 +3670,8 @@
 
     aidl_twt_session->sessionId = twt_session.session_id;
     aidl_twt_session->mloLinkId = twt_session.mlo_link_id;
-    aidl_twt_session->wakeDurationMicros = twt_session.wake_duration_micros;
-    aidl_twt_session->wakeIntervalMicros = twt_session.wake_interval_micros;
+    aidl_twt_session->wakeDurationUs = twt_session.wake_duration_micros;
+    aidl_twt_session->wakeIntervalUs = twt_session.wake_interval_micros;
     switch (twt_session.negotiation_type) {
         case WIFI_TWT_NEGO_TYPE_INDIVIDUAL:
             aidl_twt_session->negotiationType = TwtSession::TwtNegotiationType::INDIVIDUAL;
@@ -3696,7 +3702,7 @@
     aidl_twt_stats->avgRxPktCount = twt_stats.avg_pkt_num_rx;
     aidl_twt_stats->avgTxPktSize = twt_stats.avg_tx_pkt_size;
     aidl_twt_stats->avgRxPktSize = twt_stats.avg_rx_pkt_size;
-    aidl_twt_stats->avgEospDurationMicros = twt_stats.avg_eosp_dur_us;
+    aidl_twt_stats->avgEospDurationUs = twt_stats.avg_eosp_dur_us;
     aidl_twt_stats->eospCount = twt_stats.eosp_count;
 
     return true;
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 0729646..05a7548 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
@@ -42,6 +42,9 @@
   void cancelConnect();
   void cancelServiceDiscovery(in long identifier);
   void cancelWps(in String groupIfName);
+  /**
+   * @deprecated This method is deprecated from AIDL v3, newer HALs should use configureExtListenWithParams.
+   */
   void configureExtListen(in int periodInMillis, in int intervalInMillis);
   /**
    * @deprecated This method is deprecated from AIDL v3, newer HALs should use connectWithParams.
@@ -111,4 +114,5 @@
   void configureEapolIpAddressAllocationParams(in int ipAddressGo, in int ipAddressMask, in int ipAddressStart, in int ipAddressEnd);
   String connectWithParams(in android.hardware.wifi.supplicant.P2pConnectInfo connectInfo);
   void findWithParams(in android.hardware.wifi.supplicant.P2pDiscoveryInfo discoveryInfo);
+  void configureExtListenWithParams(in android.hardware.wifi.supplicant.P2pExtListenInfo extListenInfo);
 }
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 851e851..4811565 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
@@ -35,7 +35,7 @@
 @VintfStability
 interface ISupplicantP2pIfaceCallback {
   /**
-   * @deprecated This callback is deprecated from AIDL v2, newer HAL should call onDeviceFoundWithParams.
+   * @deprecated This callback is deprecated from AIDL v3, newer HAL should call onDeviceFoundWithParams.
    */
   oneway void onDeviceFound(in byte[] srcAddress, in byte[] p2pDeviceAddress, in byte[] primaryDeviceType, in String deviceName, in android.hardware.wifi.supplicant.WpsConfigMethods configMethods, in byte deviceCapabilities, in android.hardware.wifi.supplicant.P2pGroupCapabilityMask groupCapabilities, in byte[] wfdDeviceInfo);
   oneway void onDeviceLost(in byte[] p2pDeviceAddress);
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 898c2d4..9fa8f56 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
@@ -54,7 +54,7 @@
   oneway void onExtRadioWorkTimeout(in int id);
   oneway void onHs20DeauthImminentNotice(in byte[] bssid, in int reasonCode, in int reAuthDelayInSec, in String url);
   /**
-   * @deprecated No longer in use.
+   * @deprecated This callback is deprecated from AIDL v3.
    */
   oneway void onHs20IconQueryDone(in byte[] bssid, in String fileName, in byte[] data);
   oneway void onHs20SubscriptionRemediation(in byte[] bssid, in android.hardware.wifi.supplicant.OsuMethod osuMethod, in String url);
diff --git a/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl
new file mode 100644
index 0000000..b4d8e9d
--- /dev/null
+++ b/wifi/supplicant/aidl/aidl_api/android.hardware.wifi.supplicant/current/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl
@@ -0,0 +1,40 @@
+/**
+ * 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.supplicant;
+@VintfStability
+parcelable P2pExtListenInfo {
+  int periodMs;
+  int intervalMs;
+  @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
+}
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 0ff0653..46366cc 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
@@ -37,7 +37,7 @@
   byte[6] p2pDeviceAddress;
   boolean isRequest;
   android.hardware.wifi.supplicant.P2pProvDiscStatusCode status;
-  android.hardware.wifi.supplicant.WpsConfigMethods configMethods;
+  int configMethods;
   String generatedPin;
   String groupInterfaceName;
   @nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
index 983ed15..8b78a4a 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.aidl
@@ -24,6 +24,7 @@
 import android.hardware.wifi.supplicant.MiracastMode;
 import android.hardware.wifi.supplicant.P2pConnectInfo;
 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.WpsConfigMethods;
@@ -165,6 +166,9 @@
      * (with interval obviously having to be larger than or equal to duration).
      * If the P2P module is not idle at the time the Extended Listen Timing
      * timeout occurs, the Listen State operation must be skipped.
+     * <p>
+     * @deprecated This method is deprecated from AIDL v3, newer HALs should use
+     * configureExtListenWithParams.
      *
      * @param periodInMillis Period in milliseconds.
      * @param intervalInMillis Interval in milliseconds.
@@ -882,4 +886,21 @@
      *         |SupplicantStatusCode.FAILURE_IFACE_DISABLED|
      */
     void findWithParams(in P2pDiscoveryInfo discoveryInfo);
+
+    /**
+     * Configure Extended Listen Timing.
+     *
+     * If enabled, listen state must be entered every |intervalMs| for at
+     * least |periodMs|. Both values have acceptable range of 1-65535
+     * (note that the interval must be larger than or equal to the duration).
+     * If the P2P module is not idle at the time the Extended Listen Timing
+     * timeout occurs, the Listen State operation must be skipped.
+     *
+     * @param extListenInfo Parameters to configure extended listening timing.
+     * @throws ServiceSpecificException with one of the following values:
+     *         |SupplicantStatusCode.FAILURE_ARGS_INVALID|,
+     *         |SupplicantStatusCode.FAILURE_UNKNOWN|,
+     *         |SupplicantStatusCode.FAILURE_IFACE_INVALID|
+     */
+    void configureExtListenWithParams(in P2pExtListenInfo extListenInfo);
 }
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
index 11cd867..b9273a8 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.aidl
@@ -40,7 +40,7 @@
     /**
      * Used to indicate that a P2P device has been found.
      * <p>
-     * @deprecated This callback is deprecated from AIDL v2, newer HAL should call
+     * @deprecated This callback is deprecated from AIDL v3, newer HAL should call
      * onDeviceFoundWithParams.
      *
      * @param srcAddress MAC address of the device found. This must either
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
index 58893eb..172fcda 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.aidl
@@ -198,7 +198,7 @@
     /**
      * Used to indicate the result of Hotspot 2.0 Icon query.
      *
-     * @deprecated No longer in use.
+     * @deprecated This callback is deprecated from AIDL v3.
      *
      * @param bssid BSSID of the access point.
      * @param fileName Name of the file that was requested.
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl
new file mode 100644
index 0000000..1086c94
--- /dev/null
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pExtListenInfo.aidl
@@ -0,0 +1,39 @@
+/**
+ * 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 android.hardware.wifi.supplicant;
+
+import android.hardware.wifi.common.OuiKeyedData;
+
+/**
+ * Parameters used to configure the P2P Extended Listen Interval.
+ */
+@VintfStability
+parcelable P2pExtListenInfo {
+    /**
+     * Period in milliseconds.
+     */
+    int periodMs;
+    /**
+     * Interval in milliseconds.
+     */
+    int intervalMs;
+    /**
+     * Optional vendor-specific parameters. Null value indicates
+     * that no vendor data is provided.
+     */
+    @nullable OuiKeyedData[] vendorData;
+}
diff --git a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
index b559216..05152a9 100644
--- a/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
+++ b/wifi/supplicant/aidl/android/hardware/wifi/supplicant/P2pProvisionDiscoveryCompletedEventParams.aidl
@@ -18,7 +18,6 @@
 
 import android.hardware.wifi.common.OuiKeyedData;
 import android.hardware.wifi.supplicant.P2pProvDiscStatusCode;
-import android.hardware.wifi.supplicant.WpsConfigMethods;
 
 /**
  * Parameters passed as a part of P2P provision discovery frame notification.
@@ -34,8 +33,8 @@
     boolean isRequest;
     /** Status of the provision discovery */
     P2pProvDiscStatusCode status;
-    /** Mask of WPS configuration methods supported */
-    WpsConfigMethods configMethods;
+    /** Mask of |WpsConfigMethods| indicating the supported methods */
+    int configMethods;
     /** 8-digit pin generated */
     String generatedPin;
     /**