Merge "Convert hardware/interfaces/keymaster/3.0/default/Android.mk to Android.bp" into main am: ab18a3b5a7

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

Change-Id: Iabbaee5593824d690609f672cd402893800fe5e2
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp
index f9e3eb4..4902497 100644
--- a/audio/aidl/Android.bp
+++ b/audio/aidl/Android.bp
@@ -64,6 +64,9 @@
             ],
             min_sdk_version: "31",
         },
+        rust: {
+            enabled: true,
+        },
     },
     versions_with_info: [
         {
@@ -112,6 +115,13 @@
     ],
 }
 
+rust_defaults {
+    name: "latest_android_hardware_audio_common_rust",
+    rustlibs: [
+        latest_android_hardware_audio_common + "-rust",
+    ],
+}
+
 aidl_interface_defaults {
     name: "latest_android_hardware_audio_common_import_interface",
     imports: [
diff --git a/audio/aidl/common/include/Utils.h b/audio/aidl/common/include/Utils.h
index dd216e5..6241f44 100644
--- a/audio/aidl/common/include/Utils.h
+++ b/audio/aidl/common/include/Utils.h
@@ -48,6 +48,9 @@
 
 namespace aidl::android::hardware::audio::common {
 
+// TODO: b/275135031 - move this string to AIDL interfaces.
+static constexpr char kDumpFromAudioServerArgument[] = "dump_from_audioserver";
+
 // Some values are reserved for use by the system code only.
 // HALs must not accept or emit values outside from the provided list.
 constexpr std::array<::aidl::android::media::audio::common::AudioMode, 5> kValidAudioModes = {
diff --git a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
index b023df1..0c201cc 100644
--- a/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
+++ b/audio/aidl/vts/VtsHalDynamicsProcessingTest.cpp
@@ -453,12 +453,11 @@
     ENGINE_TEST_INSTANCE_NAME,
     ENGINE_TEST_RESOLUTION_PREFERENCE,
     ENGINE_TEST_PREFERRED_DURATION,
-    ENGINE_TEST_STAGE_ENABLEMENT,
-    ENGINE_TEST_LIMITER_IN_USE
+    ENGINE_TEST_STAGE_ENABLEMENT
 };
 using EngineArchitectureTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
                                                 DynamicsProcessing::ResolutionPreference, float,
-                                                DynamicsProcessing::StageEnablement, bool>;
+                                                DynamicsProcessing::StageEnablement>;
 
 void fillEngineArchConfig(DynamicsProcessing::EngineArchitecture& cfg,
                           const EngineArchitectureTestParams& params) {
@@ -466,7 +465,7 @@
     cfg.preferredProcessingDurationMs = std::get<ENGINE_TEST_PREFERRED_DURATION>(params);
     cfg.preEqStage = cfg.postEqStage = cfg.mbcStage =
             std::get<ENGINE_TEST_STAGE_ENABLEMENT>(params);
-    cfg.limiterInUse = std::get<ENGINE_TEST_LIMITER_IN_USE>(params);
+    cfg.limiterInUse = true;
 }
 
 class DynamicsProcessingTestEngineArchitecture
@@ -501,8 +500,8 @@
                         static_cast<DynamicsProcessing::ResolutionPreference>(-1)),  // variant
                 testing::Values(-10.f, 0.f, 10.f),  // processing duration
                 testing::ValuesIn(
-                        DynamicsProcessingTestHelper::kStageEnablementTestSet),  // preEQ/postEQ/mbc
-                testing::Bool()),                                                // limiter enable
+                        DynamicsProcessingTestHelper::kStageEnablementTestSet)  // preEQ/postEQ/mbc
+                ),
         [](const auto& info) {
             auto descriptor = std::get<ENGINE_TEST_INSTANCE_NAME>(info.param).second;
             DynamicsProcessing::EngineArchitecture cfg;
@@ -568,7 +567,6 @@
     LIMITER_CHANNEL,
     LIMITER_ENABLE,
     LIMITER_LINK_GROUP,
-    LIMITER_ENGINE_IN_USE,
     LIMITER_ADDITIONAL,
 };
 enum LimiterConfigTestAdditionalParam {
@@ -587,9 +585,8 @@
          {1, -60, 2.5, -2, 3.14},
          {1, 60, 2.5, -2, 3.14}}};
 
-using LimiterConfigTestParams =
-        std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool, int32_t, bool,
-                   LimiterConfigTestAdditional>;
+using LimiterConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
+                                           int32_t, bool, int32_t, LimiterConfigTestAdditional>;
 
 void fillLimiterConfig(DynamicsProcessing::LimiterConfig& cfg,
                        const LimiterConfigTestParams& params) {
@@ -609,8 +606,7 @@
       public DynamicsProcessingTestHelper {
   public:
     DynamicsProcessingTestLimiterConfig()
-        : DynamicsProcessingTestHelper(std::get<LIMITER_INSTANCE_NAME>(GetParam())),
-          mLimiterInUseEngine(std::get<LIMITER_ENGINE_IN_USE>(GetParam())) {
+        : DynamicsProcessingTestHelper(std::get<LIMITER_INSTANCE_NAME>(GetParam())) {
         fillLimiterConfig(mCfg, GetParam());
     }
 
@@ -619,11 +615,9 @@
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     DynamicsProcessing::LimiterConfig mCfg;
-    bool mLimiterInUseEngine;
 };
 
 TEST_P(DynamicsProcessingTestLimiterConfig, SetAndGetLimiterConfig) {
-    mEngineConfigPreset.limiterInUse = mLimiterInUseEngine;
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     EXPECT_NO_FATAL_FAILURE(addLimiterConfig({mCfg}));
     SetAndGetDynamicsProcessingParameters();
@@ -633,21 +627,18 @@
         DynamicsProcessingTest, DynamicsProcessingTestLimiterConfig,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
-                           testing::Values(-1, 0, 1, 2),  // channel count
-                           testing::Bool(),               // enable
-                           testing::Values(3),            // link group
-                           testing::Bool(),               // engine limiter enable
+                           testing::Values(-1, 0, 1, 2),                           // channel count
+                           testing::Bool(),                                        // enable
+                           testing::Values(3),                                     // link group
                            testing::ValuesIn(kLimiterConfigTestAdditionalParam)),  // Additional
         [](const auto& info) {
             auto descriptor = std::get<LIMITER_INSTANCE_NAME>(info.param).second;
             DynamicsProcessing::LimiterConfig cfg;
             fillLimiterConfig(cfg, info.param);
-            std::string engineLimiterInUse =
-                    std::to_string(std::get<LIMITER_ENGINE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
                                toString(descriptor.common.id.uuid) + "_limiterConfig_" +
-                               cfg.toString() + "_engineSetting_" + engineLimiterInUse;
+                               cfg.toString();
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -659,11 +650,10 @@
  */
 enum ChannelConfigTestParamName {
     BAND_CHANNEL_TEST_INSTANCE_NAME,
-    BAND_CHANNEL_TEST_CHANNEL_CONFIG,
-    BAND_CHANNEL_TEST_ENGINE_IN_USE
+    BAND_CHANNEL_TEST_CHANNEL_CONFIG
 };
 using ChannelConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
-                                           std::vector<DynamicsProcessing::ChannelConfig>, bool>;
+                                           std::vector<DynamicsProcessing::ChannelConfig>>;
 
 class DynamicsProcessingTestChannelConfig
     : public ::testing::TestWithParam<ChannelConfigTestParams>,
@@ -671,33 +661,28 @@
   public:
     DynamicsProcessingTestChannelConfig()
         : DynamicsProcessingTestHelper(std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(GetParam())),
-          mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())),
-          mInUseEngine(std::get<BAND_CHANNEL_TEST_ENGINE_IN_USE>(GetParam())) {}
+          mCfg(std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(GetParam())) {}
 
     void SetUp() override { SetUpDynamicsProcessingEffect(); }
 
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     std::vector<DynamicsProcessing::ChannelConfig> mCfg;
-    const bool mInUseEngine;
 };
 
 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPreEqChannelConfig) {
-    mEngineConfigPreset.preEqStage.inUse = mInUseEngine;
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     EXPECT_NO_FATAL_FAILURE(addPreEqChannelConfig(mCfg));
     SetAndGetDynamicsProcessingParameters();
 }
 
 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetPostEqChannelConfig) {
-    mEngineConfigPreset.postEqStage.inUse = mInUseEngine;
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     EXPECT_NO_FATAL_FAILURE(addPostEqChannelConfig(mCfg));
     SetAndGetDynamicsProcessingParameters();
 }
 
 TEST_P(DynamicsProcessingTestChannelConfig, SetAndGetMbcChannelConfig) {
-    mEngineConfigPreset.mbcStage.inUse = mInUseEngine;
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     EXPECT_NO_FATAL_FAILURE(addMbcChannelConfig(mCfg));
     SetAndGetDynamicsProcessingParameters();
@@ -709,19 +694,15 @@
                 testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                         IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
                 testing::ValuesIn(
-                        DynamicsProcessingTestHelper::kChannelConfigTestSet),  // channel config
-                testing::Bool()),                                              // Engine inUse
+                        DynamicsProcessingTestHelper::kChannelConfigTestSet)),  // channel config
         [](const auto& info) {
             auto descriptor = std::get<BAND_CHANNEL_TEST_INSTANCE_NAME>(info.param).second;
-            std::string engineInUse =
-                    std::to_string(std::get<BAND_CHANNEL_TEST_ENGINE_IN_USE>(info.param));
             std::string channelConfig = ::android::internal::ToString(
                     std::get<BAND_CHANNEL_TEST_CHANNEL_CONFIG>(info.param));
 
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               toString(descriptor.common.id.uuid) + "_" + channelConfig +
-                               "_engineInUse_" + engineInUse;
+                               toString(descriptor.common.id.uuid) + "_" + channelConfig;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -736,11 +717,10 @@
     EQ_BAND_CHANNEL,
     EQ_BAND_ENABLE,
     EQ_BAND_CUT_OFF_FREQ,
-    EQ_BAND_GAIN,
-    EQ_BAND_STAGE_IN_USE
+    EQ_BAND_GAIN
 };
 using EqBandConfigTestParams = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t,
-                                          bool, std::vector<std::pair<int, float>>, float, bool>;
+                                          bool, std::vector<std::pair<int, float>>, float>;
 
 void fillEqBandConfig(std::vector<DynamicsProcessing::EqBandConfig>& cfgs,
                       const EqBandConfigTestParams& params) {
@@ -760,8 +740,7 @@
                                            public DynamicsProcessingTestHelper {
   public:
     DynamicsProcessingTestEqBandConfig()
-        : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())),
-          mStageInUse(std::get<EQ_BAND_STAGE_IN_USE>(GetParam())) {
+        : DynamicsProcessingTestHelper(std::get<EQ_BAND_INSTANCE_NAME>(GetParam())) {
         fillEqBandConfig(mCfgs, GetParam());
     }
 
@@ -770,11 +749,9 @@
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     std::vector<DynamicsProcessing::EqBandConfig> mCfgs;
-    const bool mStageInUse;
 };
 
 TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPreEqBandConfig) {
-    mEngineConfigPreset.preEqStage.inUse = mStageInUse;
     mEngineConfigPreset.preEqStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
@@ -788,7 +765,6 @@
 }
 
 TEST_P(DynamicsProcessingTestEqBandConfig, SetAndGetPostEqBandConfig) {
-    mEngineConfigPreset.postEqStage.inUse = mStageInUse;
     mEngineConfigPreset.postEqStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
@@ -849,21 +825,19 @@
         DynamicsProcessingTest, DynamicsProcessingTestEqBandConfig,
         ::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
                                    IFactory::descriptor, getEffectTypeUuidDynamicsProcessing())),
-                           testing::Values(-1, 0, 10),      // channel ID
-                           testing::Bool(),                 // band enable
-                           testing::ValuesIn(kBands),       // cut off frequencies
-                           testing::Values(-3.14f, 3.14f),  // gain
-                           testing::Values(true)),          // stage in use
+                           testing::Values(-1, 0, 10),     // channel ID
+                           testing::Bool(),                // band enable
+                           testing::ValuesIn(kBands),      // cut off frequencies
+                           testing::Values(-3.14f, 3.14f)  // gain
+                           ),
         [](const auto& info) {
             auto descriptor = std::get<EQ_BAND_INSTANCE_NAME>(info.param).second;
             std::vector<DynamicsProcessing::EqBandConfig> cfgs;
             fillEqBandConfig(cfgs, info.param);
             std::string bands = ::android::internal::ToString(cfgs);
-            std::string stageInUse = std::to_string(std::get<EQ_BAND_STAGE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               toString(descriptor.common.id.uuid) + "_bands_" + bands +
-                               "_stageInUse_" + stageInUse;
+                               toString(descriptor.common.id.uuid) + "_bands_" + bands;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
@@ -879,7 +853,6 @@
     MBC_BAND_CHANNEL,
     MBC_BAND_ENABLE,
     MBC_BAND_CUTOFF_FREQ,
-    MBC_BAND_STAGE_IN_USE,
     MBC_BAND_ADDITIONAL
 };
 enum MbcBandConfigAdditional {
@@ -905,7 +878,7 @@
 
 using TestParamsMbcBandConfig =
         std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int32_t, bool,
-                   std::vector<std::pair<int, float>>, bool, TestParamsMbcBandConfigAdditional>;
+                   std::vector<std::pair<int, float>>, TestParamsMbcBandConfigAdditional>;
 
 void fillMbcBandConfig(std::vector<DynamicsProcessing::MbcBandConfig>& cfgs,
                        const TestParamsMbcBandConfig& params) {
@@ -936,8 +909,7 @@
       public DynamicsProcessingTestHelper {
   public:
     DynamicsProcessingTestMbcBandConfig()
-        : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())),
-          mStageInUse(std::get<MBC_BAND_STAGE_IN_USE>(GetParam())) {
+        : DynamicsProcessingTestHelper(std::get<MBC_BAND_INSTANCE_NAME>(GetParam())) {
         fillMbcBandConfig(mCfgs, GetParam());
     }
 
@@ -946,11 +918,9 @@
     void TearDown() override { TearDownDynamicsProcessingEffect(); }
 
     std::vector<DynamicsProcessing::MbcBandConfig> mCfgs;
-    const bool mStageInUse;
 };
 
 TEST_P(DynamicsProcessingTestMbcBandConfig, SetAndGetMbcBandConfig) {
-    mEngineConfigPreset.mbcStage.inUse = mStageInUse;
     mEngineConfigPreset.mbcStage.bandCount = mCfgs.size();
     EXPECT_NO_FATAL_FAILURE(addEngineConfig(mEngineConfigPreset));
     std::vector<DynamicsProcessing::ChannelConfig> cfgs(mChannelCount);
@@ -970,18 +940,15 @@
                            testing::Values(-1, 0, 10),  // channel count
                            testing::Bool(),             // enable
                            testing::ValuesIn(kBands),   // cut off frequencies
-                           testing::Bool(),             // stage in use
                            testing::ValuesIn(kMbcBandConfigAdditionalParam)),  // Additional
         [](const auto& info) {
             auto descriptor = std::get<MBC_BAND_INSTANCE_NAME>(info.param).second;
             std::vector<DynamicsProcessing::MbcBandConfig> cfgs;
             fillMbcBandConfig(cfgs, info.param);
             std::string mbcBands = ::android::internal::ToString(cfgs);
-            std::string stageInUse = std::to_string(std::get<MBC_BAND_STAGE_IN_USE>(info.param));
             std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
                                descriptor.common.name + "_UUID_" +
-                               toString(descriptor.common.id.uuid) + "_bands_" + mbcBands +
-                               "_stageInUse_" + stageInUse;
+                               toString(descriptor.common.id.uuid) + "_bands_" + mbcBands;
             std::replace_if(
                     name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
             return name;
diff --git a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
index 5930dcf..2c21d2e 100644
--- a/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalVolumeTargetTest.cpp
@@ -140,7 +140,9 @@
 class VolumeDataTest : public ::testing::TestWithParam<VolumeDataTestParam>,
                        public VolumeControlHelper {
   public:
-    VolumeDataTest() {
+    VolumeDataTest()
+        : kVsrApiLevel(
+                  android::base::GetIntProperty("ro.vendor.api_level", __ANDROID_API_FUTURE__)) {
         std::tie(mFactory, mDescriptor) = GetParam();
         mInput.resize(kBufferSize);
         mInputMag.resize(mTestFrequencies.size());
@@ -165,13 +167,17 @@
 
     void SetUp() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        // Skips test fixture if api_level <= 34 (__ANDROID_API_U__).
+        if (kVsrApiLevel <= __ANDROID_API_U__) GTEST_SKIP();
         ASSERT_NO_FATAL_FAILURE(SetUpVolumeControl());
     }
     void TearDown() override {
         SKIP_TEST_IF_DATA_UNSUPPORTED(mDescriptor.common.flags);
+        if (kVsrApiLevel <= __ANDROID_API_U__) GTEST_SKIP();
         TearDownVolumeControl();
     }
 
+    const int kVsrApiLevel;
     static constexpr int kMaxAudioSample = 1;
     static constexpr int kTransitionDuration = 300;
     static constexpr int kNPointFFT = 16384;
diff --git a/automotive/audiocontrol/aidl/Android.bp b/automotive/audiocontrol/aidl/Android.bp
index 4fc6aac..edb29c9 100644
--- a/automotive/audiocontrol/aidl/Android.bp
+++ b/automotive/audiocontrol/aidl/Android.bp
@@ -27,6 +27,9 @@
                 "com.android.car.framework",
             ],
         },
+        rust: {
+            enabled: true,
+        },
     },
     versions_with_info: [
         {
@@ -93,3 +96,17 @@
         latest_android_hardware_automotive_audiocontrol + "-ndk",
     ],
 }
+
+java_defaults {
+    name: "latest_android_hardware_automotive_audiocontrol_java_static",
+    static_libs: [
+        latest_android_hardware_automotive_audiocontrol + "-java",
+    ],
+}
+
+rust_defaults {
+    name: "latest_android_hardware_automotive_audiocontrol_rust",
+    rustlibs: [
+        latest_android_hardware_automotive_audiocontrol + "-rust",
+    ],
+}
diff --git a/automotive/audiocontrol/aidl/default/Android.bp b/automotive/audiocontrol/aidl/default/Android.bp
index a48d228..fd7e167 100644
--- a/automotive/audiocontrol/aidl/default/Android.bp
+++ b/automotive/audiocontrol/aidl/default/Android.bp
@@ -30,15 +30,14 @@
     defaults: [
         "latest_android_hardware_audio_common_ndk_shared",
         "latest_android_hardware_automotive_audiocontrol_ndk_shared",
+        "powerpolicyclient_defaults",
     ],
     shared_libs: [
         "android.hardware.audio.common@7.0-enums",
-        "android.frameworks.automotive.powerpolicy-V2-ndk",
         "libbase",
         "libbinder_ndk",
         "libcutils",
         "liblog",
-        "libpowerpolicyclient",
     ],
     srcs: [
         "AudioControl.cpp",
diff --git a/automotive/audiocontrol/aidl/rust_impl/Android.bp b/automotive/audiocontrol/aidl/rust_impl/Android.bp
new file mode 100644
index 0000000..062d989
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/Android.bp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+rust_binary {
+    name: "android.hardware.automotive.audiocontrol-V4-rust-service",
+    relative_install_path: "hw",
+    vendor: true,
+    srcs: ["src/*.rs"],
+    crate_root: "src/main.rs",
+    defaults: [
+        "latest_android_hardware_automotive_audiocontrol_rust",
+        "latest_android_hardware_audio_common_rust",
+    ],
+    vintf_fragments: ["audiocontrol-rust-service.xml"],
+    init_rc: ["audiocontrol-rust-service.rc"],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+}
diff --git a/automotive/audiocontrol/aidl/rust_impl/README.md b/automotive/audiocontrol/aidl/rust_impl/README.md
new file mode 100644
index 0000000..ed22356
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/README.md
@@ -0,0 +1,13 @@
+# Rust Skeleton Audio Control HAL implementation.
+
+WARNING: This is not a reference audio control HAl implementation and does
+not contain any actual implementation.
+
+This folder contains a skeleton audio control HAL implementation in Rust to
+demonstrate  how vendor may implement a Rust audio control HAL. To run this
+audio control HAL, include
+`android.hardware.automotive.audiocontrol-V4-rust-service` in your image.
+
+This implementation returns `StatusCode::UNKNOWN_ERROR` for all operations
+and does not pass VTS/CTS. Vendor must replace the logic in
+`default_audio_control_hal.rs` with the actual implementation.
diff --git a/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.rc b/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.rc
new file mode 100644
index 0000000..88d180d
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.rc
@@ -0,0 +1,4 @@
+service vendor.audiocontrol-default /vendor/bin/hw/android.hardware.automotive.audiocontrol-service.example
+    class hal
+    user audioserver
+    group system
diff --git a/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.xml b/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.xml
new file mode 100644
index 0000000..e54c1d3
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/audiocontrol-rust-service.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest version="2.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.automotive.audiocontrol</name>
+        <version>4</version>
+        <fqname>IAudioControl/default</fqname>
+    </hal>
+</manifest>
diff --git a/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs b/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
new file mode 100644
index 0000000..ba0ca23
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/src/default_audio_control_hal.rs
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+use android_hardware_automotive_audiocontrol::aidl::android::hardware::automotive::audiocontrol::{
+    AudioFocusChange::AudioFocusChange,
+    AudioGainConfigInfo::AudioGainConfigInfo,
+    DuckingInfo::DuckingInfo,
+    IAudioControl::IAudioControl,
+    IAudioGainCallback::IAudioGainCallback,
+    IFocusListener::IFocusListener,
+    IModuleChangeCallback::IModuleChangeCallback,
+    MutingInfo::MutingInfo,
+    Reasons::Reasons,
+};
+use android_hardware_audio_common::aidl::android::hardware::audio::common::PlaybackTrackMetadata::PlaybackTrackMetadata;
+use binder::{Interface, Result as BinderResult, StatusCode, Strong};
+
+/// This struct is defined to implement IAudioControl AIDL interface.
+pub struct DefaultAudioControlHal;
+
+impl Interface for DefaultAudioControlHal {}
+
+impl IAudioControl for DefaultAudioControlHal {
+    fn onAudioFocusChange(&self, _usage : &str, _zone_id : i32, _focus_change : AudioFocusChange
+        ) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn onDevicesToDuckChange(&self, _ducking_infos : &[DuckingInfo]) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn onDevicesToMuteChange(&self, _muting_infos : &[MutingInfo]) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn registerFocusListener(&self, _listener : &Strong<dyn IFocusListener>) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setBalanceTowardRight(&self, _value : f32) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setFadeTowardFront(&self, _value : f32) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn onAudioFocusChangeWithMetaData(&self, _playback_metadata : &PlaybackTrackMetadata,
+            _zone_id : i32, _focus_change : AudioFocusChange) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setAudioDeviceGainsChanged(&self, _reasons : &[Reasons], _gains : &[AudioGainConfigInfo]
+        ) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn registerGainCallback(&self, _callback : &Strong<dyn IAudioGainCallback>
+        ) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setModuleChangeCallback(&self, _callback : &Strong<dyn IModuleChangeCallback>
+        ) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn clearModuleChangeCallback(&self) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+}
diff --git a/automotive/audiocontrol/aidl/rust_impl/src/main.rs b/automotive/audiocontrol/aidl/rust_impl/src/main.rs
new file mode 100644
index 0000000..2ed4810
--- /dev/null
+++ b/automotive/audiocontrol/aidl/rust_impl/src/main.rs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+mod default_audio_control_hal;
+
+use android_hardware_automotive_audiocontrol::aidl::android::hardware::automotive::audiocontrol::IAudioControl::BnAudioControl;
+use crate::default_audio_control_hal::DefaultAudioControlHal;
+
+fn main() {
+    binder::ProcessState::start_thread_pool();
+    let my_service = DefaultAudioControlHal;
+    let service_name = "android.hardware.automotive.audiocontrol.IAudioControl/default";
+    let my_service_binder = BnAudioControl::new_binder(
+        my_service,
+        binder::BinderFeatures::default(),
+    );
+    binder::add_service(service_name, my_service_binder.as_binder())
+    		.expect(format!("Failed to register {}?", service_name).as_str());
+    // Does not return.
+    binder::ProcessState::join_thread_pool()
+}
diff --git a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
index a850d65..9d1610a 100644
--- a/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
+++ b/automotive/evs/aidl/impl/default/include/EvsVideoEmulatedCamera.h
@@ -93,6 +93,8 @@
 
     bool initialize();
 
+    bool initializeMediaCodec();
+
     void generateFrames();
 
     void renderOneFrame();
diff --git a/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml b/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
index 6cbc18e..af5b354 100644
--- a/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
+++ b/automotive/evs/aidl/impl/default/resources/evs_mock_configuration.xml
@@ -55,6 +55,30 @@
                 />
             </characteristics>
         </device>
+        <device id='/dev/video11' position='front'>
+            <caps>
+                <!-- list of supported controls -->
+                <supported_controls>
+                    <control name='BRIGHTNESS' min='0' max='255'/>
+                    <control name='CONTRAST' min='0' max='255'/>
+                </supported_controls>
+
+                <stream id='0' width='640'  height='360'  format='RGBA_8888' framerate='30'/>
+            </caps>
+
+            <!-- list of parameters -->
+            <characteristics>
+                <!-- Camera intrinsic calibration matrix. See
+                     https://developer.android.com/reference/android/hardware/camera2/CameraCharacteristics.html#LENS_INTRINSIC_CALIBRATION
+                -->
+                <parameter
+                    name='LENS_INTRINSIC_CALIBRATION'
+                    type='float'
+                    size='5'
+                    value='0.0,0.0,0.0,0.0,0.0'
+                />
+            </characteristics>
+        </device>
     </camera>
     <display>
         <device id='display0' position='driver'>
diff --git a/automotive/evs/aidl/impl/default/src/EvsCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
index bc3bfdd..005c71f 100644
--- a/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsCamera.cpp
@@ -198,9 +198,14 @@
     auto status = ndk::ScopedAStatus::ok();
     {
         std::unique_lock lck(mMutex);
+        if (mStreamState != StreamState::RUNNING) {
+            // We're already in the middle of the procedure to stop current data
+            // stream.
+            return status;
+        }
+
         if ((!preVideoStreamStop_locked(status, lck) || !stopVideoStreamImpl_locked(status, lck) ||
-             !postVideoStreamStop_locked(status, lck)) &&
-            !status.isOk()) {
+             !postVideoStreamStop_locked(status, lck)) && !status.isOk()) {
             needShutdown = true;
         }
     }
diff --git a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
index e3f7b5e..480c28d 100644
--- a/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
+++ b/automotive/evs/aidl/impl/default/src/EvsVideoEmulatedCamera.cpp
@@ -81,6 +81,10 @@
         }
     }
 
+    return initializeMediaCodec();
+}
+
+bool EvsVideoEmulatedCamera::initializeMediaCodec() {
     // Initialize Media Codec and file format.
     std::unique_ptr<AMediaFormat, FormatDeleter> format;
     const char* mime;
@@ -304,6 +308,13 @@
         LOG(ERROR) << __func__
                    << ": Received error in releasing output buffer. Error code: " << release_status;
     }
+
+    if ((info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) != 0) {
+        LOG(INFO) << "Start video playback from the beginning.";
+        AMediaExtractor_seekTo(mVideoExtractor.get(), /* seekPosUs= */ 0,
+                               AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC);
+        AMediaCodec_flush(mVideoCodec.get());
+    }
 }
 
 void EvsVideoEmulatedCamera::initializeParameters() {
@@ -337,11 +348,24 @@
         std::unique_lock<std::mutex>& /* lck */) {
     mStream = receiver;
 
-    const media_status_t status = AMediaCodec_start(mVideoCodec.get());
-    if (status != AMEDIA_OK) {
-        LOG(ERROR) << __func__ << ": Received error in starting decoder. Error code: " << status
-                   << ".";
-        return false;
+    if (auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
+        LOG(INFO) << __func__ << ": Received error in starting decoder. "
+                     << "Trying again after resetting this emulated device.";
+
+        if (!initializeMediaCodec()) {
+            LOG(ERROR) << __func__ << ": Failed to re-configure the media codec.";
+            return false;
+        }
+
+        AMediaExtractor_seekTo(mVideoExtractor.get(), /* seekPosUs= */ 0,
+                               AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC);
+        AMediaCodec_flush(mVideoCodec.get());
+
+        if(auto status = AMediaCodec_start(mVideoCodec.get()); status != AMEDIA_OK) {
+            LOG(ERROR) << __func__ << ": Received error again in starting decoder. "
+                       << "Error code: " << status;
+            return false;
+        }
     }
     mCaptureThread = std::thread([this]() { generateFrames(); });
 
@@ -364,6 +388,12 @@
     if (!Base::postVideoStreamStop_locked(status, lck)) {
         return false;
     }
+
+    EvsEventDesc event = { .aType = EvsEventType::STREAM_STOPPED, };
+    if (auto result = mStream->notify(event); !result.isOk()) {
+        LOG(WARNING) << "Failed to notify the end of the stream.";
+    }
+
     mStream = nullptr;
     return true;
 }
diff --git a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
index 5d33fcb..515dc98 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/src/TestWakeupClientServiceImpl.cpp
@@ -169,7 +169,8 @@
     Looper::setForThread(mLooper);
 
     while (true) {
-        mLooper->pollAll(/*timeoutMillis=*/-1);
+        // Don't use pollAll since it might swallow wake.
+        mLooper->pollOnce(/*timeoutMillis=*/-1);
         if (mServerStopped) {
             return;
         }
diff --git a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
index 4bc0086..a7927f5 100644
--- a/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
+++ b/automotive/remoteaccess/test_grpc_server/impl/test/TestWakeupClientServiceImplUnitTest.cpp
@@ -41,7 +41,6 @@
 constexpr int32_t kTestCount = 1234;
 constexpr int64_t kTestStartTimeInEpochSeconds = 2345;
 constexpr int64_t kTestPeriodicInSeconds = 123;
-const std::string kTestGrpcAddr = "localhost:50051";
 
 class MyTestWakeupClientServiceImpl final : public ServiceImpl {
   public:
@@ -53,27 +52,41 @@
 class TestWakeupClientServiceImplUnitTest : public ::testing::Test {
   public:
     virtual void SetUp() override {
-        mServerThread = std::thread([this] {
+        int selectedPort = 0;
+        mServerStarted = false;
+        mService.reset();
+        mServer.reset();
+        mServerThread = std::thread([this, &selectedPort] {
             mService = std::make_unique<MyTestWakeupClientServiceImpl>();
             ServerBuilder builder;
-            builder.AddListeningPort(kTestGrpcAddr, grpc::InsecureServerCredentials());
+            builder.AddListeningPort("localhost:0", grpc::InsecureServerCredentials(),
+                                     &selectedPort);
             WakeupClientServiceImpl wakeupClientService(mService.get());
             builder.RegisterService(&wakeupClientService);
             mServer = builder.BuildAndStart();
+            mServerStarted = true;
             {
                 std::unique_lock<std::mutex> lock(mLock);
                 mServerStartCv.notify_one();
             }
-            mServer->Wait();
+            if (mServer != nullptr) {
+                mServer->Wait();
+            }
         });
         {
             std::unique_lock<std::mutex> lock(mLock);
-            mServerStartCv.wait(lock, [this] {
+            bool serverStarted = mServerStartCv.wait_for(lock, std::chrono::seconds(10), [this] {
                 ScopedLockAssertion lockAssertion(mLock);
-                return mServer != nullptr;
+                return mServerStarted.load();
             });
+            ASSERT_TRUE(serverStarted) << "Failed to wait for mServerStarted to be set within 10s";
         }
-        mChannel = grpc::CreateChannel(kTestGrpcAddr, grpc::InsecureChannelCredentials());
+        if (mServer == nullptr) {
+            GTEST_SKIP() << "Failed to start the test grpc server";
+        }
+        std::string address = "localhost:" + std::to_string(selectedPort);
+        std::cout << "Test grpc server started at: " << address << std::endl;
+        mChannel = grpc::CreateChannel(address, grpc::InsecureChannelCredentials());
         mStub = WakeupClient::NewStub(mChannel);
     }
 
@@ -147,6 +160,7 @@
     std::thread mServerThread;
     std::unique_ptr<MyTestWakeupClientServiceImpl> mService;
     std::unique_ptr<Server> mServer;
+    std::atomic<bool> mServerStarted = false;
     std::shared_ptr<Channel> mChannel;
     std::unique_ptr<WakeupClient::Stub> mStub;
     std::vector<GetRemoteTasksResponse> mRemoteTaskResponses;
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 4846bfb..f021f7b 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -449,7 +449,8 @@
         {.config = {.prop = toInt(VehicleProperty::HVAC_MAX_DEFROST_ON),
                     .access = VehiclePropertyAccess::READ_WRITE,
                     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
+                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_FRONT_ROW},
+                                    VehicleAreaConfig{.areaId = HVAC_REAR_ROW}}},
          .initialValue = {.int32Values = {0}}},
 
         {.config = {.prop = toInt(VehicleProperty::HVAC_RECIRC_ON),
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h
index f58e09a..e866f70 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/PropertyUtils.h
@@ -50,6 +50,9 @@
           VehicleAreaWheel::LEFT_REAR | VehicleAreaWheel::RIGHT_REAR);
 constexpr int SEAT_1_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT);
 constexpr int SEAT_1_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT);
+constexpr int HVAC_FRONT_ROW = (int)(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_1_RIGHT);
+constexpr int HVAC_REAR_ROW = (int)(VehicleAreaSeat::ROW_2_LEFT | VehicleAreaSeat::ROW_2_CENTER |
+                                    VehicleAreaSeat::ROW_2_RIGHT);
 constexpr int HVAC_LEFT = (int)(VehicleAreaSeat::ROW_1_LEFT | VehicleAreaSeat::ROW_2_LEFT |
                                 VehicleAreaSeat::ROW_2_CENTER);
 constexpr int HVAC_RIGHT = (int)(VehicleAreaSeat::ROW_1_RIGHT | VehicleAreaSeat::ROW_2_RIGHT);
diff --git a/automotive/vehicle/aidl/aidl_test/Android.bp b/automotive/vehicle/aidl/aidl_test/Android.bp
index 2dc9ee1..f517df8 100644
--- a/automotive/vehicle/aidl/aidl_test/Android.bp
+++ b/automotive/vehicle/aidl/aidl_test/Android.bp
@@ -40,7 +40,7 @@
 cc_test {
     name: "VehiclePropertyAnnotationCppTest",
     srcs: ["VehiclePropertyAnnotationCppTest.cpp"],
-    header_libs: ["IVehicleGeneratedHeaders"],
+    header_libs: ["IVehicleGeneratedHeaders-V3"],
     defaults: ["VehicleHalInterfaceDefaults"],
     test_suites: ["general-tests"],
 }
@@ -49,7 +49,7 @@
     name: "VehiclePropertyAnnotationJavaTest",
     srcs: [
         "VehiclePropertyAnnotationJavaTest.java",
-        ":IVehicleGeneratedJavaFiles",
+        ":IVehicleGeneratedJavaFiles-V3",
     ],
     static_libs: [
         "android.hardware.automotive.vehicle-V3-java",
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
index 726d419..9387965 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleAreaConfig.aidl
@@ -62,7 +62,9 @@
      * For example, if a property is defined as READ_WRITE, but the OEM wants to specify certain
      * area Ids as READ-only, the corresponding areaIds should have an access set to READ, while the
      * others must be set to READ_WRITE. We do not support setting specific area Ids to WRITE-only
-     * when the property is READ-WRITE.
+     * when the property is READ-WRITE. If any one area config has access
+     * VehiclePropertyAccess::WRITE, then all VehicleAreaConfig.access values and
+     * VehiclePropConfig.access must be set to WRITE for the property.
      *
      * VehiclePropConfig.access should be equal the maximal subset of the accesses set in
      * VehiclePropConfig.areaConfigs, excluding those with access == VehiclePropertyAccess.NONE. For
@@ -73,6 +75,8 @@
      * In the scenario where the OEM actually wants to set VehicleAreaConfig.access =
      * VehiclePropertyAccess.NONE, the maximal subset rule should apply with this area config
      * included, making the VehiclePropConfig.access = VehiclePropertyAccess.NONE.
+     *
+     * See VehiclePropConfig.access for more information.
      */
     VehiclePropertyAccess access = VehiclePropertyAccess.NONE;
 
diff --git a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
index 3109621..d8304f6 100644
--- a/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
+++ b/automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehiclePropConfig.aidl
@@ -44,6 +44,36 @@
      * VehiclePropertyAccess.NONE for a particular area config, the maximal subset rule should apply
      * with this area config included, making the VehiclePropConfig.access =
      * VehiclePropertyAccess.NONE.
+     *
+     * Currently we do not support scenarios where some areaIds are WRITE while others are
+     * READ_WRITE. See the documentation for VehicleAreaConfig.access for more details.
+     *
+     * Examples:
+     *   Suppose we have a property with two areaIds which we will call "LEFT" and "RIGHT". Here
+     *   are some scenarios that can describe what the VehiclePropConfig.access value should be for
+     *   this property.
+     *   1. LEFT is READ and RIGHT is READ_WRITE. VehiclePropConfig.access must be READ as that is
+     *      the maximal common access across all areaIds.
+     *   2. LEFT is READ_WRITE and RIGHT is READ_WRITE. VehiclePropConfig.access must be READ_WRITE
+     *      as that is the maximal common access across all areaIds.
+     *   3. LEFT is WRITE and RIGHT is WRITE. VehiclePropConfig.access must be WRITE as that is the
+     *      maximal common access across all areaIds.
+     *   4. LEFT is READ_WRITE and RIGHT is not set (i.e. defaults to NONE)/is set to NONE, with the
+     *      expectation that RIGHT should be populated with the default access mode of the property.
+     *      VehiclePropConfig.access can be set to READ or READ_WRITE, whatever the OEM feels is the
+     *      appropriate default access for the property.
+     *   5. LEFT is READ and RIGHT is not set (i.e. defaults to NONE)/is set to NONE, with the
+     *      expectation that RIGHT should be populated with the default access mode of the property.
+     *      VehiclePropConfig.access must be set to READ because setting to READ_WRITE breaks the
+     *      rule of having the global access being the maximal subset of the area config accesses.
+     *      If the OEM wants RIGHT to be READ_WRITE in this scenario, the config should be rewritten
+     *      such that LEFT is not set/is set to NONE and RIGHT is set to READ_WRITE with
+     *      VehiclePropConfig.access set to READ.
+     *   6. LEFT is READ_WRITE and RIGHT is set to NONE with the intention of RIGHT to specifically
+     *      have no access. VehiclePropConfig.access must be NONE to support RIGHT maintaining its
+     *      NONE access.
+     *   7. LEFT is READ_WRITE and RIGHT is WRITE. This is unsupported behaviour and the config
+     *      should not be defined this way.
      */
     VehiclePropertyAccess access = VehiclePropertyAccess.NONE;
 
diff --git a/automotive/vehicle/aidl/emu_metadata/.clang-format b/automotive/vehicle/aidl/emu_metadata/.clang-format
new file mode 100644
index 0000000..e384528
--- /dev/null
+++ b/automotive/vehicle/aidl/emu_metadata/.clang-format
@@ -0,0 +1 @@
+DisableFormat: true
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 c812326..de0e398 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
@@ -5,23 +5,28 @@
         "values": [
             {
                 "name": "VIN of vehicle",
-                "value": 286261504
+                "value": 286261504,
+                "description": "VIN of vehicle"
             },
             {
                 "name": "Manufacturer of vehicle",
-                "value": 286261505
+                "value": 286261505,
+                "description": "Manufacturer of vehicle\nThis property must communicate the vehicle's public brand name."
             },
             {
                 "name": "Model of vehicle",
-                "value": 286261506
+                "value": 286261506,
+                "description": "Model of vehicle\nThis property must communicate the vehicle's public model name."
             },
             {
                 "name": "INFO_MODEL_YEAR",
-                "value": 289407235
+                "value": 289407235,
+                "description": "Model year of vehicle in YYYY format based on the Gregorian calendar."
             },
             {
                 "name": "INFO_FUEL_CAPACITY",
-                "value": 291504388
+                "value": 291504388,
+                "description": "Fuel capacity of the vehicle in milliliters\nThis property must communicate the maximum amount of the fuel that can be stored in the vehicle in milliliters. This property does not apply to electric vehicles. That is, if INFO_FUEL_TYPE only contains FuelType::FUEL_TYPE_ELECTRIC, this property must not be implemented. For EVs, implement INFO_EV_BATTERY_CAPACITY."
             },
             {
                 "name": "INFO_FUEL_TYPE",
@@ -29,11 +34,13 @@
                 "data_enums": [
                     "FuelType"
                 ],
-                "data_enum": "FuelType"
+                "data_enum": "FuelType",
+                "description": "List of fuels the vehicle may use.\nFuelType::FUEL_TYPE_ELECTRIC must only be included if the vehicle is plug in rechargeable. For example: An FHEV (Fully Hybrid Electric Vehicle) must not include FuelType::FUEL_TYPE_ELECTRIC in INFO_FUEL_TYPE's INT32_VEC value. So INFO_FUEL_TYPE can be populated as such: int32Values = { FuelType::FUEL_TYPE_UNLEADED } On the other hand, a PHEV (Plug-in Hybrid Electric Vehicle) is plug in rechargeable, and hence should include FuelType::FUEL_TYPE_ELECTRIC in INFO_FUEL_TYPE's INT32_VEC value. So INFO_FUEL_TYPE can be populated as such: int32Values = { FuelType::FUEL_TYPE_UNLEADED, FuelType::FUEL_TYPE_ELECTRIC }"
             },
             {
                 "name": "INFO_EV_BATTERY_CAPACITY",
-                "value": 291504390
+                "value": 291504390,
+                "description": "Nominal usable battery capacity for EV or hybrid vehicle\nReturns the nominal battery capacity, if EV or hybrid. This is the total usable battery capacity when the vehicle is new. This value might be different from EV_CURRENT_BATTERY_CAPACITY because EV_CURRENT_BATTERY_CAPACITY returns the real-time usable battery capacity taking into account factors such as battery aging and temperature dependency."
             },
             {
                 "name": "INFO_EV_CONNECTOR_TYPE",
@@ -41,7 +48,8 @@
                 "data_enums": [
                     "EvConnectorType"
                 ],
-                "data_enum": "EvConnectorType"
+                "data_enum": "EvConnectorType",
+                "description": "List of connectors this EV may use\nIf the vehicle has multiple charging ports, this property must return all possible connector types that can be used by at least one charging port on the vehicle."
             },
             {
                 "name": "Fuel door location",
@@ -49,7 +57,8 @@
                 "data_enums": [
                     "PortLocationType"
                 ],
-                "data_enum": "PortLocationType"
+                "data_enum": "PortLocationType",
+                "description": "Fuel door location\nThis property must communicate the location of the fuel door on the vehicle. This property does not apply to electric vehicles. That is, if INFO_FUEL_TYPE only contains FuelType::FUEL_TYPE_ELECTRIC, this property must not be implemented. For EVs, implement INFO_EV_PORT_LOCATION or INFO_MULTI_EV_PORT_LOCATIONS."
             },
             {
                 "name": "EV port location",
@@ -57,7 +66,8 @@
                 "data_enums": [
                     "PortLocationType"
                 ],
-                "data_enum": "PortLocationType"
+                "data_enum": "PortLocationType",
+                "description": "EV port location\nThis property must communicate the location of the charging port on the EV using the PortLocationType enum. If there are multiple ports available on the vehicle, this property must return the port that allows the fastest charging. To communicate all port locations, use INFO_MULTI_EV_PORT_LOCATIONS."
             },
             {
                 "name": "INFO_DRIVER_SEAT",
@@ -65,11 +75,13 @@
                 "data_enums": [
                     "VehicleAreaSeat"
                 ],
-                "data_enum": "VehicleAreaSeat"
+                "data_enum": "VehicleAreaSeat",
+                "description": "Driver's seat location VHAL implementations must ignore the areaId. Use VehicleArea:GLOBAL."
             },
             {
                 "name": "INFO_EXTERIOR_DIMENSIONS",
-                "value": 289472779
+                "value": 289472779,
+                "description": "Exterior dimensions of vehicle.\nint32Values[0] = height int32Values[1] = length int32Values[2] = width int32Values[3] = width including mirrors int32Values[4] = wheel base int32Values[5] = track width front int32Values[6] = track width rear int32Values[7] = curb to curb turning diameter"
             },
             {
                 "name": "Multiple EV port locations",
@@ -77,31 +89,38 @@
                 "data_enums": [
                     "PortLocationType"
                 ],
-                "data_enum": "PortLocationType"
+                "data_enum": "PortLocationType",
+                "description": "Multiple EV port locations\nImplement this property if the vehicle has multiple EV ports. Port locations are defined in PortLocationType. For example, a car has one port in front left and one port in rear left: int32Values[0] = PortLocationType::FRONT_LEFT int32Values[1] = PortLocationType::REAR_LEFT\nIf only one port exists on the vehicle, this property's value should list just one element. See INFO_EV_PORT_LOCATION for describing just one port location."
             },
             {
                 "name": "PERF_ODOMETER",
-                "value": 291504644
+                "value": 291504644,
+                "description": "Current odometer value of the vehicle"
             },
             {
                 "name": "Speed of the vehicle",
-                "value": 291504647
+                "value": 291504647,
+                "description": "Speed of the vehicle\nThe value must be positive when the vehicle is moving forward and negative when the vehicle is moving backward. This value is independent of gear value (CURRENT_GEAR or GEAR_SELECTION), for example, if GEAR_SELECTION is GEAR_NEUTRAL, PERF_VEHICLE_SPEED is positive when the vehicle is moving forward, negative when moving backward, and zero when not moving."
             },
             {
                 "name": "PERF_VEHICLE_SPEED_DISPLAY",
-                "value": 291504648
+                "value": 291504648,
+                "description": "Speed of the vehicle for displays\nSome cars display a slightly slower speed than the actual speed.  This is usually displayed on the speedometer."
             },
             {
                 "name": "PERF_STEERING_ANGLE",
-                "value": 291504649
+                "value": 291504649,
+                "description": "Front bicycle model steering angle for vehicle\nAngle is in degrees.  Left is negative.\nThis property is independent of the angle of the steering wheel. This property must communicate the angle of the front wheels with respect to the vehicle, not the angle of the steering wheel."
             },
             {
                 "name": "PERF_REAR_STEERING_ANGLE",
-                "value": 291504656
+                "value": 291504656,
+                "description": "Rear bicycle model steering angle for vehicle\nAngle is in degrees.  Left is negative.\nThis property is independent of the angle of the steering wheel. This property must communicate the angle of the rear wheels with respect to the vehicle, not the angle of the steering wheel."
             },
             {
                 "name": "Temperature of engine coolant",
-                "value": 291504897
+                "value": 291504897,
+                "description": "Temperature of engine coolant"
             },
             {
                 "name": "Engine oil level",
@@ -109,67 +128,83 @@
                 "data_enums": [
                     "VehicleOilLevel"
                 ],
-                "data_enum": "VehicleOilLevel"
+                "data_enum": "VehicleOilLevel",
+                "description": "Engine oil level"
             },
             {
                 "name": "Temperature of engine oil",
-                "value": 291504900
+                "value": 291504900,
+                "description": "Temperature of engine oil"
             },
             {
                 "name": "Engine rpm",
-                "value": 291504901
+                "value": 291504901,
+                "description": "Engine rpm"
             },
             {
                 "name": "Reports wheel ticks",
-                "value": 290521862
+                "value": 290521862,
+                "description": "Reports wheel ticks\nThe first element in the vector is a reset count.  A reset indicates previous tick counts are not comparable with this and future ones.  Some sort of discontinuity in tick counting has occurred.\nThe next four elements represent ticks for individual wheels in the following order: front left, front right, rear right, rear left.  All tick counts are cumulative.  Tick counts increment when the vehicle moves forward, and decrement when vehicles moves in reverse.  The ticks should be reset to 0 when the vehicle is started by the user.\nint64Values[0] = reset count int64Values[1] = front left ticks int64Values[2] = front right ticks int64Values[3] = rear right ticks int64Values[4] = rear left ticks\nconfigArray is used to indicate the micrometers-per-wheel-tick value and which wheels are supported.  configArray is set as follows:\nconfigArray[0], bits [0:3] = supported wheels. Uses enum Wheel. For example, if all wheels are supported, then configArray[0] = VehicleAreaWheel::LEFT_FRONT | VehicleAreaWheel::RIGHT_FRONT | VehicleAreaWheel::LEFT_REAR | VehicleAreaWheel::RIGHT_REAR configArray[1] = micrometers per front left wheel tick configArray[2] = micrometers per front right wheel tick configArray[3] = micrometers per rear right wheel tick configArray[4] = micrometers per rear left wheel tick\nNOTE:  If a wheel is not supported, its value shall always be set to 0.\nVehiclePropValue.timestamp must be correctly filled in."
             },
             {
-                "name": "FUEL_LEVEL",
-                "value": 291504903
+                "name": "Fuel level in milliliters",
+                "value": 291504903,
+                "description": "Fuel level in milliliters\nThis property must communicate the current amount of fuel remaining in the vehicle in milliliters. This property does not apply to electric vehicles. That is, if INFO_FUEL_TYPE only contains FuelType::FUEL_TYPE_ELECTRIC, this property must not be implemented. For EVs, implement EV_BATTERY_LEVEL.\nValue may not exceed INFO_FUEL_CAPACITY."
             },
             {
                 "name": "Fuel door open",
-                "value": 287310600
+                "value": 287310600,
+                "description": "Fuel door open\nThis property must communicate whether the fuel door on the vehicle is open or not. This property does not apply to electric vehicles. That is, if INFO_FUEL_TYPE only contains FuelType::FUEL_TYPE_ELECTRIC, this property must not be implemented. For EVs, implement EV_CHARGE_PORT_OPEN.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EV_BATTERY_LEVEL",
-                "value": 291504905
+                "value": 291504905,
+                "description": "Battery level for EV or hybrid vehicle\nReturns the current battery level, if EV or hybrid. This value will not exceed EV_CURRENT_BATTERY_CAPACITY. To calculate the battery percentage, use: (EV_BATTERY_LEVEL\/EV_CURRENT_BATTERY_CAPACITY)*100."
             },
             {
                 "name": "EV_CURRENT_BATTERY_CAPACITY",
-                "value": 291504909
+                "value": 291504909,
+                "description": "Current usable battery capacity for EV or hybrid vehicle\nReturns the actual value of battery capacity, if EV or hybrid. This property captures the real-time usable battery capacity taking into account factors such as battery aging and temperature dependency. Therefore, this value might be different from INFO_EV_BATTERY_CAPACITY because INFO_EV_BATTERY_CAPACITY returns the nominal battery capacity from when the vehicle was new."
             },
             {
                 "name": "EV charge port open",
-                "value": 287310602
+                "value": 287310602,
+                "description": "EV charge port open\nIf the vehicle has multiple charging ports, this property must return true if any of the charge ports are open.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EV charge port connected",
-                "value": 287310603
+                "value": 287310603,
+                "description": "EV charge port connected\nIf the vehicle has multiple charging ports, this property must return true if any of the charge ports are connected."
             },
             {
                 "name": "EV_BATTERY_INSTANTANEOUS_CHARGE_RATE",
-                "value": 291504908
+                "value": 291504908,
+                "description": "EV instantaneous charge rate in milliwatts\nPositive value indicates battery is being charged. Negative value indicates battery being discharged."
             },
             {
                 "name": "Range remaining",
-                "value": 291504904
+                "value": 291504904,
+                "description": "Range remaining\nMeters remaining of fuel and charge.  Range remaining shall account for all energy sources in a vehicle.  For example, a hybrid car's range will be the sum of the ranges based on fuel and battery.\nThis property is defined as VehiclePropertyAccess.READ_WRITE because a navigation app could update the range if it has a more accurate estimate based on the upcoming route. However, this property can be implemented as VehiclePropertyAccess.READ only at the OEM's discretion."
             },
             {
                 "name": "EV battery average temperature",
-                "value": 291504910
+                "value": 291504910,
+                "description": "EV battery average temperature\nExposes the temperature of the battery in an EV. If multiple batteries exist in the EV, or multiple temperature sensors exist, this property should be set to the mean or a meaningful weighted average that best represents the overall temperature of the battery system."
             },
             {
                 "name": "Tire pressure",
-                "value": 392168201
+                "value": 392168201,
+                "description": "Tire pressure\nEach tires is identified by its areaConfig.areaId config and their minFloatValue\/maxFloatValue are used to store OEM recommended pressure range. The minFloatValue and maxFloatValue in VehicleAreaConfig must be defined. The minFloatValue in the areaConfig data represents the lower bound of the recommended tire pressure. The maxFloatValue in the areaConfig data represents the upper bound of the recommended tire pressure. For example: The following areaConfig indicates the recommended tire pressure of left_front tire is from 200.0 KILOPASCAL to 240.0 KILOPASCAL. .areaConfigs = { VehicleAreaConfig { .areaId = VehicleAreaWheel::LEFT_FRONT, .minFloatValue = 200.0, .maxFloatValue = 240.0, } },"
             },
             {
                 "name": "Critically low tire pressure",
-                "value": 392168202
+                "value": 392168202,
+                "description": "Critically low tire pressure\nThis property indicates the critically low pressure threshold for each tire. It indicates when it is time for tires to be replaced or fixed. The value must be less than or equal to minFloatValue in TIRE_PRESSURE. Minimum and maximum property values (that is, minFloatValue, maxFloatValue) are not applicable to this property."
             },
             {
                 "name": "ENGINE_IDLE_AUTO_STOP_ENABLED",
-                "value": 287310624
+                "value": 287310624,
+                "description": "Represents feature for engine idle automatic stop.\nIf true, the vehicle may automatically shut off the engine when it is not needed and then automatically restart it when needed.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Impact detected.",
@@ -177,7 +212,8 @@
                 "data_enums": [
                     "ImpactSensorLocation"
                 ],
-                "data_enum": "ImpactSensorLocation"
+                "data_enum": "ImpactSensorLocation",
+                "description": "Impact detected.\nBit flag property to relay information on whether an impact has occurred on a particular side of the vehicle as described through the ImpactSensorLocation enum. As a bit flag property, this property can be set to multiple ORed together values of the enum when necessary.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all bit flags of ImpactSensorLocation are supported."
             },
             {
                 "name": "Currently selected gear",
@@ -185,7 +221,8 @@
                 "data_enums": [
                     "VehicleGear"
                 ],
-                "data_enum": "VehicleGear"
+                "data_enum": "VehicleGear",
+                "description": "Currently selected gear\nThis is the gear selected by the user.\nValues in the config data must represent the list of supported gears for this vehicle. For example, config data for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_DRIVE, GEAR_1, GEAR_2,...} and for manual transmission the list must be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}\nIn the case of an automatic transmission vehicle that allows the driver to select specific gears on demand (i.e. \"manual mode\"), GEAR_SELECTION's value must be set to the specific gear selected by the driver instead of simply GEAR_DRIVE."
             },
             {
                 "name": "CURRENT_GEAR",
@@ -193,27 +230,33 @@
                 "data_enums": [
                     "VehicleGear"
                 ],
-                "data_enum": "VehicleGear"
+                "data_enum": "VehicleGear",
+                "description": "Current gear. In non-manual case, selected gear may not match the current gear. For example, if the selected gear is GEAR_DRIVE, the current gear will be one of GEAR_1, GEAR_2 etc, which reflects the actual gear the transmission is currently running in.\nValues in the config data must represent the list of supported gears for this vehicle.  For example, config data for an automatic transmission must contain {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_PARK, GEAR_1, GEAR_2,...} and for manual transmission the list must be {GEAR_NEUTRAL, GEAR_REVERSE, GEAR_1, GEAR_2,...}. This list need not be the same as that of the supported gears reported in GEAR_SELECTION."
             },
             {
                 "name": "Parking brake state.",
-                "value": 287310850
+                "value": 287310850,
+                "description": "Parking brake state.\nThis property is true indicates that the car's parking brake is currently engaged. False implies that the car's parking brake is currently disengaged."
             },
             {
                 "name": "Auto-apply parking brake.",
-                "value": 287310851
+                "value": 287310851,
+                "description": "Auto-apply parking brake.\nThis property is true indicates that the car's automatic parking brake feature is currently enabled. False indicates that the car's automatic parking brake feature is currently disabled.\nThis property is often confused with PARKING_BRAKE_ON. The difference is that PARKING_BRAKE_ON describes whether the actual parking brake is currently on\/off, whereas PARKING_BRAKE_AUTO_APPLY describes whether the feature of automatic parking brake is enabled\/ disabled, and does not describe the current state of the actual parking brake."
             },
             {
                 "name": "EV_BRAKE_REGENERATION_LEVEL",
-                "value": 289408012
+                "value": 289408012,
+                "description": "Regenerative braking level of a electronic vehicle\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between minInt32Value and maxInt32Value must be supported. The minInt32Value must be 0.\nThe maxInt32Value indicates the setting for the maximum amount of energy regenerated from braking. The minInt32Value indicates the setting for no regenerative braking.\nThis property is a more granular form of EV_REGENERATIVE_BRAKING_STATE. It allows the user to set a more specific level of regenerative braking if the states in EvRegenerativeBrakingState are not granular enough for the OEM.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Warning for fuel low level.",
-                "value": 287310853
+                "value": 287310853,
+                "description": "Warning for fuel low level.\nThis property corresponds to the low fuel warning on the dashboard. Once FUEL_LEVEL_LOW is set, it should not be cleared until more fuel is added to the vehicle.  This property may take into account all fuel sources for a vehicle - for example:\nFor a gas powered vehicle, this property is based soley on gas level. For a battery powered vehicle, this property is based solely on battery level. For a hybrid vehicle, this property may be based on the combination of gas and battery levels, at the OEM's discretion."
             },
             {
                 "name": "Night mode",
-                "value": 287310855
+                "value": 287310855,
+                "description": "Night mode\nTrue indicates that the night mode sensor has detected that the car cabin environment has low light. The platform could use this, for example, to enable appropriate UI for better viewing in dark or low light environments."
             },
             {
                 "name": "TURN_SIGNAL_STATE",
@@ -221,7 +264,8 @@
                 "data_enums": [
                     "VehicleTurnSignal"
                 ],
-                "data_enum": "VehicleTurnSignal"
+                "data_enum": "VehicleTurnSignal",
+                "description": "State of the vehicles turn signals"
             },
             {
                 "name": "Represents ignition state",
@@ -229,15 +273,18 @@
                 "data_enums": [
                     "VehicleIgnitionState"
                 ],
-                "data_enum": "VehicleIgnitionState"
+                "data_enum": "VehicleIgnitionState",
+                "description": "Represents ignition state"
             },
             {
                 "name": "ABS is active",
-                "value": 287310858
+                "value": 287310858,
+                "description": "ABS is active\nSet to true when ABS is active.  Reset to false when ABS is off.  This property may be intermittently set (pulsing) based on the real-time state of the ABS system."
             },
             {
                 "name": "Traction Control is active",
-                "value": 287310859
+                "value": 287310859,
+                "description": "Traction Control is active\nSet to true when traction control (TC) is active.  Reset to false when TC is off.  This property may be intermittently set (pulsing) based on the real-time state of the TC system."
             },
             {
                 "name": "EV_STOPPING_MODE",
@@ -245,11 +292,13 @@
                 "data_enums": [
                     "EvStoppingMode"
                 ],
-                "data_enum": "EvStoppingMode"
+                "data_enum": "EvStoppingMode",
+                "description": "Represents property for the current stopping mode of the vehicle.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless all enum values of EvStoppingMode are supported.\nThe EvStoppingMode enum may be extended to include more states in the future.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "ELECTRONIC_STABILITY_CONTROL_ENABLED",
-                "value": 287310862
+                "value": 287310862,
+                "description": "Enable or disable Electronic Stability Control (ESC).\nSet true to enable ESC and false to disable ESC. When ESC is enabled, a system in the vehicle should be controlling the tires during instances with high risk of skidding to actively prevent the same from happening.\nIn general, ELECTRONIC_STABILITY_CONTROL_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too high, that information must be conveyed through the ErrorState values in the ELECTRONIC_STABILITY_CONTROL_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "ELECTRONIC_STABILITY_CONTROL_STATE",
@@ -258,11 +307,13 @@
                     "ElectronicStabilityControlState",
                     "ErrorState"
                 ],
-                "data_enum": "ElectronicStabilityControlState"
+                "data_enum": "ElectronicStabilityControlState",
+                "description": "Electronic Stability Control (ESC) state.\nReturns the current state of ESC. This property must always return a valid state defined in ElectronicStabilityControlState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both ElectronicStabilityControlState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "Fan speed setting",
-                "value": 356517120
+                "value": 356517120,
+                "description": "Fan speed setting\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the lowest fan speed. The maxInt32Value indicates the highest fan speed.\nThis property is not in any particular unit but in a specified range of relative speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Fan direction setting",
@@ -270,55 +321,68 @@
                 "data_enums": [
                     "VehicleHvacFanDirection"
                 ],
-                "data_enum": "VehicleHvacFanDirection"
+                "data_enum": "VehicleHvacFanDirection",
+                "description": "Fan direction setting\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "HVAC current temperature.",
-                "value": 358614274
+                "value": 358614274,
+                "description": "HVAC current temperature."
             },
             {
-                "name": "HVAC, target temperature set.",
-                "value": 358614275
+                "name": "HVAC_TEMPERATURE_SET",
+                "value": 358614275,
+                "description": "HVAC target temperature set in Celsius.\nThe minFloatValue and maxFloatValue in VehicleAreaConfig must be defined.\nThe minFloatValue indicates the minimum temperature setting in Celsius. The maxFloatValue indicates the maximum temperature setting in Celsius.\nIf all the values between minFloatValue and maxFloatValue are not supported, the configArray can be used to list the valid temperature values that can be set. It also describes a lookup table to convert the temperature from Celsius to Fahrenheit and vice versa for this vehicle. The configArray must be defined if standard unit conversion is not supported on this vehicle.\nThe configArray is set as follows: configArray[0] = [the lower bound of the supported temperature in Celsius] * 10. configArray[1] = [the upper bound of the supported temperature in Celsius] * 10. configArray[2] = [the increment in Celsius] * 10. configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10. configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10. configArray[5] = [the increment in Fahrenheit] * 10.\nThe minFloatValue and maxFloatValue in VehicleAreaConfig must be equal to configArray[0] and configArray[1] respectively.\nFor example, if the vehicle supports temperature values as: [16.0, 16.5, 17.0 ,..., 28.0] in Celsius [60.5, 61.5, 62.5 ,..., 84.5] in Fahrenheit The configArray should be configArray = {160, 280, 5, 605, 845, 10}.\nIdeally, the ratio of the Celsius increment to the Fahrenheit increment should be as close to the actual ratio of 1 degree Celsius to 1.8 degrees Fahrenheit.\nThere must be a one to one mapping of all Celsius values to Fahrenheit values defined by the configArray. The configArray will be used by clients to convert this property's temperature from Celsius to Fahrenheit. Also, it will let clients know what Celsius value to set the property to achieve their desired Fahreneheit value for the system. If the ECU does not have a one to one mapping of all Celsius values to Fahrenheit values, then the config array should only define the list of Celsius and Fahrenheit values that do have a one to one mapping.\nFor example, if the ECU supports Celsius values from 16 to 28 and Fahrenheit values from 60 to 85 both with an increment of 1, then one possible configArray would be {160, 280, 10, 600, 840, 20}. In this case, 85 would not be a supported temperature.\nAny value set in between a valid value should be rounded to the closest valid value.\nIt is highly recommended that the OEM also implement the HVAC_TEMPERATURE_VALUE_SUGGESTION vehicle property because it provides applications a simple method for determining temperature values that can be set for this vehicle and for converting values between Celsius and Fahrenheit.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "HVAC_DEFROSTER",
-                "value": 320865540
+                "value": 320865540,
+                "description": "Fan-based defrost for designated window.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "HVAC_AC_ON",
-                "value": 354419973
+                "value": 354419973,
+                "description": "On\/off AC for designated areaId\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "On\/off max AC",
-                "value": 354419974
+                "value": 354419974,
+                "description": "On\/off max AC\nWhen MAX AC is on, the ECU may adjust the vent position, fan speed, temperature, etc as necessary to cool the vehicle as quickly as possible. Any parameters modified as a side effect of turning on\/off the MAX AC parameter shall generate onPropertyEvent() callbacks to the VHAL.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "On\/off max defrost",
-                "value": 354419975
+                "value": 354419975,
+                "description": "On\/off max defrost\nWhen MAX DEFROST is on, the ECU may adjust the vent position, fan speed, temperature, etc as necessary to defrost the windows as quickly as possible.  Any parameters modified as a side effect of turning on\/off the MAX DEFROST parameter shall generate onPropertyEvent() callbacks to the VHAL. The AreaIDs for HVAC_MAX_DEFROST_ON indicate MAX DEFROST can be controlled in the area. For example: areaConfig.areaId = {ROW_1_LEFT | ROW_1_RIGHT} indicates HVAC_MAX_DEFROST_ON only can be controlled for the front rows.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Recirculation on\/off",
-                "value": 354419976
+                "value": 354419976,
+                "description": "Recirculation on\/off\nControls the supply of exterior air to the cabin.  Recirc “on” means the majority of the airflow into the cabin is originating in the cabin. Recirc “off” means the majority of the airflow into the cabin is coming from outside the car.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "HVAC_DUAL_ON",
-                "value": 354419977
+                "value": 354419977,
+                "description": "Enable temperature coupling between areas.\nThe AreaIDs for HVAC_DUAL_ON property shall contain a combination of HVAC_TEMPERATURE_SET AreaIDs that can be coupled together. If HVAC_TEMPERATURE_SET is mapped to AreaIDs [a_1, a_2, ..., a_n], and if HVAC_DUAL_ON can be enabled to couple a_i and a_j, then HVAC_DUAL_ON property must be mapped to [a_i | a_j]. Further, if a_k and a_l can also be coupled together separately then HVAC_DUAL_ON must be mapped to [a_i | a_j, a_k | a_l].\nExample: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). There are two temperature control units -- driver side and passenger side -- which can be optionally synchronized. This may be expressed in the AreaIDs this way: - HVAC_TEMPERATURE_SET->[ROW_1_LEFT | ROW_2_LEFT, ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT] - HVAC_DUAL_ON->[ROW_1_LEFT | ROW_2_LEFT | ROW_1_RIGHT | ROW_2_CENTER | ROW_2_RIGHT]\nWhen the property is enabled, the ECU must synchronize the temperature for the affected areas. Any parameters modified as a side effect of turning on\/off the DUAL_ON parameter shall generate onPropertyEvent() callbacks to the VHAL. In addition, if setting a temperature (i.e. driver's temperature) changes another temperature (i.e. front passenger's temperature), then the appropriate onPropertyEvent() callbacks must be generated.  If a user changes a temperature that breaks the coupling (e.g. setting the passenger temperature independently) then the VHAL must send the appropriate onPropertyEvent() callbacks (i.e. HVAC_DUAL_ON = false, HVAC_TEMPERATURE_SET[AreaID] = xxx, etc).\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "HVAC_AUTO_ON",
-                "value": 354419978
+                "value": 354419978,
+                "description": "On\/off automatic climate control.\nIf true, automatic climate control is on. If false, automatic climate control is off.\nIf the vehicle does not support directly turning off automatic climate control, then OEMs should add logic in their VHAL implementation so that setting HVAC_AUTO_ON to false would change the necessary HVAC settings to indirectly turn off HVAC_AUTO_ON. Ideally, this should not be disruptive to the user, so OEMs should change back to the previous state any settings that were modified once automatic climate control is off. That way the only outcome should be that HVAC_AUTO_ON is off. If restoring the HVAC settings to its previous settings is not possible, then the OEM should choose the least disruptive change and implement that.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat heating\/cooling",
-                "value": 356517131
+                "value": 356517131,
+                "description": "Seat heating\/cooling\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the maximum seat temperature heating setting. The minInt32Value must be 0, unless the vehicle supports seat cooling as well. In this case, minInt32Value indicates the maximum seat temperature cooling setting.\nThis property is not in any particular unit, but in a specified range of relative temperature settings.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Side Mirror Heat",
-                "value": 339739916
+                "value": 339739916,
+                "description": "Side Mirror Heat\nIncreasing values denote higher heating levels for side mirrors.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value in the config data represents the maximum heating level. The minInt32Value in the config data MUST be zero and indicates no heating.\nThis property is not in any particular unit but in a specified range of relative heating settings.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Steering Wheel Heating\/Cooling",
-                "value": 289408269
+                "value": 289408269,
+                "description": "Steering Wheel Heating\/Cooling\nSets the amount of heating\/cooling for the steering wheel.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the maximum steering wheel heating setting. The minInt32Value should be 0, unless the vehicle supports steering wheel cooling as well. In such a case, the minInt32Value indicates the maximum steering wheel cooling setting.\nThis property is not in any particular unit but in a specified range of heating settings.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Temperature units for display",
@@ -326,15 +390,18 @@
                 "data_enums": [
                     "VehicleUnit"
                 ],
-                "data_enum": "VehicleUnit"
+                "data_enum": "VehicleUnit",
+                "description": "Temperature units for display\nIndicates whether the vehicle is displaying temperature to the user as Celsius or Fahrenheit. VehiclePropConfig.configArray is used to indicate the supported temperature display units. For example: configArray[0] = CELSIUS configArray[1] = FAHRENHEIT\nThis parameter MAY be used for displaying any HVAC temperature in the system. Values must be one of VehicleUnit.CELSIUS or VehicleUnit.FAHRENHEIT Note that internally, all temperatures are represented in floating point Celsius.\nIf updating HVAC_TEMPERATURE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties, then their values must be updated and communicated to the AAOS framework as well.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Actual fan speed",
-                "value": 356517135
+                "value": 356517135,
+                "description": "Actual fan speed"
             },
             {
                 "name": "HVAC_POWER_ON",
-                "value": 354419984
+                "value": 354419984,
+                "description": "Represents global power state for HVAC. Setting this property to false MAY mark some properties that control individual HVAC features\/subsystems to UNAVAILABLE state. Setting this property to true MAY mark some properties that control individual HVAC features\/subsystems to AVAILABLE state (unless any\/all of them are UNAVAILABLE on their own individual merits).\n[Definition] HvacPower_DependentProperties: Properties that need HVAC to be powered on in order to enable their functionality. For example, in some cars, in order to turn on the AC, HVAC must be powered on first.\nHvacPower_DependentProperties list must be set in the VehiclePropConfig.configArray. HvacPower_DependentProperties must only contain properties that are associated with VehicleArea:SEAT. Properties that are not associated with VehicleArea:SEAT, for example, HVAC_DEFROSTER, must never depend on HVAC_POWER_ON property and must never be part of HvacPower_DependentProperties list.\nAreaID mapping for HVAC_POWER_ON property must contain all AreaIDs that HvacPower_DependentProperties are mapped to.\nExample 1: A car has two front seats (ROW_1_LEFT, ROW_1_RIGHT) and three back seats (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT). If the HVAC features (AC, Temperature etc.) throughout the car are dependent on a single HVAC power controller then HVAC_POWER_ON must be mapped to [ROW_1_LEFT | ROW_1_RIGHT | ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT].\nExample 2: A car has two seats in the front row (ROW_1_LEFT, ROW_1_RIGHT) and three seats in the second (ROW_2_LEFT, ROW_2_CENTER, ROW_2_RIGHT) and third rows (ROW_3_LEFT, ROW_3_CENTER, ROW_3_RIGHT). If the car has temperature controllers in the front row which can operate entirely independently of temperature controllers in the back of the vehicle, then HVAC_POWER_ON must be mapped to a two element array: - ROW_1_LEFT | ROW_1_RIGHT - ROW_2_LEFT | ROW_2_CENTER | ROW_2_RIGHT | ROW_3_LEFT | ROW_3_CENTER | ROW_3_RIGHT\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Fan Positions Available",
@@ -342,23 +409,28 @@
                 "data_enums": [
                     "VehicleHvacFanDirection"
                 ],
-                "data_enum": "VehicleHvacFanDirection"
+                "data_enum": "VehicleHvacFanDirection",
+                "description": "Fan Positions Available\nThis is a bit mask of fan positions available for the zone.  Each available fan direction is denoted by a separate entry in the vector.  A fan direction may have multiple bits from vehicle_hvac_fan_direction set. For instance, a typical car may have the following fan positions: - FAN_DIRECTION_FACE (0x1) - FAN_DIRECTION_FLOOR (0x2) - FAN_DIRECTION_FACE | FAN_DIRECTION_FLOOR (0x3) - FAN_DIRECTION_DEFROST (0x4) - FAN_DIRECTION_FLOOR | FAN_DIRECTION_DEFROST (0x6)"
             },
             {
                 "name": "Automatic recirculation on\/off",
-                "value": 354419986
+                "value": 354419986,
+                "description": "Automatic recirculation on\/off\nWhen automatic recirculation is ON, the HVAC system may automatically switch to recirculation mode if the vehicle detects poor incoming air quality.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat ventilation",
-                "value": 356517139
+                "value": 356517139,
+                "description": "Seat ventilation\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value must be 0. The maxInt32Value indicates the maximum ventilation setting available for the seat.\nThis property is not in any particular unit but in the specified range of ventilation settings.\nUsed by HVAC apps and Assistant to enable, change, or read state of seat ventilation.  This is different than seating cooling. It can be on at the same time as cooling, or not.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Electric defrosters' status",
-                "value": 320865556
+                "value": 320865556,
+                "description": "Electric defrosters' status\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "HVAC_TEMPERATURE_VALUE_SUGGESTION",
-                "value": 291570965
+                "value": 291570965,
+                "description": "Suggested values for setting HVAC temperature.\nImplement the property to help applications understand the closest supported temperature value in Celsius or Fahrenheit.\nfloatValues[0] = the requested value that an application wants to set a temperature to. floatValues[1] = the unit for floatValues[0]. It should be one of {VehicleUnit.CELSIUS, VehicleUnit.FAHRENHEIT}. floatValues[2] = the value OEMs suggested in CELSIUS. This value is not included in the request. floatValues[3] = the value OEMs suggested in FAHRENHEIT. This value is not included in the request.\nAn application calls set(VehiclePropValue propValue) with the requested value and unit for the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by onPropertyEvent() callbacks. The suggested values must conform to the values that can be derived from the HVAC_TEMPERATURE_SET configArray. In other words, the suggested values and the table of values from the configArray should be the same. It is recommended for the OEM to add custom logic in their VHAL implementation in order to avoid making requests to the HVAC ECU.\nThe logic can be as follows: For converting the temperature from celsius to fahrenheit use the following: \/\/ Given tempC and the configArray float minTempC = configArray[0] \/ 10.0; float temperatureIncrementCelsius = configArray[2] \/ 10.0; float minTempF = configArray[3] \/ 10.0; float temperatureIncrementFahrenheit = configArray[5] \/ 10.0; \/\/ Round to the closest increment int numIncrements = round((tempC - minTempC) \/ temperatureIncrementCelsius); tempF = temperatureIncrementFahrenheit * numIncrements + minTempF;\nFor example, when a user uses the voice assistant to set HVAC temperature to 66.2 in Fahrenheit. First, an application will set this property with the value [66.2, (float)VehicleUnit.FAHRENHEIT,0,0]. If OEMs suggest to set 19.0 in Celsius or 66.5 in Fahrenheit for user's request, then VHAL must generate a callback with property value [66.2, (float)VehicleUnit.FAHRENHEIT, 19.0, 66.5]. After the voice assistant gets the callback, it will inform the user and set HVAC temperature to the suggested value.\nAnother example, an application receives 21 Celsius as the current temperature value by querying HVC_TEMPERATURE_SET. But the application wants to know what value is displayed on the car's UI in Fahrenheit. For this, the application sets the property to [21, (float)VehicleUnit.CELSIUS, 0, 0]. If the suggested value by the OEM for 21 Celsius is 70 Fahrenheit, then VHAL must generate a callback with property value [21, (float)VehicleUnit.CELSIUS, 21.0, 70.0]. In this case, the application can know that the value is 70.0 Fahrenheit in the car’s UI."
             },
             {
                 "name": "Distance units for display",
@@ -366,7 +438,8 @@
                 "data_enums": [
                     "VehicleUnit"
                 ],
-                "data_enum": "VehicleUnit"
+                "data_enum": "VehicleUnit",
+                "description": "Distance units for display\nIndicates which units the car is using to display distances to the user. Eg. Mile, Meter Kilometer.\nDistance units are defined in VehicleUnit. VehiclePropConfig.configArray is used to indicate the supported distance display units. For example: configArray[0] = METER configArray[1] = KILOMETER configArray[2] = MILE\nIf updating DISTANCE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties, then their values must be updated and communicated to the AAOS framework as well.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Fuel volume units for display",
@@ -374,7 +447,8 @@
                 "data_enums": [
                     "VehicleUnit"
                 ],
-                "data_enum": "VehicleUnit"
+                "data_enum": "VehicleUnit",
+                "description": "Fuel volume units for display\nIndicates which units the car is using to display fuel volume to the user. Eg. Liter or Gallon.\nVehiclePropConfig.configArray is used to indicate the supported fuel volume display units. Volume units are defined in VehicleUnit. For example: configArray[0] = LITER configArray[1] = GALLON\nIf updating FUEL_VOLUME_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties, then their values must be updated and communicated to the AAOS framework as well.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "TIRE_PRESSURE_DISPLAY_UNITS",
@@ -382,7 +456,8 @@
                 "data_enums": [
                     "VehicleUnit"
                 ],
-                "data_enum": "VehicleUnit"
+                "data_enum": "VehicleUnit",
+                "description": "Tire pressure units for display\nIndicates which units the car is using to display tire pressure to the user. Eg. PSI, Bar or Kilopascal.\nVehiclePropConfig.configArray is used to indicate the supported pressure display units. Pressure units are defined in VehicleUnit. For example: configArray[0] = KILOPASCAL configArray[1] = PSI configArray[2] = BAR\nIf updating TIRE_PRESSURE_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties, then their values must be updated and communicated to the AAOS framework as well.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EV battery units for display",
@@ -390,71 +465,88 @@
                 "data_enums": [
                     "VehicleUnit"
                 ],
-                "data_enum": "VehicleUnit"
+                "data_enum": "VehicleUnit",
+                "description": "EV battery units for display\nIndicates which units the car is using to display EV battery information to the user. Eg. watt-hours(Wh), kilowatt-hours(kWh) or ampere-hours(Ah).\nVehiclePropConfig.configArray is used to indicate the supported electrical energy units. Electrical energy units are defined in VehicleUnit. For example: configArray[0] = WATT_HOUR configArray[1] = AMPERE_HOURS configArray[2] = KILOWATT_HOUR\nIf updating EV_BATTERY_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties, then their values must be updated and communicated to the AAOS framework as well.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME",
-                "value": 287311364
+                "value": 287311364,
+                "description": "Fuel consumption units for display\nIndicates type of units the car is using to display fuel consumption information to user True indicates units are distance over volume such as MPG. False indicates units are volume over distance such as L\/100KM.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Speed units for display",
-                "value": 289408517
+                "value": 289408517,
+                "description": "Speed units for display\nIndicates type of units the car is using to display speed to user. Eg. m\/s, km\/h, or mph.\nVehiclePropConfig.configArray is used to indicate the supported speed display units. Pressure units are defined in VehicleUnit. For example: configArray[0] = METER_PER_SEC configArray[1] = MILES_PER_HOUR configArray[2] = KILOMETERS_PER_HOUR\nIf updating VEHICLE_SPEED_DISPLAY_UNITS affects the values of other *_DISPLAY_UNITS properties, then their values must be updated and communicated to the AAOS framework as well.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EXTERNAL_CAR_TIME",
-                "value": 290457096
+                "value": 290457096,
+                "description": "Current date and time suggestion for the Car, encoded as Epoch time (in milliseconds). This value denotes the number of milliseconds seconds that have elapsed since 1\/1\/1970 UTC.\nThis property signals a change in CarTime to Android. If the property is supported, VHAL must report the most accurate current CarTime when this property is read, and publish a change to this property when the CarTime value has changed. An on-change event for this property must be published when CarTime changes for any reason other than the natural elapse of time (time delta smaller than 500ms should not trigger an on change event). Android will read and subscribe to this property to fetch time from VHAL. This can be useful to synchronize Android's time with other vehicle systems (dash clock etc). int64Values[0] = provided Epoch time (in milliseconds)\nWhenever a new Value for the property is received, AAOS will create and send an \"ExternalTimeSuggestion\" to the \"TimeDetectorService\". If other sources do not have a higher priority, Android will use this to set the system time. For information on how to adjust time source priorities and how time suggestions are handled (including how Android handles gitter, drift, and minimum resolution) see Time Detector Service documentation.\nNote that the property may take >0 ms to get propagated through the stack and, having a timestamped property helps reduce any time drift. So, for all reads to the property, the timestamp can be used to negate this drift: drift = elapsedTime - PropValue.timestamp effectiveTime = PropValue.value.int64Values[0] + drift\nIt is strongly recommended that this property must not be used to retrieve time from ECUs using protocols (GNSS, NTP, Telephony etc). Since these protocols are already supported by Android, it is recommended to use Android’s own systems for them instead of wiring those through the VHAL using this property.\nWARNING: The value available through this property should not be dependent on value written by Android to ANDROID_EPOCH_TIME property in any way."
             },
             {
                 "name": "ANDROID_EPOCH_TIME",
-                "value": 290457094
+                "value": 290457094,
+                "description": "Current date and time, encoded as Epoch time (in milliseconds). This value denotes the number of milliseconds seconds that have elapsed since 1\/1\/1970 UTC.\nCarServices will write to this value to give VHAL the Android system's time, if the VHAL supports this property. This can be useful to synchronize other vehicle systems (dash clock etc) with Android's time.\nAAOS writes to this property once during boot, and will thereafter write only when some time-source changes are propagated. AAOS will fill in VehiclePropValue.timestamp correctly. Note that AAOS will not send updates for natural elapse of time. int64Values[0] = provided Unix time (in milliseconds)\nNote that the property may take >0 ms to get propagated through the stack and, having a timestamped property helps reduce any time drift. So, for all writes to the property, the timestamp can be used to negate this drift: drift = elapsedTime - PropValue.timestamp effectiveTime = PropValue.value.int64Values[0] + drift"
             },
             {
                 "name": "STORAGE_ENCRYPTION_BINDING_SEED",
-                "value": 292554247
+                "value": 292554247,
+                "description": "External encryption binding seed.\nThis value is mixed with the local key storage encryption key. This property holds 16 bytes, and is expected to be persisted on an ECU separate from the IVI. The property is initially set by AAOS, who generates it using a CSRNG. AAOS will then read the property on subsequent boots. The binding seed is expected to be reliably persisted. Any loss of the seed results in a factory reset of the IVI."
             },
             {
                 "name": "Outside temperature",
-                "value": 291505923
+                "value": 291505923,
+                "description": "Outside temperature\nThis property must communicate the temperature reading of the environment outside the vehicle. If there are multiple sensors for measuring the outside temperature, this property should be populated with the mean or a meaningful weighted average of the readings that will best represent the temperature of the outside environment."
             },
             {
                 "name": "AP_POWER_STATE_REQ",
-                "value": 289475072
+                "value": 289475072,
+                "description": "Property to control power state of application processor\nIt is assumed that AP's power state is controlled by a separate power controller.\nFor configuration information, VehiclePropConfig.configArray must have bit flag combining values in VehicleApPowerStateConfigFlag.\nint32Values[0] : VehicleApPowerStateReq enum value int32Values[1] : additional parameter relevant for each state, 0 if not used."
             },
             {
                 "name": "AP_POWER_STATE_REPORT",
-                "value": 289475073
+                "value": 289475073,
+                "description": "Property to report power state of application processor\nIt is assumed that AP's power state is controller by separate power controller.\nint32Values[0] : VehicleApPowerStateReport enum value int32Values[1] : Time in ms to wake up, if necessary.  Otherwise 0."
             },
             {
                 "name": "AP_POWER_BOOTUP_REASON",
-                "value": 289409538
+                "value": 289409538,
+                "description": "Property to report bootup reason for the current power on. This is a static property that will not change for the whole duration until power off. For example, even if user presses power on button after automatic power on with door unlock, bootup reason must stay with VehicleApPowerBootupReason#USER_UNLOCK.\nint32Values[0] must be VehicleApPowerBootupReason."
             },
             {
                 "name": "DISPLAY_BRIGHTNESS",
-                "value": 289409539
+                "value": 289409539,
+                "description": "Property to represent brightness of the display.\nSome cars have single control for the brightness of all displays and this property is to share change in that control. In cars which have displays whose brightness is controlled separately, they must use PER_DISPLAY_BRIGHTNESS.\nOnly one of DISPLAY_BRIGHTNESS and PER_DISPLAY_BRIGHTNESS should be implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by AAOS.\nIf this is writable, android side can set this value when user changes display brightness from Settings. If this is read only, user may still change display brightness from Settings, but that must not be reflected to other displays.\nIf this is writable, writing this property must cause an on property change event even if the new display brightness is the same as the current value."
             },
             {
                 "name": "PER_DISPLAY_BRIGHTNESS",
-                "value": 289475076
+                "value": 289475076,
+                "description": "Property to represent brightness of the displays which are controlled separately.\nSome cars have one or more displays whose brightness is controlled separately and this property is to inform the brightness of each passenger display. In cars where all displays' brightness is controlled together, they must use DISPLAY_BRIGHTNESS.\nOnly one of DISPLAY_BRIGHTNESS and PER_DISPLAY_BRIGHTNESS should be implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by AAOS.\nIf this is supported, PER_DISPLAY_MAX_BRIGHTNESS must be supported to represent the max display brightness for each display. Otherwise, the max display brightness is by default 1. The VehicleAreaConfig.maxInt32Value must not be used to represent max display brightness, because maxInt32Value is defined to be the max value for all the elements inside the integer value, which includes display port and brightness. So it is not meaningful.\nThe display port uniquely identifies a physical connector on the device for display output, ranging from 0 to 255.\nWriting this property must cause an on property change event that contains the same [display port, brightness] tuple even if the new display brightness is the same as the current value.\nTo get the display brightness for a specific display port, the GetValueRequest must contain a VehiclePropValue, which contains one int32Value: displayPort. Getting this property without specifying the the display port is undefined behavior.\nint32Values[0] : display port int32Values[1] : brightness"
             },
             {
                 "name": "Valet mode enabled",
-                "value": 287312389
+                "value": 287312389,
+                "description": "Valet mode enabled\nThis property allows the user to enable\/disable valet mode in their vehicle. Valet mode is a privacy and security setting that prevents an untrusted driver to access more private areas in the vehicle, such as the glove box or the trunk(s).\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Head up display (HUD) enabled",
-                "value": 354421254
+                "value": 354421254,
+                "description": "Head up display (HUD) enabled\nThis property allows the user to turn on\/off the HUD for their seat.\nEach HUD in the vehicle should be assigned to the seat that is intended to use it. For example, if there is a single HUD in the vehicle that is used by the driver so that they no longer need to continuously look at the instrument cluster, then this property should be defined with a single area ID equal to the driver's seat area value."
             },
             {
                 "name": "HW_KEY_INPUT",
-                "value": 289475088
+                "value": 289475088,
+                "description": "Property to feed H\/W input events to android\nint32Values[0] : action defined by VehicleHwKeyInputAction int32Values[1] : key code, must use standard android key code int32Values[2] : target display defined in VehicleDisplay. Events not tied to specific display must be sent to VehicleDisplay#MAIN. int32Values[3] : [optional] Number of ticks. The value must be equal or greater than 1. When omitted, Android will default to 1."
             },
             {
                 "name": "HW_KEY_INPUT_V2",
-                "value": 367004177
+                "value": 367004177,
+                "description": "Property to feed H\/W input events to android\nint32array[0]: target display defined by VehicleDisplay like VehicleDisplay::MAIN, VehicleDisplay::INSTRUMENT_CLUSTER, VehicleDisplay::AUX int32array[1]: key code, must use standard android key code like KEYCODE_HOME, KEYCODE_BACK int32array[2]: action defined in VehicleHwKeyInputAction like VehicleHwKeyInputAction::ACTION_UP, VehicleHwKeyInputAction::ACTION_UP int32array[3]: repeat count of the event. For key down events, this is the repeat count with the first down starting at 0 and counting up from there. For key up events, this is always equal to 0\nint64array[0]: down time, elapsed nanoseconds since boot. Denotes the time of the most recent key down event. For the down event, it will be the event time of the down event itself"
             },
             {
                 "name": "HW_MOTION_INPUT",
-                "value": 367004178
+                "value": 367004178,
+                "description": "Property to feed H\/W input events to android\nint32array[0]: target display defined by VehicleDisplay like VehicleDisplay::MAIN, VehicleDisplay::INSTRUMENT_CLUSTER, VehicleDisplay::AUX int32array[1]: input type defined in VehicleHwMotionInputSource like VehicleHwMotionInputSource::SOURCE_KEYBOARD, VehicleHwMotionInputSource::SOURCE_DPAD int32array[2]: action code defined in VehicleHwMotionInputAction like VehicleHwMotionInputAction::ACTION_UP, VehicleHwMotionInputAction::ACTION_DOWN int32array[3]: button state flag defined in VehicleHwMotionButtonStateFlag like VehicleHwMotionButtonStateFlag::BUTTON_PRIMARY, VehicleHwMotionButtonStateFlag::BUTTON_SECONDARY int32array[4]: pointer events count, N. N must be a positive integer int32array[5:5+N-1]: pointer id, length N int32array[5+N:5+2*N-1] : tool type, length N. As defined in VehicleHwMotionToolType like VehicleHwMotionToolType::TOOL_TYPE_FINGER, VehicleHwMotionToolType::TOOL_TYPE_STYLUS\nfloatArray[0:N-1] : x data, length N floatArray[N:2*N-1] : y data, length N floatArray[2*N:3*N-1] : pressure data, length N floatArray[3*N:4*N-1] : size data, length N\nint64array[0]: down time, elapsed nanoseconds since boot. Denotes the time when the user originally pressed down to start a stream of position events. For the down event, it will be the event time of the down event itself"
             },
             {
                 "name": "HW_ROTARY_INPUT",
@@ -462,7 +554,8 @@
                 "data_enums": [
                     "RotaryInputType"
                 ],
-                "data_enum": "RotaryInputType"
+                "data_enum": "RotaryInputType",
+                "description": "Property to feed H\/W rotary events to android\nint32Values[0] : RotaryInputType identifying which rotary knob rotated int32Values[1] : number of detents (clicks), positive for clockwise, negative for counterclockwise int32Values[2] : target display defined in VehicleDisplay. Events not tied to specific display must be sent to VehicleDisplay#MAIN. int32values[3 .. 3 + abs(number of detents) - 2]: nanosecond deltas between pairs of consecutive detents, if the number of detents is > 1 or < -1\nVehiclePropValue.timestamp: when the rotation occurred. If the number of detents is > 1 or < -1, this is when the first detent of rotation occurred."
             },
             {
                 "name": "HW_CUSTOM_INPUT",
@@ -470,167 +563,208 @@
                 "data_enums": [
                     "CustomInputType"
                 ],
-                "data_enum": "CustomInputType"
+                "data_enum": "CustomInputType",
+                "description": "Defines a custom OEM partner input event.\nThis input event must be used by OEM partners who wish to propagate events not supported by Android. It is composed by an array of int32 values only.\nThe Android properties are:\nint32Values[0] : Input code identifying the function representing this event. Valid event types are defined by CustomInputType.CUSTOM_EVENT_F1 up to CustomInputType.CUSTOM_EVENT_F10. They represent the custom event to be defined by OEM partners. int32Values[1] : target display type defined in VehicleDisplay. Events not tied to specific display must be sent to VehicleDisplay#MAIN. int32Values[2] : repeat counter, if 0 then event is not repeated. Values 1 or above means how many times this event repeated."
             },
             {
                 "name": "Door position",
-                "value": 373295872
+                "value": 373295872,
+                "description": "Door position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the door is closed. The minInt32Value must be 0. The maxInt32Value indicates the door is fully open.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the closed and fully open positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nSome vehicles (minivans) can open the door electronically. Hence, the ability to write this property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Door move",
-                "value": 373295873
+                "value": 373295873,
+                "description": "Door move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the door while opening. The minInt32Value represents the maximum movement speed of the door while closing.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the door reaches the positional limit, the value must reset to 0. If DOOR_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Door lock",
-                "value": 371198722
+                "value": 371198722,
+                "description": "Door lock\n'true' indicates door is locked\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "DOOR_CHILD_LOCK_ENABLED",
-                "value": 371198723
+                "value": 371198723,
+                "description": "Door child lock feature enabled\nReturns true if the door child lock feature is enabled and false if it is disabled.\nIf enabled, the door is unable to be opened from the inside.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Mirror Z Position",
-                "value": 339741504
+                "value": 339741504,
+                "description": "Mirror Z Position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the mirror is tilted completely downwards. This must be a non-positive value. The maxInt32Value indicates the mirror is tilted completely upwards. This must be a non-negative value. 0 indicates the mirror is not tilted in either direction.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the fully downward and fully upwards positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Mirror Z Move",
-                "value": 339741505
+                "value": 339741505,
+                "description": "Mirror Z Move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the mirror while tilting upwards. The minInt32Value represents the maximum movement speed of the mirror while tilting downwards.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the mirror reaches the positional limit, the value must reset to 0. If MIRROR_Z_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Mirror Y Position",
-                "value": 339741506
+                "value": 339741506,
+                "description": "Mirror Y Position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the mirror is tilted completely to the left. This must be a non-positive value. The maxInt32Value indicates the mirror is tilted completely to the right. This must be a non-negative value. 0 indicates the mirror is not tilted in either direction.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the left extreme and right extreme positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Mirror Y Move",
-                "value": 339741507
+                "value": 339741507,
+                "description": "Mirror Y Move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the mirror while tilting right. The minInt32Value represents the maximum movement speed of the mirror while tilting left.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the mirror reaches the positional limit, the value must reset to 0. If MIRROR_Y_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Mirror Lock",
-                "value": 287312708
+                "value": 287312708,
+                "description": "Mirror Lock\nTrue indicates mirror positions are locked and not changeable\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Mirror Fold",
-                "value": 287312709
+                "value": 287312709,
+                "description": "Mirror Fold\nTrue indicates mirrors are folded\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "MIRROR_AUTO_FOLD_ENABLED",
-                "value": 337644358
+                "value": 337644358,
+                "description": "Represents property for Mirror Auto Fold feature.\nThis property is true when the feature for automatically folding the vehicle's side mirrors (for example, when the mirrors fold inward automatically when one exits and locks the vehicle) is enabled.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "MIRROR_AUTO_TILT_ENABLED",
-                "value": 337644359
+                "value": 337644359,
+                "description": "Represents property for Mirror Auto Tilt feature.\nThis property is true when the feature for automatically tilting the vehicle's side mirrors (for example, when the mirrors tilt downward automatically when one reverses the vehicle) is enabled.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat memory select",
-                "value": 356518784
+                "value": 356518784,
+                "description": "Seat memory select\nThis parameter selects the memory preset to use to select the seat position. The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported. The minInt32Value is always 0, and the maxInt32Value determines the number of seat preset memory slots available (i.e. numSeatPresets - 1).\nFor instance, if the driver's seat has 3 memory presets, the maxInt32Value will be 2. When the user wants to select a preset, the desired preset number (0, 1, or 2) is set."
             },
             {
                 "name": "Seat memory set",
-                "value": 356518785
+                "value": 356518785,
+                "description": "Seat memory set\nThis setting allows the user to save the current seat position settings into the selected preset slot. The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. The minInt32Value must be 0, and the maxInt32Value for each seat position must match the maxInt32Value for SEAT_MEMORY_SELECT."
             },
             {
                 "name": "Seatbelt buckled",
-                "value": 354421634
+                "value": 354421634,
+                "description": "Seatbelt buckled\nTrue indicates belt is buckled.\nWrite access indicates automatic seat buckling capabilities.  There are no known cars at this time, but you never know...\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seatbelt height position",
-                "value": 356518787
+                "value": 356518787,
+                "description": "Seatbelt height position\nAdjusts the shoulder belt anchor point.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the seat belt's shoulder anchor is at its lowest position. The maxInt32Value indicates the seat belt's shoulder anchor is at its highest position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the lowest and highest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seatbelt height move",
-                "value": 356518788
+                "value": 356518788,
+                "description": "Seatbelt height move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat belt's shoulder anchor while moving upwards. The minInt32Value represents the maximum movement speed of the seat belt's shoulder anchor while moving downwards.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat belt reaches the positional limit, the value must reset to 0. If SEAT_BELT_HEIGHT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat fore\/aft position",
-                "value": 356518789
+                "value": 356518789,
+                "description": "Seat fore\/aft position\nSets the seat position forward and backwards.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the seat is at its rearward-most linear position. The maxInt32Value indicates the seat is at its forward-most linear position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the closest and farthest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat fore\/aft move",
-                "value": 356518790
+                "value": 356518790,
+                "description": "Seat fore\/aft move\nThis property moves the entire seat forward\/backward in the direction that it is facing.\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat while moving forward. The minInt32Value represents the maximum movement speed of the seat while moving backward.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat reaches the positional limit, the value must reset to 0. If SEAT_FORE_AFT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat backrest angle 1 position",
-                "value": 356518791
+                "value": 356518791,
+                "description": "Seat backrest angle 1 position\nBackrest angle 1 is the actuator closest to the bottom of the seat.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the seat backrest's full recline position w.r.t the actuator at the bottom of the seat. The maxInt32Value indicates the seat backrest's most upright\/forward position w.r.t the actuator at the bottom of the seat.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the full recline and upright\/forward positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat backrest angle 1 move",
-                "value": 356518792
+                "value": 356518792,
+                "description": "Seat backrest angle 1 move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat backrest while angling forward. The minInt32Value represents the maximum movement speed of the seat backrest while reclining.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat backrest reaches the positional limit, the value must reset to 0. If SEAT_BACKREST_ANGLE_1_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat backrest angle 2 position",
-                "value": 356518793
+                "value": 356518793,
+                "description": "Seat backrest angle 2 position\nBackrest angle 2 is the next actuator up from the bottom of the seat.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the seat backrest's full recline position w.r.t the next actuator in the backrest from the one at the bottom of the seat (see SEAT_BACKREST_ANGLE_1_POS for additional details). The maxInt32Value indicates the seat backrest's most upright\/forward position w.r.t the next actuator in the backrest from the one at the bottom of the seat(see SEAT_BACKREST_ANGLE_1_POS for additional details).\nValues in between minInt32Value and maxInt32Value indicate a transition state between the full recline and upright\/forward positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat backrest angle 2 move",
-                "value": 356518794
+                "value": 356518794,
+                "description": "Seat backrest angle 2 move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat backrest while angling forward. The minInt32Value represents the maximum movement speed of the seat backrest while reclining.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat backrest reaches the positional limit, the value must reset to 0. If SEAT_BACKREST_ANGLE_2_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat height position",
-                "value": 356518795
+                "value": 356518795,
+                "description": "Seat height position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the seat is in its lowest position. The maxInt32Value indicates the seat is in its highest position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the lowest and highest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat height move",
-                "value": 356518796
+                "value": 356518796,
+                "description": "Seat height move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat while moving upward. The minInt32Value represents the maximum movement speed of the seat while moving downward.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat reaches the positional limit, the value must reset to 0. If SEAT_HEIGHT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat depth position",
-                "value": 356518797
+                "value": 356518797,
+                "description": "Seat depth position\nSets the seat depth, distance from back rest to front edge of seat.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the seat is in its shallowest position (i.e. the position with the smallest distance between the front edge of the seat cushion and the rear end of the seat). The maxInt32Value indicates the seat is in its deepest position (i.e. the position with the largest distance between the front edge of the seat cushion and the rear end of the seat).\nValues in between minInt32Value and maxInt32Value indicate a transition state between the shallowest and deepest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat depth move",
-                "value": 356518798
+                "value": 356518798,
+                "description": "Seat depth move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat while getting deeper The minInt32Value represents the maximum movement speed of the seat while getting shallower.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat backrest reaches the positional limit, the value must reset to 0. If SEAT_DEPTH_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat tilt position",
-                "value": 356518799
+                "value": 356518799,
+                "description": "Seat tilt position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the seat bottom is angled at its lowest angular position. This corresponds to the seat's front edge at its lowest possible position relative to the rear end of the seat. The maxInt32Value indicates the seat bottom is angled at its highest angular position. This corresponds to the seat's front edge at its highest possible position relative to the rear end of the seat.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the lowest and highest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat tilt move",
-                "value": 356518800
+                "value": 356518800,
+                "description": "Seat tilt move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the front edge of the seat while moving upward. The minInt32Value represents the maximum movement speed of the front edge of the seat while moving downward.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat bottom reaches the positional limit, the value must reset to 0. If SEAT_TILT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Lumber fore\/aft position",
-                "value": 356518801
+                "value": 356518801,
+                "description": "Lumber fore\/aft position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the lumbar support is in its rearward most position (i.e. least supportive position). The maxInt32Value indicates the lumbar support is in its forward most position (i.e. most supportive position).\nValues in between minInt32Value and maxInt32Value indicate a transition state between the forward and rearward positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Lumbar fore\/aft move",
-                "value": 356518802
+                "value": 356518802,
+                "description": "Lumbar fore\/aft move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat's lumbar support while moving forward. The minInt32Value represents the maximum movement speed of the seat's lumbar support while moving backward.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat's lumbar support reaches the positional limit, the value must reset to 0. If SEAT_LUMBAR_FORE_AFT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Lumbar side support position",
-                "value": 356518803
+                "value": 356518803,
+                "description": "Lumbar side support position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the lumbar side support is in its thinnest position (i.e. most support). The maxInt32Value indicates the lumbar side support is in its widest position (i.e. least support).\nValues in between minInt32Value and maxInt32Value indicate a transition state between the thinnest and widest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Lumbar side support move",
-                "value": 356518804
+                "value": 356518804,
+                "description": "Lumbar side support move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat's lumbar side support while getting wider. The minInt32Value represents the maximum movement speed of the seat's lumbar side support while getting thinner.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat's lumbar side support reaches the positional limit, the value must reset to 0. If SEAT_LUMBAR_SIDE_SUPPORT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_HEADREST_HEIGHT_POS",
-                "value": 289409941
+                "value": 289409941,
+                "description": "(Deprecated) Headrest height position\nThis property is deprecated because it is defined as type VehicleArea:GLOBAL, which means all seats use the same value. Use SEAT_HEADREST_HEIGHT_POS_V2 instead which fixes this issue by being defined as type VehicleArea:SEAT.\nSets the headrest height. Max value indicates tallest setting. Min value indicates shortest setting.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Headrest height position",
-                "value": 356518820
+                "value": 356518820,
+                "description": "Headrest height position\nSets the headrest height for supported seats. VehiclePropConfig.areaConfigs specifies which seats are supported.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the headrest is in its lowest position. The maxInt32Value indicates the headrest is in its highest position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the lowest and highest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Headrest height move",
-                "value": 356518806
+                "value": 356518806,
+                "description": "Headrest height move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat's headrest while moving up. The minInt32Value represents the maximum movement speed of the seat's headrest while moving down.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat's headrest reaches the positional limit, the value must reset to 0. If SEAT_HEADREST_HEIGHT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Headrest angle position",
-                "value": 356518807
+                "value": 356518807,
+                "description": "Headrest angle position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the headrest is in its full recline position. The maxInt32Value indicates the headrest is in its most upright\/forward position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the full recline and most upright\/forward positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Headrest angle move",
-                "value": 356518808
+                "value": 356518808,
+                "description": "Headrest angle move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat's headrest while moving into an upright\/forward position. The minInt32Value represents the maximum movement speed of the seat's headrest while moving into a shallow position.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat's headrest reaches the positional limit, the value must reset to 0. If SEAT_HEADREST_ANGLE_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Headrest fore\/aft position",
-                "value": 356518809
+                "value": 356518809,
+                "description": "Headrest fore\/aft position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the headrest is in its rearward-most linear position. The maxInt32Value indicates the headrest is in its forward-most linear position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the forward and rearward positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Headrest fore\/aft move",
-                "value": 356518810
+                "value": 356518810,
+                "description": "Headrest fore\/aft move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat's headrest while moving forward. The minInt32Value represents the maximum movement speed of the seat's headrest while moving backward.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat's headrest reaches the positional limit, the value must reset to 0. If SEAT_HEADREST_FORE_AFT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_FOOTWELL_LIGHTS_STATE",
@@ -638,7 +772,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Represents property for the seat footwell lights state.\nSEAT_FOOTWELL_LIGHTS_STATE reflects the current state of the lights at any point in time. This is different from the function of SEAT_FOOTWELL_LIGHTS_SWITCH which represents the position of the switch controlling the lights. Therefore, SEAT_FOOTWELL_LIGHTS_STATE may not match the value of SEAT_FOOTWELL_LIGHTS_SWITCH (e.g. SEAT_FOOTWELL_LIGHTS_SWITCH=AUTOMATIC and SEAT_FOOTWELL_LIGHTS_STATE=ON).\nThis property should only be implemented if SEAT_FOOTWELL_LIGHTS_STATE's value may be different from that of CABIN_LIGHTS_STATE.\nFor each supported area ID, the VehicleAreaConfig#supportedEnumValues must be defined unless all enum values of VehicleLightState are supported."
             },
             {
                 "name": "SEAT_FOOTWELL_LIGHTS_SWITCH",
@@ -646,15 +781,18 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Represents property for the seat footwell lights switch.\nSEAT_FOOTWELL_LIGHTS_SWITCH represents the position of the switch controlling the lights. This is different from the function of SEAT_FOOTWELL_LIGHTS_STATE which reflects the current state of the lights at any point in time. Therefore, SEAT_FOOTWELL_LIGHTS_SWITCH may not match the value of SEAT_FOOTWELL_LIGHTS_STATE (e.g. SEAT_FOOTWELL_LIGHTS_SWITCH=AUTOMATIC and SEAT_FOOTWELL_LIGHTS_STATE=ON).\nThis property should only be implemented if SEAT_FOOTWELL_LIGHTS_SWITCH's value may be different from that of CABIN_LIGHTS_SWITCH.\nFor each supported area ID, the VehicleAreaConfig#supportedEnumValues must be defined unless all enum values of VehicleLightSwitch are supported.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_EASY_ACCESS_ENABLED",
-                "value": 354421661
+                "value": 354421661,
+                "description": "Represents property for Seat easy access feature.\nIf true, the seat will automatically adjust to make it easier for the occupant to enter and exit the vehicle. Each area ID must map to the seat that the user is trying to enter\/exit with the help of the easy access feature.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_AIRBAG_ENABLED",
-                "value": 354421662
+                "value": 354421662,
+                "description": "Represents feature to enable\/disable a seat's ability to deploy airbag(s) when triggered (e.g. by a crash).\nIf true, it means the seat's airbags are enabled, and if triggered (e.g. by a crash), they will deploy. If false, it means the seat's airbags are disabled, and they will not deploy under any circumstance. This property does not indicate if the airbags are deployed or not.\nThis property can be set to VehiclePropertyAccess.READ read only for the sake of regulation or safety concerns.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Seat airbags deployed",
@@ -662,31 +800,38 @@
                 "data_enums": [
                     "VehicleAirbagLocation"
                 ],
-                "data_enum": "VehicleAirbagLocation"
+                "data_enum": "VehicleAirbagLocation",
+                "description": "Seat airbags deployed\nBit flag property to relay information on which airbags have been deployed in the vehicle at each seat, vs which ones are currently still armed. If SEAT_AIRBAG_ENABLED is set to false at a particular areaId, this property should return status code UNAVAILABLE at that areaId.\nEnums apply to each seat, not the global vehicle. For example, VehicleAirbagsLocation#CURTAIN at the driver seat areaId represents whether the driver side curtain airbag has been deployed. Multiple bit flags can be set to indicate that multiple different airbags have been deployed for the seat.\nFor each seat area ID, the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of VehicleAirbagLocation are supported (including OTHER, which is not recommended)."
             },
             {
                 "name": "SEAT_CUSHION_SIDE_SUPPORT_POS",
-                "value": 356518815
+                "value": 356518815,
+                "description": "Represents property for seat’s hipside (bottom cushion’s side) support position.\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the seat cushion side support is in its widest position (i.e. least support). The minInt32Value indicates the seat cushion side support is in its thinnest position (i.e. most support).\nValues in between minInt32Value and maxInt32Value indicate a transition state between the thinnest and widest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_CUSHION_SIDE_SUPPORT_MOVE",
-                "value": 356518816
+                "value": 356518816,
+                "description": "Represents property for movement direction and speed of seat cushion side support.\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value represents the maximum movement speed of the seat cushion side support when growing wider (i.e. support is decreasing). The minInt32Value represents the maximum movement speed of the seat cushion side support when growing thinner (i.e. support is increasing).\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat cushion side support reaches the positional limit, the value must reset to 0. If SEAT_CUSHION_SIDE_SUPPORT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_LUMBAR_VERTICAL_POS",
-                "value": 356518817
+                "value": 356518817,
+                "description": "Represents property for seat’s lumbar support vertical position.\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the lumbar support's highest position. The minInt32Value indicates the lumbar support's lowest position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the lowest and highest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_LUMBAR_VERTICAL_MOVE",
-                "value": 356518818
+                "value": 356518818,
+                "description": "Represents property for vertical movement direction and speed of seat lumbar support.\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the lumbar support is moving at the fastest upward speed. The minInt32Value indicates the lumbar support is moving at the fastest downward speed.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the seat cushion side support reaches the positional limit, the value must reset to 0. If SEAT_LUMBAR_VERTICAL_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_WALK_IN_POS",
-                "value": 356518819
+                "value": 356518819,
+                "description": "Represents property that indicates the current walk-in position of the seat.\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the normal seat position. The minInt32Value must be 0. The maxInt32Value indicates the seat is in the full walk-in position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the normal and walk-in positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThe area ID must match the seat that actually moves when the walk-in feature activates, not the intended seat the passengers will sit in.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SEAT_BELT_PRETENSIONER_DEPLOYED",
-                "value": 354421670
+                "value": 354421670,
+                "description": "Seat belt pretensioner deployed.\nProperty to relay information on whether the seat belt pretensioner has been deployed for a particular seat due to a collision. This is different from the regular seat belt tightening system that continuously adds tension to the seat belts so that they fit snugly around the person sitting in the seat, nor is it the seat belt retractor system that locks the seat belt in place during sudden brakes or when the user jerks the seat belt.\nIf this property is dependant on the state of other properties, and those properties are currently in the state that doesn't support this property, this should return StatusCode#NOT_AVAILABLE"
             },
             {
                 "name": "Seat Occupancy",
@@ -694,23 +839,28 @@
                 "data_enums": [
                     "VehicleSeatOccupancyState"
                 ],
-                "data_enum": "VehicleSeatOccupancyState"
+                "data_enum": "VehicleSeatOccupancyState",
+                "description": "Seat Occupancy\nIndicates whether a particular seat is occupied or not, to the best of the car's ability to determine. Valid values are from the VehicleSeatOccupancyState enum."
             },
             {
                 "name": "Window Position",
-                "value": 322964416
+                "value": 322964416,
+                "description": "Window Position\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates the window is closed\/fully open out of plane. If the window cannot open out of plane, then minInt32Value is the position of the window when fully closed and must be 0. If the window can open out of plane, the minInt32Value indicates the window is fully open in its position out of plane and will be a negative value. See the example below for a more detailed explanation. The maxInt32Value indicates the window is fully open.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the closed\/fully open out-of-plane and fully open positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nFor example, this is how the property should work for a window that can move out of plane: For a window that may open out of plane (i.e. vent mode of sunroof) this parameter will work with negative values as follows: Max = sunroof completely open 0 = sunroof closed. Min = sunroof vent completely open\nNote that in this mode, 0 indicates the window is closed.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Window Move",
-                "value": 322964417
+                "value": 322964417,
+                "description": "Window Move\nThe maxInt32Value and minInt32Value in each VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the window is opening in plane\/closing in the out of plane direction at the fastest speed. The minInt32Value indicates the window is closing in plane\/opening in the out of plane direction at the fastest speed.\nLarger absolute values, either positive or negative, indicate a faster movement speed. Once the window reaches the positional limit, the value must reset to 0. If WINDOW_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nFor a window that may open out of plane (i.e. vent mode of sunroof) this parameter will work as follows:\nIf sunroof is open: Max = open the sunroof further, automatically stop when fully open. Min = close the sunroof, automatically stop when sunroof is closed.\nIf vent is open: Max = close the vent, automatically stop when vent is closed. Min = open the vent further, automatically stop when vent is fully open.\nIf sunroof is in the closed position: Max = open the sunroof, automatically stop when sunroof is fully open. Min = open the vent, automatically stop when vent is fully open.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
-                "name": "Window Lock",
-                "value": 320867268
+                "name": "Window Child Lock",
+                "value": 320867268,
+                "description": "Window Child Lock\nTrue indicates the window is child-locked.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "WINDSHIELD_WIPERS_PERIOD",
-                "value": 322964421
+                "value": 322964421,
+                "description": "Windshield wipers period (milliseconds).\nReturns the instantaneous time period for 1 full cycle of the windshield wipers in milliseconds. A full cycle is defined as a wiper moving from and returning to its rest position.\nWhen an intermittent wiper setting is selected, this property value must be set to 0 during the \"pause\" period of the intermittent wiping.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. The maxInt32Value for each area ID must specify the longest wiper period. The minInt32Value must be set to 0 for each area ID."
             },
             {
                 "name": "Windshield wipers state.",
@@ -718,7 +868,8 @@
                 "data_enums": [
                     "WindshieldWipersState"
                 ],
-                "data_enum": "WindshieldWipersState"
+                "data_enum": "WindshieldWipersState",
+                "description": "Windshield wipers state.\nReturns the current state of the windshield wipers. The value of WINDSHIELD_WIPERS_STATE may not match the value of WINDSHIELD_WIPERS_SWITCH. (e.g. WINDSHIELD_WIPERS_STATE = ON and WINDSHIELD_WIPERS_SWITCH = WindshieldWipersSwitch#AUTO).\nIf WINDSHIELD_WIPERS_STATE = ON and WINDSHIELD_WIPERS_PERIOD is implemented, then WINDSHIELD_WIPERS_PERIOD must reflect the time period of 1 full cycle of the wipers.\nFor each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined unless all states in WindshieldWipersState are supported (including OTHER, which is not recommended)."
             },
             {
                 "name": "Windshield wipers switch.",
@@ -726,91 +877,113 @@
                 "data_enums": [
                     "WindshieldWipersSwitch"
                 ],
-                "data_enum": "WindshieldWipersSwitch"
+                "data_enum": "WindshieldWipersSwitch",
+                "description": "Windshield wipers switch.\nRepresents the position of the switch controlling the windshield wipers. The value of WINDSHIELD_WIPERS_SWITCH may not match the value of WINDSHIELD_WIPERS_STATE (e.g. WINDSHIELD_WIPERS_SWITCH = AUTO and WINDSHIELD_WIPERS_STATE = WindshieldWipersState#ON).\nFor each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined unless all states in WindshieldWipersSwitch are supported (including OTHER, which is not recommended).\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only.\nIf this property is implemented as VehiclePropertyAccess.READ_WRITE and the OTHER state is listed in the VehicleAreaConfig#supportedEnumValues array, then OTHER is not a supported value for writing. It is only a supported value for reading."
             },
             {
                 "name": "Steering wheel depth position",
-                "value": 289410016
+                "value": 289410016,
+                "description": "Steering wheel depth position\nAll steering wheel properties' unique ids start from 0x0BE0.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the steering wheel position furthest from the driver. The minInt32Value indicates the steering wheel position closest to the driver.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the closest and furthest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Steering wheel depth movement",
-                "value": 289410017
+                "value": 289410017,
+                "description": "Steering wheel depth movement\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the steering wheel moving away from the driver. The minInt32Value indicates the steering wheel moving towards the driver.\nLarger integers, either positive or negative, indicate a faster movement speed. Once the steering wheel reaches the positional limit, the value must reset to 0. If STEERING_WHEEL_DEPTH_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Steering wheel height position",
-                "value": 289410018
+                "value": 289410018,
+                "description": "Steering wheel height position\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the steering wheel being in the highest position. The minInt32Value indicates the steering wheel being in the lowest position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the lowest and highest positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Steering wheel height movement",
-                "value": 289410019
+                "value": 289410019,
+                "description": "Steering wheel height movement\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between minInt32Value and maxInt32Value must be supported.\nThe maxInt32Value indicates the steering wheel moving upwards. The minInt32Value indicates the steering wheel moving downwards.\nLarger integers, either positive or negative, indicate a faster movement speed. Once the steering wheel reaches the positional limit, the value must reset to 0. If STEERING_WHEEL_HEIGHT_MOVE's value is currently 0, then that means there is no movement currently occurring.\nThis property is not in any particular unit but in a specified range of relative movement speeds.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "STEERING_WHEEL_THEFT_LOCK_ENABLED",
-                "value": 287312868
+                "value": 287312868,
+                "description": "Steering wheel theft lock feature enabled\nIf true, the steering wheel will lock automatically to prevent theft in certain situations.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Steering wheel locked",
-                "value": 287312869
+                "value": 287312869,
+                "description": "Steering wheel locked\nIf true, the steering wheel's position is locked and not changeable.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "STEERING_WHEEL_EASY_ACCESS_ENABLED",
-                "value": 287312870
+                "value": 287312870,
+                "description": "Steering wheel easy access feature enabled\nIf true, the driver’s steering wheel will automatically adjust to make it easier for the driver to enter and exit the vehicle.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "GLOVE_BOX_DOOR_POS",
-                "value": 356518896
+                "value": 356518896,
+                "description": "Property that represents the current position of the glove box door.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All integers between minInt32Value and maxInt32Value must be supported.\nThe minInt32Value indicates that the glove box door is closed. The minInt32Value must be 0. The maxInt32Value indicates that the glove box door is in the fully open position.\nValues in between minInt32Value and maxInt32Value indicate a transition state between the closed and fully open positions.\nThis property is not in any particular unit but in a specified range of relative positions.\nThe area ID must match the seat by which the glove box is intended to be used  (e.g. if the front right dashboard has a glove box embedded in it, then the area ID should be SEAT_1_RIGHT).\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Lock or unlock the glove box.",
-                "value": 354421745
+                "value": 354421745,
+                "description": "Lock or unlock the glove box.\nIf true, the glove box is locked. If false, the glove box is unlocked.\nThe area ID must match the seat by which the glove box is intended to be used (e.g. if the front right dashboard has a glove box embedded in it, then the area ID should be VehicleAreaSeat#ROW_1_RIGHT).\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "VEHICLE_MAP_SERVICE",
-                "value": 299895808
+                "value": 299895808,
+                "description": "Vehicle Maps Service (VMS) message\nThis property uses MIXED data to communicate vms messages.\nIts contents are to be interpreted as follows: the indices defined in VmsMessageIntegerValuesIndex are to be used to read from int32Values; bytes is a serialized VMS message as defined in the vms protocol which is opaque to the framework;\nIVehicle#get must always return StatusCode::NOT_AVAILABLE."
             },
             {
                 "name": "LOCATION_CHARACTERIZATION",
-                "value": 289410064
+                "value": 289410064,
+                "description": "Characterization of inputs used for computing location.\nThis property must indicate what (if any) data and sensor inputs are considered by the system when computing the vehicle's location that is shared with Android through the GNSS HAL.\nThe value must return a collection of bit flags. The bit flags are defined in LocationCharacterization. The value must also include exactly one of DEAD_RECKONED or RAW_GNSS_ONLY among its collection of bit flags.\nWhen this property is not supported, it is assumed that no additional sensor inputs are fused into the GNSS updates provided through the GNSS HAL. That is unless otherwise specified through the GNSS HAL interfaces."
             },
             {
                 "name": "ULTRASONICS_SENSOR_POSITION",
-                "value": 406916128
+                "value": 406916128,
+                "description": "Static data for the position of each ultrasonic sensor installed on the vehicle.\nEach individual sensor is identified by its unique VehicleAreaConfig#areaId and returns the sensor's position formatted as [x, y, z] where:\nint32Values[0] = x, the position of the sensor along the x-axis relative to the origin of the Android Automotive sensor coordinate frame in millimeters int32Values[1] = y, the position of the sensor along the y-axis relative to the origin of the Android Automotive sensor coordinate frame in millimeters. int32Values[2] = z, the position of the sensor along the z-axis relative to the origin of the Android Automotive sensor coordinate frame in millimeters.\nIf the data is aggregated by another ECU, then OEMs have the option of reporting the same reading across all included sensors or reporting a virtual representation of all the included sensors as if they were one sensor."
             },
             {
                 "name": "ULTRASONICS_SENSOR_ORIENTATION",
-                "value": 409013281
+                "value": 409013281,
+                "description": "Static data for the orientation of each ultrasonic sensor installed on the vehicle.\nEach individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's orientation formatted as [qw, qx, qy, qz] where:\nint32Values[0] = qw, the quaternion coefficient w within the quaterinion (w + xi + yj + zk) describing the rotation of the sensor relative to the Android Automotive sensor coordinate frame. int32Values[1] = qx, the quaternion coefficient x within the quaterinion (w + xi + yj + zk) describing the rotation of the sensor relative to the Android Automotive sensor coordinate frame. int32Values[2] = qy, the quaternion coefficient y within the quaterinion (w + xi + yj + zk) describing the rotation of the sensor relative to the Android Automotive sensor coordinate frame. int32Values[3] = qz, the quaternion coefficient z within the quaterinion (w + xi + yj + zk) describing the rotation of the sensor relative to the Android Automotive sensor coordinate frame.\nThis assumes each sensor uses the same axes conventions as Android Automotive.\nIf the data is aggregated by another ECU, then OEMs have the option of reporting the same reading across all included sensors or reporting a virtual representation of all the included sensors as if they were one sensor."
             },
             {
                 "name": "ULTRASONICS_SENSOR_FIELD_OF_VIEW",
-                "value": 406916130
+                "value": 406916130,
+                "description": "Static data for the field of view of each ultrasonic sensor in degrees.\nEach individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's field of view formatted as [horizontal, vertical] where:\nint32Values[0] = horizontal, the horizontal field of view for the specified ultrasonic sensor in degrees. int32Values[1] = vertical, the vertical field of view for the associated specified ultrasonic sensor in degrees.\nThis assumes each sensor uses the same axes conventions as Android Automotive.\nIf the data is aggregated by another ECU, then OEMs have the option of reporting the same reading across all included sensors or reporting a virtual representation of all the included sensors as if they were one sensor."
             },
             {
                 "name": "ULTRASONICS_SENSOR_DETECTION_RANGE",
-                "value": 406916131
+                "value": 406916131,
+                "description": "Static data for the detection range of each ultrasonic sensor in millimeters.\nEach individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's detection range formatted as [minimum, maximum] where:\nint32Values[0] = minimum, the minimum range detectable by the ultrasonic sensor in millimeters. int32Values[1] = maximum, the maximum range detectable by the ultrasonic sensor in millimeters.\nIf the data is aggregated by another ECU, then OEMs have the option of reporting the same reading across all included sensors or reporting a virtual representation of all the included sensors as if they were one sensor."
             },
             {
                 "name": "ULTRASONICS_SENSOR_SUPPORTED_RANGES",
-                "value": 406916132
+                "value": 406916132,
+                "description": "Static data for the supported ranges of each ultrasonic sensor in millimeters.\nFor ultrasonic sensors that only support readings within a specific range. For example, if an ultrasonic sensor detects an object at 700mm, but can only report that an object has been detected between 500mm and 1000mm.\nEach individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's supported ranges formatted as [range_min_1, range_max_1, range_min_2, range_max_2, ...] where:\nint32Values[0] = range_min_1, the minimum of one supported range by the specified sensor in millimeters, inclusive. int32Values[1] = range_max_1, the maximum of one supported range by the specified sensor in millimeters, inclusive. int32Values[2] = range_min_2, the minimum of another supported range by the specified sensor in millimeters, inclusive. int32Values[3] = range_max_2, the maximum of another supported range by the specified sensor in millimeters, inclusive.\nExample: - Ultrasonic sensor supports the following ranges: - 150mm to 499mm - 500mm to 999mm - 1000mm to 1500mm - The associated supported ranges should be formatted as: - int32Values[0] = 150 - int32Values[1] = 499 - int32Values[2] = 500 - int32Values[3] = 999 - int32Values[4] = 1000 - int32Values[5] = 1500\nIf this property is not defined, all the values within the ULTRASONICS_SENSOR_DETECTION_RANGE for the specified sensor are assumed to be supported.\nIf the data is aggregated by another ECU, then OEMs have the option of reporting the same reading across all included sensors or reporting a virtual representation of all the included sensors as if they were one sensor."
             },
             {
                 "name": "ULTRASONICS_SENSOR_MEASURED_DISTANCE",
-                "value": 406916133
+                "value": 406916133,
+                "description": "The distance reading of the nearest detected object per sensor in millimeters.\nEach individual sensor is identified by its VehicleAreaConfig#areaId and returns the sensor's measured distance formatted as [distance, distance_error] where:\nint32Values[0] = distance, the measured distance of the nearest object in millimeters. If only a range is supported, this value must be set to the minimum supported distance in the detected range as specified in ULTRASONICS_SENSOR_SUPPORTED_RANGES. int32Values[1] = distance_error, the error of the measured distance value in millimeters.\nIf no object is detected, an empty vector must be returned. If distance_error is not available then an array of only the measured distance must be returned.\nIf the data is aggregated by another ECU, then OEMs have the option of reporting the same reading across all included sensors or reporting a virtual representation of all the included sensors as if they were one sensor."
             },
             {
                 "name": "OBD2 Live Sensor Data",
-                "value": 299896064
+                "value": 299896064,
+                "description": "OBD2 Live Sensor Data\nReports a snapshot of the current (live) values of the OBD2 sensors available.\nThe configArray is set as follows: configArray[0] = number of vendor-specific integer-valued sensors configArray[1] = number of vendor-specific float-valued sensors\nThe values of this property are to be interpreted as in the following example. Considering a configArray = {2,3} int32Values must be a vector containing Obd2IntegerSensorIndex.LAST_SYSTEM_INDEX + 2 elements (that is, 33 elements); floatValues must be a vector containing Obd2FloatSensorIndex.LAST_SYSTEM_INDEX + 3 elements (that is, 73 elements);\nIt is possible for each frame to contain a different subset of sensor values, both system provided sensors, and vendor-specific ones. In order to support that, the bytes element of the property value is used as a bitmask,.\nbytes must have a sufficient number of bytes to represent the total number of possible sensors (in this case, 14 bytes to represent 106 possible values); it is to be read as a contiguous bitmask such that each bit indicates the presence or absence of a sensor from the frame, starting with as many bits as the size of int32Values, immediately followed by as many bits as the size of floatValues.\nFor example, should bytes[0] = 0x4C (0b01001100) it would mean that: int32Values[0 and 1] are not valid sensor values int32Values[2 and 3] are valid sensor values int32Values[4 and 5] are not valid sensor values int32Values[6] is a valid sensor value int32Values[7] is not a valid sensor value Should bytes[5] = 0x61 (0b01100001) it would mean that: int32Values[32] is a valid sensor value floatValues[0 thru 3] are not valid sensor values floatValues[4 and 5] are valid sensor values floatValues[6] is not a valid sensor value"
             },
             {
                 "name": "OBD2 Freeze Frame Sensor Data",
-                "value": 299896065
+                "value": 299896065,
+                "description": "OBD2 Freeze Frame Sensor Data\nReports a snapshot of the value of the OBD2 sensors available at the time that a fault occurred and was detected.\nA configArray must be provided with the same meaning as defined for OBD2_LIVE_FRAME.\nThe values of this property are to be interpreted in a similar fashion as those for OBD2_LIVE_FRAME, with the exception that the stringValue field may contain a non-empty diagnostic troubleshooting code (DTC).\nA IVehicle#get request of this property must provide a value for int64Values[0]. This will be interpreted as the timestamp of the freeze frame to retrieve. A list of timestamps can be obtained by a IVehicle#get of OBD2_FREEZE_FRAME_INFO.\nShould no freeze frame be available at the given timestamp, a response of NOT_AVAILABLE must be returned by the implementation. Because vehicles may have limited storage for freeze frames, it is possible for a frame request to respond with NOT_AVAILABLE even if the associated timestamp has been recently obtained via OBD2_FREEZE_FRAME_INFO."
             },
             {
                 "name": "OBD2 Freeze Frame Information",
-                "value": 299896066
+                "value": 299896066,
+                "description": "OBD2 Freeze Frame Information\nThis property describes the current freeze frames stored in vehicle memory and available for retrieval via OBD2_FREEZE_FRAME.\nThe values are to be interpreted as follows: each element of int64Values must be the timestamp at which a a fault code has been detected and the corresponding freeze frame stored, and each such element can be used as the key to OBD2_FREEZE_FRAME to retrieve the corresponding freeze frame."
             },
             {
                 "name": "OBD2 Freeze Frame Clear",
-                "value": 299896067
+                "value": 299896067,
+                "description": "OBD2 Freeze Frame Clear\nThis property allows deletion of any of the freeze frames stored in vehicle memory, as described by OBD2_FREEZE_FRAME_INFO.\nThe configArray is set as follows: configArray[0] = 1 if the implementation is able to clear individual freeze frames by timestamp, 0 otherwise\nIVehicle#set of this property is to be interpreted as follows: if int64Values contains no elements, then all frames stored must be cleared; if int64Values contains one or more elements, then frames at the timestamps stored in int64Values must be cleared, and the others not cleared. Should the vehicle not support selective clearing of freeze frames, this latter mode must return NOT_AVAILABLE."
             },
             {
                 "name": "Headlights State",
@@ -818,7 +991,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Headlights State\nReturn the current state of headlights."
             },
             {
                 "name": "High beam lights state",
@@ -826,7 +1000,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "High beam lights state\nReturn the current state of high beam lights."
             },
             {
                 "name": "Fog light state",
@@ -834,7 +1009,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Fog light state\nReturn the current state of fog lights.\nIf the car has both front and rear fog lights: If front and rear fog lights can only be controlled together: FOG_LIGHTS_STATE must be implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must not be implemented.\nIf the front and rear fog lights can only be controlled independently: FOG_LIGHTS_STATE must not be implemented. FRONT_FOG_LIGHTS_STATE and REAR_FOG_LIGHTS_STATE must be implemented.\nIf the car has only front fog lights: Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented and not both. REAR_FOG_LIGHTS_STATE must not be implemented.\nIf the car has only rear fog lights: Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented and not both. FRONT_FOG_LIGHTS_STATE must not be implemented."
             },
             {
                 "name": "Hazard light status",
@@ -842,7 +1018,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Hazard light status\nReturn the current status of hazard lights."
             },
             {
                 "name": "Headlight switch",
@@ -850,7 +1027,8 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Headlight switch\nThe setting that the user wants.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "High beam light switch",
@@ -858,7 +1036,8 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "High beam light switch\nThe setting that the user wants.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Fog light switch",
@@ -866,7 +1045,8 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Fog light switch\nThe setting that the user wants.\nIf the car has both front and rear fog lights: If front and rear fog lights can only be controlled together: FOG_LIGHTS_SWITCH must be implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must not be implemented.\nIf the front and rear fog lights can only be controlled independently: FOG_LIGHTS_SWITCH must not be implemented. FRONT_FOG_LIGHTS_SWITCH and REAR_FOG_LIGHTS_SWITCH must be implemented.\nIf the car has only front fog lights: Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented and not both. REAR_FOG_LIGHTS_SWITCH must not be implemented.\nIf the car has only rear fog lights: Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented and not both. FRONT_FOG_LIGHTS_SWITCH must not be implemented.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Hazard light switch",
@@ -874,7 +1054,8 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Hazard light switch\nThe setting that the user wants.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Cabin lights",
@@ -882,7 +1063,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Cabin lights\nReturn current status of cabin lights."
             },
             {
                 "name": "Cabin lights switch",
@@ -890,7 +1072,8 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Cabin lights switch\nThe position of the physical switch which controls the cabin lights. This might be different than the CABIN_LIGHTS_STATE if the lights are on because a door is open or because of a voice command. For example, while the switch is in the \"off\" or \"automatic\" position.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Reading lights",
@@ -898,7 +1081,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Reading lights\nReturn current status of reading lights."
             },
             {
                 "name": "Reading lights switch",
@@ -906,7 +1090,8 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Reading lights switch\nThe position of the physical switch which controls the reading lights. This might be different than the READING_LIGHTS_STATE if the lights are on because a door is open or because of a voice command. For example, while the switch is in the \"off\" or \"automatic\" position.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Steering wheel lights state",
@@ -914,7 +1099,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Steering wheel lights state\nRepresents the current state of the steering wheel lights. This is different from STEERING_WHEEL_LIGHTS_SWITCH which represents the position of the switch controlling the lights. Therefore, STEERING_WHEEL_LIGHTS_STATE may not match the value of STEERING_WHEEL_LIGHTS_SWITCH (e.g. STEERING_WHEEL_LIGHTS_SWITCH=AUTOMATIC and STEERING_WHEEL_LIGHTS_STATE=ON).\nThis property should only be implemented if STEERING_WHEEL_LIGHTS_STATE's value may be different from that of CABIN_LIGHTS_STATE.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless all enum values of VehicleLightState are supported."
             },
             {
                 "name": "Steering wheel lights switch",
@@ -922,83 +1108,103 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Steering wheel lights switch\nRepresents the position of the switch controlling the steering wheel lights. This is different from STEERING_WHEEL_LIGHTS_STATE which represents the current state of the steering wheel lights. Therefore, STEERING_WHEEL_LIGHTS_SWITCH may not match the value of STEERING_WHEEL_LIGHTS_STATE (e.g. STEERING_WHEEL_LIGHTS_SWITCH=AUTOMATIC and STEERING_WHEEL_LIGHTS_STATE=ON).\nThis property should only be implemented if STEERING_WHEEL_LIGHTS_SWITCH's value may be different from that of CABIN_LIGHTS_SWITCH.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless all enum values of VehicleLightSwitch are supported.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "SUPPORT_CUSTOMIZE_VENDOR_PERMISSION",
-                "value": 287313669
+                "value": 287313669,
+                "description": "Support customize permissions for vendor properties\nImplement this property if vehicle hal support customize vendor permissions feature. VehiclePropConfig.configArray is used to indicate vendor properties and permissions which selected for this vendor property. The permission must be one of enum in VehicleVendorPermission. The configArray is set as follows: configArray[n] = propId : property ID for the vendor property configArray[n+1] = one of enums in VehicleVendorPermission. It indicates the permission for reading value of the property. configArray[n+2] = one of enums in VehicleVendorPermission. It indicates the permission for writing value of the property.\nFor example: configArray = { vendor_prop_1, PERMISSION_VENDOR_SEAT_READ, PERMISSION_VENDOR_SEAT_WRITE, vendor_prop_2, PERMISSION_VENDOR_INFO, PERMISSION_NOT_ACCESSIBLE, } If vendor properties are not in this array, they will have the default vendor permission. If vendor chose PERMISSION_NOT_ACCESSIBLE, android will not have access to the property. In the example, Android can not write value for vendor_prop_2."
             },
             {
                 "name": "DISABLED_OPTIONAL_FEATURES",
-                "value": 286265094
+                "value": 286265094,
+                "description": "Allow disabling optional featurs from vhal.\nThis property reports optional features that should be disabled. All allowed optional features for the system is declared in Car service overlay, config_allowed_optional_car_features. This property allows disabling features defined in the overlay. Without this property, all the features declared in the overlay will be enabled.\nValue read should include all features disabled with ',' separation. ex) \"com.android.car.user.CarUserNoticeService,storage_monitoring\""
             },
             {
                 "name": "INITIAL_USER_INFO",
-                "value": 299896583
+                "value": 299896583,
+                "description": "Defines the initial Android user to be used during initialization.\nThis property is called by the Android system when it initializes and it lets the HAL define which Android user should be started.\nThis request is made by setting a VehiclePropValue (defined by InitialUserInfoRequest), and the HAL must respond with a property change event (defined by InitialUserInfoResponse). If the HAL doesn't respond after some time (defined by the Android system), the Android system will proceed as if HAL returned a response of action InitialUserInfoResponseAction:DEFAULT.\nFor example, on first boot, the request could be:\nint32[0]: 42  \/\/ request id (arbitrary number set by Android system) int32[1]: 1   \/\/ InitialUserInfoRequestType::FIRST_BOOT int32[2]: 0   \/\/ id of current user (usersInfo.currentUser.userId) int32[3]: 1   \/\/ flag of current user (usersInfo.currentUser.flags = SYSTEM) int32[4]: 1   \/\/ number of existing users (usersInfo.numberUsers); int32[5]: 0   \/\/ user #0  (usersInfo.existingUsers[0].userId) int32[6]: 1   \/\/ flags of user #0  (usersInfo.existingUsers[0].flags)\nAnd if the HAL want to respond with the creation of an admin user called \"Owner\", the response would be:\nint32[0]: 42      \/\/ must match the request id from the request int32[1]:  2      \/\/ action = InitialUserInfoResponseAction::CREATE int32[2]: -10000  \/\/ userToSwitchOrCreate.userId (not used as user will be created) int32[3]:  8      \/\/ userToSwitchOrCreate.flags = ADMIN string: \"||Owner\" \/\/ userLocales + separator + userNameToCreate\nNotice the string value represents multiple values, separated by ||. The first value is the (optional) system locales for the user to be created (in this case, it's empty, meaning it will use Android's default value), while the second value is the (also optional) name of the to user to be created (when the type of response is InitialUserInfoResponseAction:CREATE). For example, to create the same \"Owner\" user with \"en-US\" and \"pt-BR\" locales, the string value of the response would be \"en-US,pt-BR||Owner\". As such, neither the locale nor the name can have || on it, although a single | is fine.\nNOTE: if the HAL doesn't support user management, then it should not define this property, which in turn would disable the other user-related properties (for example, the Android system would never issue them and user-related requests from the HAL layer would be ignored by the Android System). But if it supports user management, then it must support all core user-related properties (INITIAL_USER_INFO, SWITCH_USER, CREATE_USER, and REMOVE_USER)."
             },
             {
                 "name": "SWITCH_USER",
-                "value": 299896584
+                "value": 299896584,
+                "description": "Defines a request to switch the foreground Android user.\nThis property is used primarily by the Android System to inform the HAL that the current foreground Android user is switching, but it could also be used by the HAL to request the Android system to switch users - the\nWhen the request is made by Android, it sets a VehiclePropValue and the HAL must responde with a property change event; when the HAL is making the request, it must also do it through a property change event (the main difference is that the request id will be positive in the former case, and negative in the latter; the SwitchUserMessageType will also be different).\nThe format of both request is defined by SwitchUserRequest and the format of the response (when needed) is defined by SwitchUserResponse. How the HAL (or Android System) should proceed depends on the message type (which is defined by the SwitchUserMessageType parameter), as defined below.\n1.LEGACY_ANDROID_SWITCH -----------------------\nCalled by the Android System to indicate the Android user is about to change, when the change request was made in a way that is not integrated with the HAL (for example, through adb shell am switch-user).\nThe HAL can switch its internal user once it receives this request, but it doesn't need to reply back to the Android System. If its internal user cannot be changed for some reason, then it must wait for the SWITCH_USER(type=ANDROID_POST_SWITCH) call to recover (for example, it could issue a SWITCH_USER(type=VEHICLE_REQUEST) to switch back to the previous user), but ideally it should never fail (as switching back could result in a confusing experience for the end user).\nFor example, if the system have users (0, 10, 11) and it's switching from 0 to 11 (where none of them have any special flag), the request would be:\nint32[0]:  42  \/\/ request id int32[1]:  1   \/\/ SwitchUserMessageType::LEGACY_ANDROID_SWITCH int32[2]:  11  \/\/ target user id int32[3]:  0   \/\/ target user flags (none) int32[4]:  10  \/\/ current user int32[5]:  0   \/\/ current user flags (none) int32[6]:  3   \/\/ number of users int32[7]:  0   \/\/ user #0 (Android user id 0) int32[8]:  0   \/\/ flags of user #0 (none) int32[9]:  10  \/\/ user #1 (Android user id 10) int32[10]: 0   \/\/ flags of user #1 (none) int32[11]: 11  \/\/ user #2 (Android user id 11) int32[12]: 0   \/\/ flags of user #2 (none)\n2.ANDROID_SWITCH ---------------- Called by the Android System to indicate the Android user is about to change, but Android will wait for the HAL's response (up to some time) before proceeding.\nThe HAL must switch its internal user once it receives this request, then respond back to Android with a SWITCH_USER(type=VEHICLE_RESPONSE) indicating whether its internal user was switched or not (through the SwitchUserStatus enum).\nFor example, if Android has users (0, 10, 11) and it's switching from 10 to 11 (where none of them have any special flag), the request would be:\nint32[0]:  42  \/\/ request id int32[1]:  2   \/\/ SwitchUserMessageType::ANDROID_SWITCH int32[2]:  11  \/\/ target user id int32[3]:  0   \/\/ target user flags (none) int32[4]:  10  \/\/ current user int32[5]:  0   \/\/ current user flags (none) int32[6]:  3   \/\/ number of users int32[7]:  0   \/\/ 1st user (user 0) int32[8]:  1   \/\/ 1st user flags (SYSTEM) int32[9]:  10  \/\/ 2nd user (user 10) int32[10]: 0   \/\/ 2nd user flags (none) int32[11]: 11  \/\/ 3rd user (user 11) int32[12]: 0   \/\/ 3rd user flags (none)\nIf the request succeeded, the HAL must update the property with:\nint32[0]: 42  \/\/ request id int32[1]: 3   \/\/ messageType = SwitchUserMessageType::VEHICLE_RESPONSE int32[2]: 1   \/\/ status = SwitchUserStatus::SUCCESS\nBut if it failed, the response would be something like:\nint32[0]: 42   \/\/ request id int32[1]: 3    \/\/ messageType = SwitchUserMessageType::VEHICLE_RESPONSE int32[2]: 2    \/\/ status = SwitchUserStatus::FAILURE string: \"108-D'OH!\" \/\/ OEM-specific error message\n3.VEHICLE_RESPONSE ------------------ Called by the HAL to indicate whether a request of type ANDROID_SWITCH should proceed or abort - see the ANDROID_SWITCH section above for more info.\n4.VEHICLE_REQUEST ------------------ Called by the HAL to request that the current foreground Android user is switched.\nThis is useful in situations where Android started as one user, but the vehicle identified the driver as another user. For example, user A unlocked the car using the key fob of user B; the INITIAL_USER_INFO request returned user B, but then a face recognition subsubsystem identified the user as A.\nThe HAL makes this request by a property change event (passing a negative request id), and the Android system will response by issue an ANDROID_POST_SWITCH call which the same request id.\nFor example, if the current foreground Android user is 10 and the HAL asked it to switch to 11, the request would be:\nint32[0]: -108  \/\/ request id int32[1]: 4     \/\/ messageType = SwitchUserMessageType::VEHICLE_REQUEST int32[2]: 11    \/\/ Android user id\nIf the request succeeded and Android has 3 users (0, 10, 11), the response would be:\nint32[0]: -108 \/\/ request id int32[1]:  5   \/\/ messageType = SwitchUserMessageType::ANDROID_POST_SWITCH int32[2]:  11  \/\/ target user id int32[3]:  0   \/\/ target user id flags (none) int32[4]:  11  \/\/ current user int32[5]:  0   \/\/ current user flags (none) int32[6]:  3   \/\/ number of users int32[7]:  0   \/\/ 1st user (user 0) int32[8]:  0   \/\/ 1st user flags (none) int32[9]:  10  \/\/ 2nd user (user 10) int32[10]: 4   \/\/ 2nd user flags (none) int32[11]: 11  \/\/ 3rd user (user 11) int32[12]: 3   \/\/ 3rd user flags (none)\nNotice that both the current and target user ids are the same - if the request failed, then they would be different (i.e, target user would be 11, but current user would still be 10).\n5.ANDROID_POST_SWITCH --------------------- Called by the Android System after a request to switch a user was made.\nThis property is called after switch requests of any type (i.e., LEGACY_ANDROID_SWITCH, ANDROID_SWITCH, or VEHICLE_REQUEST) and can be used to determine if the request succeeded or failed:\n1. When it succeeded, it's called when the Android user is in the unlocked state and the value of the current and target users ids in the response are the same. This would be equivalent to receiving an Intent.ACTION_USER_UNLOCKED in an Android app. 2. When it failed it's called right away and the value of the current and target users ids in the response are different (as the current user didn't change to the target). 3. If a new switch request is made before the HAL responded to the previous one or before the user was unlocked, then the ANDROID_POST_SWITCH request is not made. For example, the driver could accidentally switch to the wrong user which has lock credentials, then switch to the right one before entering the credentials.\nThe HAL can update its internal state once it receives this request, but it doesn't need to reply back to the Android System.\nRequest: the first N values as defined by INITIAL_USER_INFO (where the request-specific value at index 1 is SwitchUserMessageType::ANDROID_POST_SWITCH), then 2 more values for the target user id (i.e., the Android user id that was requested to be switched to) and its flags (as defined by  UserFlags).\nResponse: none.\nExample: see VEHICLE_REQUEST section above."
             },
             {
                 "name": "CREATE_USER",
-                "value": 299896585
+                "value": 299896585,
+                "description": "Called by the Android System after an Android user was created.\nThe HAL can use this property to create its equivalent user.\nThis is an async request: Android makes the request by setting a VehiclePropValue, and HAL must respond with a property change indicating whether the request succeeded or failed. If it failed, the Android system will remove the user.\nThe format of the request is defined by CreateUserRequest and the format of the response by CreateUserResponse.\nFor example, if system had 2 users (0 and 10) and a 3rd one (which is an ephemeral guest) was created, the request would be:\nint32[0]: 42  \/\/ request id int32[1]: 11  \/\/ Android id of the created user int32[2]: 6   \/\/ Android flags (ephemeral guest) of the created user int32[3]: 10  \/\/ current user int32[4]: 0   \/\/ current user flags (none) int32[5]: 3   \/\/ number of users int32[6]: 0   \/\/ 1st user (user 0) int32[7]: 0   \/\/ 1st user flags (none) int32[8]: 10  \/\/ 2nd user (user 10) int32[9]: 0   \/\/ 2nd user flags (none) int32[19]: 11 \/\/ 3rd user (user 11) int32[11]: 6  \/\/ 3rd user flags (ephemeral guest) string: \"ElGuesto\" \/\/ name of the new user\nThen if the request succeeded, the HAL would return:\nint32[0]: 42  \/\/ request id int32[1]: 1   \/\/ CreateUserStatus::SUCCESS\nBut if it failed:\nint32[0]: 42  \/\/ request id int32[1]: 2   \/\/ CreateUserStatus::FAILURE string: \"D'OH!\" \/\/ The meaning is a blackbox - it's passed to the caller (like Settings UI), \/\/ which in turn can take the proper action."
             },
             {
                 "name": "REMOVE_USER",
-                "value": 299896586
+                "value": 299896586,
+                "description": "Called by the Android System after an Android user was removed.\nThe HAL can use this property to remove its equivalent user.\nThis is write-only call - the Android System is not expecting a reply from the HAL. Hence, this request should not fail - if the equivalent HAL user cannot be removed, then HAL should mark it as inactive or recover in some other way.\nThe request is made by setting the VehiclePropValue with the contents defined by RemoveUserRequest.\nFor example, if system had 3 users (0, 10, and 11) and user 11 was removed, the request would be:\nint32[0]: 42  \/\/ request id int32[1]: 11  \/\/ (Android user id of the removed user) int32[2]: 0   \/\/ (Android user flags of the removed user) int32[3]: 10  \/\/ current user int32[4]: 0   \/\/ current user flags (none) int32[5]: 2   \/\/ number of users int32[6]: 0   \/\/ 1st user (user 0) int32[7]: 0   \/\/ 1st user flags (none) int32[8]: 10  \/\/ 2nd user (user 10) int32[9]: 0   \/\/ 2nd user flags (none)"
             },
             {
                 "name": "USER_IDENTIFICATION_ASSOCIATION",
-                "value": 299896587
+                "value": 299896587,
+                "description": "Property used to associate (or query the association) the current user with vehicle-specific identification mechanisms (such as key FOB).\nThis is an optional user management property - the OEM could still support user management without defining it. In fact, this property could be used without supporting the core user-related functions described on INITIAL_USER_INFO.\nTo query the association, the Android system gets the property, passing a VehiclePropValue containing the types of associations are being queried, as defined by UserIdentificationGetRequest. The HAL must return right away, returning a VehiclePropValue with a UserIdentificationResponse. Notice that user identification should have already happened while system is booting up and the VHAL implementation should only return the already identified association (like the key FOB used to unlock the car), instead of starting a new association from the get call.\nTo associate types, the Android system sets the property, passing a VehiclePropValue containing the types and values of associations being set, as defined by the UserIdentificationSetRequest. The HAL will then use a property change event (whose VehiclePropValue is defined by UserIdentificationResponse) indicating the current status of the types after the request.\nFor example, to query if the current user (10) is associated with the FOB that unlocked the car and a custom mechanism provided by the OEM, the request would be:\nint32[0]: 42  \/\/ request id int32[1]: 10  (Android user id) int32[2]: 0   (Android user flags) int32[3]: 2   (number of types queried) int32[4]: 1   (1st type queried, UserIdentificationAssociationType::KEY_FOB) int32[5]: 101 (2nd type queried, UserIdentificationAssociationType::CUSTOM_1)\nIf the user is associated with the FOB but not with the custom mechanism, the response would be:\nint32[0]: 42  \/\/ request id int32[1]: 2   (number of associations in the response) int32[2]: 1   (1st type: UserIdentificationAssociationType::KEY_FOB) int32[3]: 2   (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER) int32[4]: 101 (2st type: UserIdentificationAssociationType::CUSTOM_1) int32[5]: 4   (2nd value: UserIdentificationAssociationValue::NOT_ASSOCIATED_ANY_USER)\nThen to associate the user with the custom mechanism, a set request would be made:\nint32[0]: 43  \/\/ request id int32[1]: 10  (Android user id) int32[2]: 0   (Android user flags) int32[3]: 1   (number of associations being set) int32[4]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1) int32[5]: 1   (1st value: UserIdentificationAssociationSetValue::ASSOCIATE_CURRENT_USER)\nIf the request succeeded, the response would be simply:\nint32[0]: 43  \/\/ request id int32[1]: 1   (number of associations in the response) int32[2]: 101 (1st type: UserIdentificationAssociationType::CUSTOM_1) int32[3]: 1   (1st value: UserIdentificationAssociationValue::ASSOCIATED_CURRENT_USER)\nNotice that the set request adds associations, but doesn't remove the existing ones. In the example above, the end state would be 2 associations (FOB and CUSTOM_1). If we wanted to associate the user with just CUSTOM_1 but not FOB, then the request should have been:\nint32[0]: 43  \/\/ request id int32[1]: 10  (Android user id) int32[2]: 2   (number of types set) int32[3]: 1   (1st type: UserIdentificationAssociationType::KEY_FOB) int32[4]: 2   (1st value: UserIdentificationAssociationValue::DISASSOCIATE_CURRENT_USER) int32[5]: 101 (2nd type: UserIdentificationAssociationType::CUSTOM_1) int32[6]: 1   (2nd value: UserIdentificationAssociationValue::ASSOCIATE_CURRENT_USER)"
             },
             {
                 "name": "Enable\/request an EVS service.",
-                "value": 289476368
+                "value": 289476368,
+                "description": "Enable\/request an EVS service.\nThe property provides a generalized way to trigger EVS services.  VHAL should use this property to request Android to start or stop EVS service.\nint32Values[0] = a type of the EVS service. The value must be one of enums in EvsServiceType. int32Values[1] = the state of the EVS service. The value must be one of enums in EvsServiceState.\nFor example, to enable rear view EVS service, android side can set the property value as [EvsServiceType::REAR_VIEW, EvsServiceState::ON]."
             },
             {
                 "name": "POWER_POLICY_REQ",
-                "value": 286265121
+                "value": 286265121,
+                "description": "Defines a request to apply power policy.\nVHAL sets this property to change car power policy. Car power policy service subscribes to this property and actually changes the power policy. The request is made by setting the VehiclePropValue with the ID of a power policy which is defined at \/vendor\/etc\/automotive\/power_policy.xml. If the given ID is not defined, car power policy service ignores the request and the current power policy is maintained.\nstring: \"sample_policy_id\" \/\/ power policy ID"
             },
             {
                 "name": "POWER_POLICY_GROUP_REQ",
-                "value": 286265122
+                "value": 286265122,
+                "description": "Defines a request to set the power polic group used to decide a default power policy per power status transition.\nVHAL sets this property with the ID of a power policy group in order to set the default power policy applied at power status transition. Power policy groups are defined at \/vendor\/etc\/power_policy.xml. If the given ID is not defined, car power policy service ignores the request. Car power policy service subscribes to this property and sets the power policy group. The actual application of power policy takes place when the system power status changes and there is a valid mapped power policy for the new power status.\nstring: \"sample_policy_group_id\" \/\/ power policy group ID"
             },
             {
                 "name": "CURRENT_POWER_POLICY",
-                "value": 286265123
+                "value": 286265123,
+                "description": "Notifies the current power policy to VHAL layer.\nCar power policy service sets this property when the current power policy is changed.\nstring: \"sample_policy_id\" \/\/ power policy ID"
             },
             {
                 "name": "WATCHDOG_ALIVE",
-                "value": 290459441
+                "value": 290459441,
+                "description": "Defines an event that car watchdog updates to tell it's alive.\nCar watchdog sets this property to system uptime in milliseconds at every 3 second. During the boot, the update may take longer time."
             },
             {
                 "name": "WATCHDOG_TERMINATED_PROCESS",
-                "value": 299896626
+                "value": 299896626,
+                "description": "Defines a process terminated by car watchdog and the reason of termination.\nint32Values[0]: 1         \/\/ ProcessTerminationReason showing why a process is terminated. string: \"\/system\/bin\/log\" \/\/ Process execution command."
             },
             {
                 "name": "VHAL_HEARTBEAT",
-                "value": 290459443
+                "value": 290459443,
+                "description": "Defines an event that VHAL signals to car watchdog as a heartbeat.\nIf VHAL supports this property, VHAL should write system uptime to this property at every 3 second. Car watchdog subscribes to this property and checks if the property is updated at every 3 second. With the buffer time of 3 second, car watchdog waits for a heart beat to be signaled up to 6 seconds from the last heart beat. If it isn’t, car watchdog considers VHAL unhealthy and terminates it. If this property is not supported by VHAL, car watchdog doesn't check VHAL health status."
             },
             {
                 "name": "CLUSTER_SWITCH_UI",
-                "value": 289410868
+                "value": 289410868,
+                "description": "Starts the ClusterUI in cluster display.\nint32: the type of ClusterUI to show 0 indicates ClusterHome, that is a home screen of cluster display, and provides the default UI and a kind of launcher functionality for cluster display. the other values are followed by OEM's definition."
             },
             {
                 "name": "CLUSTER_DISPLAY_STATE",
-                "value": 289476405
+                "value": 289476405,
+                "description": "Changes the state of the cluster display.\nBounds: the area to render the cluster Activity. Inset: the area which Activity should avoid from placing any important information.\nint32[0]: on\/off: 0 - off, 1 - on, -1 - don't care int32[1]: Bounds - left: positive number - left position in pixels -1 - don't care (should set all Bounds fields) int32[2]: Bounds - top:    same format with 'left' int32[3]: Bounds - right:  same format with 'left' int32[4]: Bounds - bottom: same format with 'left' int32[5]: Inset - left: positive number - actual left inset value in pixels -1 - don't care (should set \"don't care\" all Inset fields) int32[6]: Inset - top:    same format with 'left' int32[7]: Inset - right:  same format with 'left' int32[8]: Inset - bottom: same format with 'left'"
             },
             {
                 "name": "CLUSTER_REPORT_STATE",
-                "value": 299896630
+                "value": 299896630,
+                "description": "Reports the current display state and ClusterUI state.\nClusterHome will send this message when it handles CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE.\nIn addition, ClusterHome should send this message when it starts for the first time. When ClusterOS receives this message and if the internal expectation is different with the received message, then it should send CLUSTER_SWITCH_UI, CLUSTER_DISPLAY_STATE again to match the state.\nint32[0]: on\/off: 0 - off, 1 - on int32[1]: Bounds - left int32[2]: Bounds - top int32[3]: Bounds - right int32[4]: Bounds - bottom int32[5]: Inset - left int32[6]: Inset - top int32[7]: Inset - right int32[8]: Inset - bottom int32[9]: the type of ClusterUI in the fullscreen or main screen. 0 indicates ClusterHome. the other values are followed by OEM's definition. int32[10]: the type of ClusterUI in sub screen if the currently two UIs are shown. -1 indicates the area isn't used any more. bytes: the array to represent the availability of ClusterUI. 0 indicates non-available and 1 indicates available. For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL, and it only supports CALL UI only when the cellular network is available. Then, if the nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0]."
             },
             {
                 "name": "CLUSTER_REQUEST_DISPLAY",
-                "value": 289410871
+                "value": 289410871,
+                "description": "Requests to change the cluster display state to show some ClusterUI.\nWhen the current display state is off and ClusterHome sends this message to ClusterOS to request to turn the display on to show some specific ClusterUI. ClusterOS should response this with CLUSTER_DISPLAY_STATE.\nint32: the type of ClusterUI to show"
             },
             {
                 "name": "CLUSTER_NAVIGATION_STATE",
-                "value": 292556600
+                "value": 292556600,
+                "description": "Informs the current navigation state.\nbytes: the serialized message of NavigationStateProto."
             },
             {
                 "name": "ELECTRONIC_TOLL_COLLECTION_CARD_TYPE",
@@ -1006,7 +1212,8 @@
                 "data_enums": [
                     "ElectronicTollCollectionCardType"
                 ],
-                "data_enum": "ElectronicTollCollectionCardType"
+                "data_enum": "ElectronicTollCollectionCardType",
+                "description": "Electronic Toll Collection card type.\nThis property indicates the type of ETC card in this vehicle. If the head unit is aware of an ETC card attached to the vehicle, this property should return the type of card attached; otherwise, this property should be UNAVAILABLE."
             },
             {
                 "name": "ELECTRONIC_TOLL_COLLECTION_CARD_STATUS",
@@ -1014,7 +1221,8 @@
                 "data_enums": [
                     "ElectronicTollCollectionCardStatus"
                 ],
-                "data_enum": "ElectronicTollCollectionCardStatus"
+                "data_enum": "ElectronicTollCollectionCardStatus",
+                "description": "Electronic Toll Collection card status.\nThis property indicates the status of ETC card in this vehicle. If the head unit is aware of an ETC card attached to the vehicle, ELECTRONIC_TOLL_COLLECTION_CARD_TYPE gives that status of the card; otherwise, this property should be UNAVAILABLE."
             },
             {
                 "name": "Front fog lights state",
@@ -1022,7 +1230,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Front fog lights state\nReturn the current state of the front fog lights. Only one of FOG_LIGHTS_STATE or FRONT_FOG_LIGHTS_STATE must be implemented. Please refer to the documentation on FOG_LIGHTS_STATE for more information."
             },
             {
                 "name": "Front fog lights switch",
@@ -1030,7 +1239,8 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Front fog lights switch\nThe setting that the user wants. Only one of FOG_LIGHTS_SWITCH or FRONT_FOG_LIGHTS_SWITCH must be implemented. Please refer to the documentation on FOG_LIGHTS_SWITCH for more information.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Rear fog lights state",
@@ -1038,7 +1248,8 @@
                 "data_enums": [
                     "VehicleLightState"
                 ],
-                "data_enum": "VehicleLightState"
+                "data_enum": "VehicleLightState",
+                "description": "Rear fog lights state\nReturn the current state of the rear fog lights. Only one of FOG_LIGHTS_STATE or REAR_FOG_LIGHTS_STATE must be implemented. Please refer to the documentation on FOG_LIGHTS_STATE for more information."
             },
             {
                 "name": "Rear fog lights switch",
@@ -1046,15 +1257,18 @@
                 "data_enums": [
                     "VehicleLightSwitch"
                 ],
-                "data_enum": "VehicleLightSwitch"
+                "data_enum": "VehicleLightSwitch",
+                "description": "Rear fog lights switch\nThe setting that the user wants. Only one of FOG_LIGHTS_SWITCH or REAR_FOG_LIGHTS_SWITCH must be implemented. Please refer to the documentation on FOG_LIGHTS_SWITCH for more information.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EV_CHARGE_CURRENT_DRAW_LIMIT",
-                "value": 291508031
+                "value": 291508031,
+                "description": "Indicates the maximum current draw threshold for charging set by the user\nconfigArray[0] is used to specify the max current draw allowed by the vehicle in Amperes.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EV_CHARGE_PERCENT_LIMIT",
-                "value": 291508032
+                "value": 291508032,
+                "description": "Indicates the maximum charge percent threshold set by the user\nReturns a float value from 0 to 100.\nconfigArray is used to specify the valid values. For example, if the vehicle supports the following charge percent limit values: [20, 40, 60, 80, 100] then the configArray should be {20, 40, 60, 80, 100} If the configArray is empty then all values from 0 to 100 must be valid.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Charging state of the car",
@@ -1062,15 +1276,18 @@
                 "data_enums": [
                     "EvChargeState"
                 ],
-                "data_enum": "EvChargeState"
+                "data_enum": "EvChargeState",
+                "description": "Charging state of the car\nReturns the current charging state of the car.\nIf the vehicle has a target charge percentage other than 100, this property must return EvChargeState::STATE_FULLY_CHARGED when the battery charge level has reached the target level. See EV_CHARGE_PERCENT_LIMIT for more context."
             },
             {
                 "name": "EV_CHARGE_SWITCH",
-                "value": 287313730
+                "value": 287313730,
+                "description": "Start or stop charging the EV battery\nThe setting that the user wants. Setting this property to true starts the battery charging and setting to false stops charging.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EV_CHARGE_TIME_REMAINING",
-                "value": 289410883
+                "value": 289410883,
+                "description": "Estimated charge time remaining in seconds\nReturns 0 if the vehicle is not charging."
             },
             {
                 "name": "EV_REGENERATIVE_BRAKING_STATE",
@@ -1078,7 +1295,8 @@
                 "data_enums": [
                     "EvRegenerativeBrakingState"
                 ],
-                "data_enum": "EvRegenerativeBrakingState"
+                "data_enum": "EvRegenerativeBrakingState",
+                "description": "Regenerative braking or one-pedal drive setting of the car\nReturns the current setting associated with the regenerative braking setting in the car\nIf the OEM requires more setting than those provided in EvRegenerativeBrakingState, the EV_BRAKE_REGENERATION_LEVEL property can be used instead, which provides a more granular way of providing the same information."
             },
             {
                 "name": "TRAILER_PRESENT",
@@ -1086,11 +1304,13 @@
                 "data_enums": [
                     "TrailerState"
                 ],
-                "data_enum": "TrailerState"
+                "data_enum": "TrailerState",
+                "description": "Indicates if there is a trailer present or not.\nReturns the trailer state of the car."
             },
             {
                 "name": "VEHICLE_CURB_WEIGHT",
-                "value": 289410886
+                "value": 289410886,
+                "description": "Vehicle’s curb weight in kilograms.\nReturns the vehicle's curb weight in kilograms. Curb weight is the total weight of the vehicle with standard equipment and all necessary operating consumables such as motor oil,transmission oil, brake fluid, coolant, air conditioning refrigerant, and weight of fuel at nominal tank capacity, while not loaded with either passengers or cargo.\nconfigArray[0] is used to specify the vehicle’s gross weight in kilograms. The vehicle’s gross weight is the maximum operating weight of the vehicle as specified by the manufacturer including the vehicle's chassis, body, engine, engine fluids, fuel, accessories, driver, passengers and cargo but excluding that of any trailers."
             },
             {
                 "name": "GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT",
@@ -1098,11 +1318,13 @@
                 "data_enums": [
                     "GsrComplianceRequirementType"
                 ],
-                "data_enum": "GsrComplianceRequirementType"
+                "data_enum": "GsrComplianceRequirementType",
+                "description": "EU's General security regulation compliance requirement.\nReturns whether general security regulation compliance is required, if so, what type of requirement."
             },
             {
                 "name": "SUPPORTED_PROPERTY_IDS",
-                "value": 289476424
+                "value": 289476424,
+                "description": "(Deprecated) List of all supported property IDs.\nA list of all supported property IDs (including this property). This property is required for HIDL VHAL to work with large amount of vehicle prop configs where the getAllPropConfigs payload exceeds the binder limitation. This issue is fixed in AIDL version using LargeParcelable in getAllPropConfigs, so this property is deprecated.\nIn HIDL VHAL implementation, if the amount of data returned in getAllPropConfigs exceeds the binder limitation, vendor must support this property and return all the supported property IDs. Car service will divide this list into smaller sub lists and use getPropConfigs([ids]) to query the sub lists. The results will be merged together in Car Service.\nThe config array for this property must contain one int element which is the number of configs per getPropConfigs request by Car Service. This number must be small enough so that each getPropConfigs payload will not exceed binder limitation, however, a smaller number will cause more requests, which increase overhead to fetch all the configs."
             },
             {
                 "name": "SHUTDOWN_REQUEST",
@@ -1110,15 +1332,18 @@
                 "data_enums": [
                     "VehicleApPowerStateShutdownParam"
                 ],
-                "data_enum": "VehicleApPowerStateShutdownParam"
+                "data_enum": "VehicleApPowerStateShutdownParam",
+                "description": "Request the head unit to be shutdown.\n<p>This is required for executing a task when the head unit is powered off (remote task feature). After the head unit is powered-on to execute the task, the head unit should be shutdown. The head unit will send this message once the task is finished.\n<p>This is not for the case when a user wants to shutdown the head unit.\n<p>This usually involves telling a separate system outside the head unit (e.g. a power controller) to prepare shutting down the head unit.\n<p>Note that the external system must validate whether this request is valid by checking whether the vehicle is currently in use. If a user enters the vehicle after a SHUTDOWN_REQUEST is sent, then the system must ignore this request. It is recommended to store a VehicleInUse property in the power controller and exposes it through VEHICLE_IN_USE property. A shutdown request must be ignored if VehicleInUse is true.\n<p>If allowed, the external system will start sending a shutdown signal to the head unit, which will cause VHAL to send SHUTDOWN_PREPARE message to Android. Android will then start the shut down process by handling the message.\n<p>This property is only for issuing a request and only supports writing. Every time this property value is set, the request to shutdown will be issued no matter what the current property value is. The current property value is meaningless.\n<p>Since this property is write-only, subscribing is not allowed and no property change event will be generated.\n<p>The value to set indicates the shutdown option, it must be one of {@code VehicleApPowerStateShutdownParam}, e.g., VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY. This shutdown option might not be honored if the system doesn't support such option. In such case, an error will not be returned.\n<p>For configuration information, VehiclePropConfig.configArray must have bit flag combining values in {@code VehicleApPowerStateConfigFlag} to indicate which shutdown options are supported.\n<p>Returns error if failed to send the shutdown request to the other system."
             },
             {
                 "name": "VEHICLE_IN_USE",
-                "value": 287313738
+                "value": 287313738,
+                "description": "Whether the vehicle is currently in use.\n<p>In-use means a human user is present and is intended to use the vehicle. This doesn't necessarily means the human user is in the vehicle. For example, if the human user unlocks the vehicle remotely, the vehicle is considered in use.\n<p>If this property is supported:\n<p>Each time user powers on the vehicle or the system detects the user is present, VEHICLE_IN_USE must be set to true. Each time user powers off the vehicle or the system detects the user is not present, VEHICLE_IN_USE must be set to false.\n<p>This property is different than AP_POWER_BOOTUP_REASON in the sense that AP_POWER_BOOTUP_REASON is only set once during the system bootup. However, this property might change multiple times during a system bootup cycle.\n<p>For example, a device is currently not in use. The system bootup to execute a remote task. VEHICLE_IN_USE is false. While the remote task is executing, the user enters the vehicle and powers on the vehicle. VEHICLE_IN_USE is set to true. After a driving session, user powers off the vehicle, VEHICLE_IN_USE is set to false.\n<p>This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "CLUSTER_HEARTBEAT",
-                "value": 299896651
+                "value": 299896651,
+                "description": "Sends the heartbeat signal to ClusterOS.\nint64[0]: epochTimeNs int64[1]: the visibility of ClusterUI, 0 - invisible, 1 - visible bytes: the app specific metadata, this can be empty when ClusterHomeService use the heartbeat to deliver the change of the visibility."
             },
             {
                 "name": "VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL",
@@ -1126,7 +1351,8 @@
                 "data_enums": [
                     "VehicleAutonomousState"
                 ],
-                "data_enum": "VehicleAutonomousState"
+                "data_enum": "VehicleAutonomousState",
+                "description": "Current state of vehicle autonomy.\nDefines the level of autonomy currently engaged in the vehicle from the J3016_202104 revision of the SAE standard levels 0-5, with 0 representing no autonomy and 5 representing full driving automation. These levels should be used in accordance with the standards defined in https:\/\/www.sae.org\/standards\/content\/j3016_202104\/ and https:\/\/www.sae.org\/blog\/sae-j3016-update\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of VehicleAutonomousState are supported."
             },
             {
                 "name": "CAMERA_SERVICE_CURRENT_STATE",
@@ -1134,11 +1360,18 @@
                 "data_enums": [
                     "CameraServiceState"
                 ],
-                "data_enum": "CameraServiceState"
+                "data_enum": "CameraServiceState",
+                "description": "Reports current state of CarEvsService types.\nInforms other components of current state of each CarEvsService service type with values defined in CameraServiceState. CarEvsService will update this property whenever a service type transitions into a new state.\nint32[0]: Current state of REARVIEW service type. int32[1]: Current state of SURROUNDVIEW service type. int32[2]: Current state of FRONTVIEW service type. int32[3]: Current state of LEFTVIEW service type. int32[4]: Current state of RIGHTVIEW service type. int32[5]: Current state of DRIVERVIEW service type. int32[6]: Current state of FRONT_PASSENGERVIEW service type. int32[7]: Current state of REAR_PASSENGERVIEW service type."
+            },
+            {
+                "name": "PER_DISPLAY_MAX_BRIGHTNESS",
+                "value": 289476430,
+                "description": "Property to represent max brightness of the displays which are controlled separately.\nThis is only used if PER_DISPLAY_BRIGHTNESS is supported.\nThe display port uniquely identifies a physical connector on the device for display output, ranging from 0 to 255.\nint32Values[0] : display port number int32Values[1] : max brightness for display port number specified at int32Values[0] int32Values[2] : display port number int32Values[3] : max brightness for display port number specified at int32Values[2] ..."
             },
             {
                 "name": "AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
-                "value": 287313920
+                "value": 287313920,
+                "description": "Enable or disable Automatic Emergency Braking (AEB).\nSet true to enable AEB and false to disable AEB. When AEB is enabled, the ADAS system in the vehicle should be turned on and monitoring to avoid potential collisions. This property should apply for higher speed applications only. For enabling low speed automatic emergency braking, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED should be used.\nIn general, AUTOMATIC_EMERGENCY_BRAKING_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low, that information must be conveyed through the ErrorState values in the AUTOMATIC_EMERGENCY_BRAKING_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "AUTOMATIC_EMERGENCY_BRAKING_STATE",
@@ -1147,11 +1380,13 @@
                     "AutomaticEmergencyBrakingState",
                     "ErrorState"
                 ],
-                "data_enum": "AutomaticEmergencyBrakingState"
+                "data_enum": "AutomaticEmergencyBrakingState",
+                "description": "Automatic Emergency Braking (AEB) state.\nReturns the current state of AEB. This property must always return a valid state defined in AutomaticEmergencyBrakingState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead. This property should apply for higher speed applications only. For representing the state of the low speed automatic emergency braking system, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE should be used.\nIf AEB includes forward collision warnings before activating the brakes, those warnings must be surfaced through the Forward Collision Warning (FCW) properties.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both AutomaticEmergencyBrakingState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "FORWARD_COLLISION_WARNING_ENABLED",
-                "value": 287313922
+                "value": 287313922,
+                "description": "Enable or disable Forward Collision Warning (FCW).\nSet true to enable FCW and false to disable FCW. When FCW is enabled, the ADAS system in the vehicle should be turned on and monitoring for potential collisions.\nIn general, FORWARD_COLLISION_WARNING_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low, that information must be conveyed through the ErrorState values in the FORWARD_COLLISION_WARNING_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "FORWARD_COLLISION_WARNING_STATE",
@@ -1160,11 +1395,13 @@
                     "ForwardCollisionWarningState",
                     "ErrorState"
                 ],
-                "data_enum": "ForwardCollisionWarningState"
+                "data_enum": "ForwardCollisionWarningState",
+                "description": "Forward Collision Warning (FCW) state.\nReturns the current state of FCW. This property must always return a valid state defined in ForwardCollisionWarningState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both ForwardCollisionWarningState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "BLIND_SPOT_WARNING_ENABLED",
-                "value": 287313924
+                "value": 287313924,
+                "description": "Enable and disable Blind Spot Warning (BSW).\nSet true to enable BSW and false to disable BSW. When BSW is enabled, the ADAS system in the vehicle should be turned on and monitoring for objects in the vehicle’s blind spots.\nIn general, BLIND_SPOT_WARNING_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low, that information must be conveyed through the ErrorState values in the BLIND_SPOT_WARNING_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "BLIND_SPOT_WARNING_STATE",
@@ -1173,11 +1410,13 @@
                     "BlindSpotWarningState",
                     "ErrorState"
                 ],
-                "data_enum": "BlindSpotWarningState"
+                "data_enum": "BlindSpotWarningState",
+                "description": "Blind Spot Warning (BSW) state.\nReturns the current state of BSW. This property must always return a valid state defined in BlindSpotWarningState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nFor each supported area ID, the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both BlindSpotWarningState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "LANE_DEPARTURE_WARNING_ENABLED",
-                "value": 287313926
+                "value": 287313926,
+                "description": "Enable or disable Lane Departure Warning (LDW).\nSet true to enable LDW and false to disable LDW. When LDW is enabled, the ADAS system in the vehicle should be turned on and monitoring if the vehicle is approaching or crossing lane lines, in which case a warning will be given.\nIn general, LANE_DEPARTURE_WARNING_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low or too high, that information must be conveyed through the ErrorState values in the LANE_DEPARTURE_WARNING_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "LANE_DEPARTURE_WARNING_STATE",
@@ -1186,11 +1425,13 @@
                     "LaneDepartureWarningState",
                     "ErrorState"
                 ],
-                "data_enum": "LaneDepartureWarningState"
+                "data_enum": "LaneDepartureWarningState",
+                "description": "Lane Departure Warning (LDW) state.\nReturns the current state of LDW. This property must always return a valid state defined in LaneDepartureWarningState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both LaneDepartureWarningState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "LANE_KEEP_ASSIST_ENABLED",
-                "value": 287313928
+                "value": 287313928,
+                "description": "Enable or disable Lane Keep Assist (LKA).\nSet true to enable LKA and false to disable LKA. When LKA is enabled, the ADAS system in the vehicle should be turned on and monitoring if the driver unintentionally drifts toward or over the lane marking. If an unintentional lane departure is detected, the system applies steering control to return the vehicle into the current lane.\nThis is different from Lane Centering Assist (LCA) which, when activated, applies continuous steering control to keep the vehicle centered in the current lane.\nIn general, LANE_KEEP_ASSIST_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low or too high, that information must be conveyed through the ErrorState values in the LANE_KEEP_ASSIST_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Lane Keep Assist (LKA) state.",
@@ -1199,11 +1440,13 @@
                     "LaneKeepAssistState",
                     "ErrorState"
                 ],
-                "data_enum": "LaneKeepAssistState"
+                "data_enum": "LaneKeepAssistState",
+                "description": "Lane Keep Assist (LKA) state.\nReturns the current state of LKA. This property must always return a valid state defined in LaneKeepAssistState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nIf LKA includes lane departure warnings before applying steering corrections, those warnings must be surfaced through the Lane Departure Warning (LDW) properties.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both LaneKeepAssistState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "LANE_CENTERING_ASSIST_ENABLED",
-                "value": 287313930
+                "value": 287313930,
+                "description": "Enable or disable Lane Centering Assist (LCA).\nSet true to enable LCA and false to disable LCA. When LCA is enabled, the ADAS system in the vehicle should be turned on and waiting for an activation signal from the driver. Once the feature is activated, the ADAS system should be steering the vehicle to keep it centered in its current lane.\nThis is different from Lane Keep Assist (LKA) which monitors if the driver unintentionally drifts toward or over the lane marking. If an unintentional lane departure is detected, the system applies steering control to return the vehicle into the current lane.\nIn general, LANE_CENTERING_ASSIST_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low or too high, that information must be conveyed through the ErrorState values in the LANE_CENTERING_ASSIST_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "LANE_CENTERING_ASSIST_COMMAND",
@@ -1211,7 +1454,8 @@
                 "data_enums": [
                     "LaneCenteringAssistCommand"
                 ],
-                "data_enum": "LaneCenteringAssistCommand"
+                "data_enum": "LaneCenteringAssistCommand",
+                "description": "Lane Centering Assist (LCA) commands.\nCommands to activate and suspend LCA.\nWhen the command ACTIVATE from LaneCenteringAssistCommand is sent, LANE_CENTERING_ASSIST_STATE must be set to LaneCenteringAssistState#ACTIVATION_REQUESTED. When the ACTIVATE command succeeds, LANE_CENTERING_ASSIST_STATE must be set to LaneCenteringAssistState#ACTIVATED. When the command DEACTIVATE from LaneCenteringAssistCommand succeeds, LANE_CENTERING_ASSIST_STATE must be set to LaneCenteringAssistState#ENABLED.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues must be defined unless all enum values of LaneCenteringAssistCommand are supported.\nWhen this property is not available because LCA is disabled (i.e. LANE_CENTERING_ASSIST_ENABLED is false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If LANE_CENTERING_ASSIST_STATE is implemented and the state is set to an ErrorState value, then this property must return a StatusCode that aligns with the ErrorState value. For example, if LANE_CENTERING_ASSIST_STATE is set to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return StatusCode#NOT_AVAILABLE_SPEED_LOW."
             },
             {
                 "name": "LANE_CENTERING_ASSIST_STATE",
@@ -1220,11 +1464,13 @@
                     "LaneCenteringAssistState",
                     "ErrorState"
                 ],
-                "data_enum": "LaneCenteringAssistState"
+                "data_enum": "LaneCenteringAssistState",
+                "description": "Lane Centering Assist (LCA) state.\nReturns the current state of LCA. This property must always return a valid state defined in LaneCenteringAssistState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nIf LCA includes lane departure warnings, those warnings must be surfaced through the Lane Departure Warning (LDW) properties.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both LaneCenteringAssistState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "EMERGENCY_LANE_KEEP_ASSIST_ENABLED",
-                "value": 287313933
+                "value": 287313933,
+                "description": "Enable or disable Emergency Lane Keep Assist (ELKA).\nSet true to enable ELKA and false to disable ELKA. When ELKA is enabled, the ADAS system in the vehicle should be on and monitoring for unsafe lane changes by the driver. When an unsafe maneuver is detected, ELKA alerts the driver and applies steering corrections to keep the vehicle in its original lane.\nIn general, EMERGENCY_LANE_KEEP_ASSIST_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low, that information must be conveyed through the ErrorState values in the EMERGENCY_LANE_KEEP_ASSIST_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "EMERGENCY_LANE_KEEP_ASSIST_STATE",
@@ -1233,11 +1479,13 @@
                     "EmergencyLaneKeepAssistState",
                     "ErrorState"
                 ],
-                "data_enum": "EmergencyLaneKeepAssistState"
+                "data_enum": "EmergencyLaneKeepAssistState",
+                "description": "Emergency Lane Keep Assist (ELKA) state.\nReturns the current state of ELKA. Generally, this property should return a valid state defined in the EmergencyLaneKeepAssistState or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through ErrorState.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of EmergencyLaneKeepAssistState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "CRUISE_CONTROL_ENABLED",
-                "value": 287313935
+                "value": 287313935,
+                "description": "Enable or disable cruise control (CC).\nSet true to enable CC and false to disable CC. This property is shared by all forms of CruiseControlType(s).\nWhen CC is enabled, the ADAS system in the vehicle should be turned on and responding to commands.\nIn general, CRUISE_CONTROL_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low, that information must be conveyed through the ErrorState values in the CRUISE_CONTROL_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "CRUISE_CONTROL_TYPE",
@@ -1246,7 +1494,8 @@
                     "CruiseControlType",
                     "ErrorState"
                 ],
-                "data_enum": "CruiseControlType"
+                "data_enum": "CruiseControlType",
+                "description": "Current type of Cruise Control (CC).\nWhen CRUISE_CONTROL_ENABLED is true, this property returns the type of CC that is currently enabled (for example, standard CC, adaptive CC, predictive CC, etc.). Generally, this property should return a valid state defined in the CruiseControlType or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through ErrorState.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of CruiseControlType (including OTHER, which is not recommended) and ErrorState are supported.\nTrying to write CruiseControlType#OTHER or an ErrorState to this property will throw an IllegalArgumentException.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "CRUISE_CONTROL_STATE",
@@ -1255,7 +1504,8 @@
                     "CruiseControlState",
                     "ErrorState"
                 ],
-                "data_enum": "CruiseControlState"
+                "data_enum": "CruiseControlState",
+                "description": "Current state of Cruise Control (CC).\nThis property returns the current state of CC. Generally, this property should return a valid state defined in the CruiseControlState or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through ErrorState.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of CruiseControlState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "CRUISE_CONTROL_COMMAND",
@@ -1263,23 +1513,28 @@
                 "data_enums": [
                     "CruiseControlCommand"
                 ],
-                "data_enum": "CruiseControlCommand"
+                "data_enum": "CruiseControlCommand",
+                "description": "Write Cruise Control (CC) commands.\nSee CruiseControlCommand for the details about each supported command.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of CruiseControlState are supported. Any unsupported commands sent through this property must return StatusCode#INVALID_ARG.\nWhen this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE is implemented and the state is set to an ErrorState value, then this property must return a StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return StatusCode#NOT_AVAILABLE_SPEED_LOW."
             },
             {
                 "name": "CRUISE_CONTROL_TARGET_SPEED",
-                "value": 291508243
+                "value": 291508243,
+                "description": "Current target speed for Cruise Control (CC).\nOEMs should set the minFloatValue and maxFloatValue values for this property to define the min and max target speed values. These values must be non-negative.\nThe maxFloatValue represents the upper bound of the target speed. The minFloatValue represents the lower bound of the target speed.\nWhen this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE is implemented and the state is set to an ErrorState value, then this property must return a StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return StatusCode#NOT_AVAILABLE_SPEED_LOW."
             },
             {
                 "name": "ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP",
-                "value": 289411092
+                "value": 289411092,
+                "description": "Current target time gap for Adaptive Cruise Control (ACC) or Predictive Cruise Control in milliseconds.\nThis property should specify the target time gap to a leading vehicle. This gap is defined as the time to travel the distance between the leading vehicle's rear-most point to the ACC vehicle's front-most point. The actual time gap from a leading vehicle can be above or below this value.\nThe possible values to set for the target time gap should be specified in configArray in ascending order. All values must be positive. If the property is writable, all values must be writable.\nWhen this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE is implemented and the state is set to an ErrorState value, then this property must return a StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return StatusCode#NOT_AVAILABLE_SPEED_LOW.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE",
-                "value": 289411093
+                "value": 289411093,
+                "description": "Measured distance from leading vehicle when using Adaptive Cruise Control (ACC) or Predictive Cruise Control.\nReturns the measured distance in millimeters between the rear-most point of the leading vehicle and the front-most point of the ACC vehicle.\nThe maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. The minInt32Value should be 0. The maxInt32Value should be populated with the maximum range the distance sensor can support. This value should be non-negative.\nWhen no lead vehicle is detected (that is, when there is no leading vehicle or the leading vehicle is too far away for the sensor to detect), this property should return StatusCode.NOT_AVAILABLE.\nWhen this property is not available because CC is disabled (i.e. CRUISE_CONTROL_ENABLED is false), this property must return StatusCode#NOT_AVAILABLE_DISABLED. If CRUISE_CONTROL_STATE is implemented and the state is set to an ErrorState value, then this property must return a StatusCode that aligns with the ErrorState value. For example, if CRUISE_CONTROL_STATE is set to ErrorState#NOT_AVAILABLE_SPEED_LOW, then this property must return StatusCode#NOT_AVAILABLE_SPEED_LOW."
             },
             {
                 "name": "HANDS_ON_DETECTION_ENABLED",
-                "value": 287313942
+                "value": 287313942,
+                "description": "Enable or disable Hands On Detection (HOD).\nSet true to enable HOD and false to disable HOD. When HOD is enabled, a system inside the vehicle should be monitoring the presence of the driver's hands on the steering wheel and send a warning if it detects that the driver's hands are no longer on the steering wheel.\nIn general, HANDS_ON_DETECTION_ENABLED should always return true or false. If the feature is not available due to some temporary state, that information must be conveyed through the ErrorState values in the HANDS_ON_DETECTION_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "HANDS_ON_DETECTION_DRIVER_STATE",
@@ -1288,7 +1543,8 @@
                     "HandsOnDetectionDriverState",
                     "ErrorState"
                 ],
-                "data_enum": "HandsOnDetectionDriverState"
+                "data_enum": "HandsOnDetectionDriverState",
+                "description": "Hands On Detection (HOD) driver state.\nReturns whether the driver's hands are on the steering wheel. Generally, this property should return a valid state defined in the HandsOnDetectionDriverState or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through ErrorState.\nIf the vehicle wants to send a warning to the user because the driver's hands have been off the steering wheel for too long, the warning should be surfaced through HANDS_ON_DETECTION_WARNING.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both HandsOnDetectionDriverState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "HANDS_ON_DETECTION_WARNING",
@@ -1297,11 +1553,13 @@
                     "HandsOnDetectionWarning",
                     "ErrorState"
                 ],
-                "data_enum": "HandsOnDetectionWarning"
+                "data_enum": "HandsOnDetectionWarning",
+                "description": "Hands On Detection (HOD) warning.\nReturns whether a warning is being sent to the driver for having their hands off the wheel for too long a duration.\nGenerally, this property should return a valid state defined in HandsOnDetectionWarning or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through an ErrorState.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both HandsOnDetectionWarning (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED",
-                "value": 287313945
+                "value": 287313945,
+                "description": "Enable or disable driver drowsiness and attention monitoring.\nSet true to enable driver drowsiness and attention monitoring and false to disable driver drowsiness and attention monitoring. When driver drowsiness and attention monitoring is enabled, a system inside the vehicle should be monitoring the drowsiness and attention level of the driver and warn the driver if needed.\nIn general, DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED should always return true or false. If the feature is not available due to some temporary state, that information must be conveyed through the ErrorState values in the DRIVER_DROWSINESS_ATTENTION_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "DRIVER_DROWSINESS_ATTENTION_STATE",
@@ -1310,11 +1568,13 @@
                     "DriverDrowsinessAttentionState",
                     "ErrorState"
                 ],
-                "data_enum": "DriverDrowsinessAttentionState"
+                "data_enum": "DriverDrowsinessAttentionState",
+                "description": "Driver drowsiness and attention level state.\nReturns the current detected state of driver drowiness and attention level based on the Karolinska Sleepiness scale. If alternative measurement methods are used, the value should be translated to the Karolinska Sleepiness Scale equivalent.\nGenerally, this property should return a valid state defined in the DriverDrowsinessAttentionState or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through ErrorState.\nIf the vehicle is sending a warning to the user because the driver is too drowsy, the warning should be surfaced through {@link #DRIVER_DROWSINESS_ATTENTION_WARNING}.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both DriverDrowsinessAttentionState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED",
-                "value": 287313947
+                "value": 287313947,
+                "description": "Enable or disable driver drowsiness and attention warnings.\nSet true to enable driver drowsiness and attention warnings and false to disable driver drowsiness and attention warnings.\nWhen driver drowsiness and attention warnings are enabled, the driver drowsiness and attention monitoring system inside the vehicle should warn the driver when it detects the driver is drowsy or not attentive.\nIn general, DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED should always return true or false. If the feature is not available due to some temporary state, that information must be conveyed through the ErrorState values in the DRIVER_DROWSINESS_ATTENTION_WARNING property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "DRIVER_DROWSINESS_ATTENTION_WARNING",
@@ -1323,11 +1583,13 @@
                     "DriverDrowsinessAttentionWarning",
                     "ErrorState"
                 ],
-                "data_enum": "DriverDrowsinessAttentionWarning"
+                "data_enum": "DriverDrowsinessAttentionWarning",
+                "description": "Driver drowsiness and attention warning.\nReturns whether a warning is being sent to the driver for being drowsy or not attentive.\nGenerally, this property should return a valid state defined in DriverDrowsinessAttentionWarning or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through an ErrorState.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both DriverDrowsinessAttentionWarning (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "DRIVER_DISTRACTION_SYSTEM_ENABLED",
-                "value": 287313949
+                "value": 287313949,
+                "description": "Enable or disable driver distraction monitoring.\nSet true to enable driver distraction monitoring and false to disable driver distraction monitoring. When driver distraction monitoring is enabled, a system inside the vehicle should be monitoring the distraction level of the driver and warn the driver if needed.\nIn general, DRIVER_DISTRACTION_SYSTEM_ENABLED should always return true or false. If the feature is not available due to some temporary state, that information must be conveyed through the ErrorState values in the DRIVER_DISTRACTION_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Driver distraction state.",
@@ -1336,11 +1598,13 @@
                     "DriverDistractionState",
                     "ErrorState"
                 ],
-                "data_enum": "DriverDistractionState"
+                "data_enum": "DriverDistractionState",
+                "description": "Driver distraction state.\nReturns the current detected driver distraction state.\nGenerally, this property should return a valid state defined in the DriverDistractionState or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through ErrorState.\nIf the vehicle is sending a warning to the user because the driver is too distracted, the warning should be surfaced through {@link #DRIVER_DISTRACTION_WARNING}.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both DriverDistractionState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "DRIVER_DISTRACTION_WARNING_ENABLED",
-                "value": 287313951
+                "value": 287313951,
+                "description": "Enable or disable driver distraction warnings.\nSet true to enable driver distraction warnings and false to disable driver distraction warnings.\nWhen driver distraction warnings are enabled, the driver distraction monitoring system inside the vehicle should warn the driver when it detects the driver is distracted.\nIn general, DRIVER_DISTRACTION_WARNING_ENABLED should always return true or false. If the feature is not available due to some temporary state, that information must be conveyed through the ErrorState values in the DRIVER_DISTRACTION_WARNING property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "Driver distraction warning.",
@@ -1349,11 +1613,13 @@
                     "DriverDistractionWarning",
                     "ErrorState"
                 ],
-                "data_enum": "DriverDistractionWarning"
+                "data_enum": "DriverDistractionWarning",
+                "description": "Driver distraction warning.\nReturns whether a warning is being sent to the driver for being distracted.\nGenerally, this property should return a valid state defined in DriverDistractionWarning or ErrorState. For example, if the feature is not available due to some temporary state, that information should be conveyed through an ErrorState.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both DriverDistractionWarning (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "LOW_SPEED_COLLISION_WARNING_ENABLED",
-                "value": 287313953
+                "value": 287313953,
+                "description": "Enable or disable Low Speed Collision Warning.\nSet true to enable low speed collision warning and false to disable low speed collision warning. When low speed collision warning is enabled, the ADAS system in the vehicle should warn the driver of potential collisions at low speeds. This property is different from the pre-existing FORWARD_COLLISION_WARNING_ENABLED, which should apply to higher speed applications only. If the vehicle doesn't have a separate collision detection system for low speed environments, this property should not be implemented.\nIn general, LOW_SPEED_COLLISION_WARNING_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too high, that information must be conveyed through the ErrorState values in the LOW_SPEED_COLLISION_WARNING_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "LOW_SPEED_COLLISION_WARNING_STATE",
@@ -1362,11 +1628,13 @@
                     "LowSpeedCollisionWarningState",
                     "ErrorState"
                 ],
-                "data_enum": "LowSpeedCollisionWarningState"
+                "data_enum": "LowSpeedCollisionWarningState",
+                "description": "Low Speed Collision Warning state.\nReturns the current state of Low Speed Collision Warning. This property must always return a valid state defined in LowSpeedCollisionWarningState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead. This property is different from the pre-existing FORWARD_COLLISION_WARNING_STATE, which should apply to higher speed applications only. If the vehicle doesn't have a separate collision detection system for low speed environments, this property should not be implemented.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both LowSpeedCollisionWarningState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "CROSS_TRAFFIC_MONITORING_ENABLED",
-                "value": 287313955
+                "value": 287313955,
+                "description": "Enable or disable Cross Traffic Monitoring.\nSet true to enable Cross Traffic Monitoring and false to disable Cross Traffic Monitoring. When Cross Traffic Monitoring is enabled, the ADAS system in the vehicle should be turned on and monitoring for potential sideways collisions.\nIn general, CROSS_TRAFFIC_MONITORING_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too high, that information must be conveyed through the ErrorState values in the CROSS_TRAFFIC_MONITORING_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "CROSS_TRAFFIC_MONITORING_WARNING_STATE",
@@ -1375,11 +1643,13 @@
                     "CrossTrafficMonitoringWarningState",
                     "ErrorState"
                 ],
-                "data_enum": "CrossTrafficMonitoringWarningState"
+                "data_enum": "CrossTrafficMonitoringWarningState",
+                "description": "Cross Traffic Monitoring warning state.\nReturns the current state of Cross Traffic Monitoring Warning. This property must always return a valid state defined in CrossTrafficMonitoringWarningState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both CrossTrafficMonitoringWarningState (including OTHER, which is not recommended) and ErrorState are supported."
             },
             {
                 "name": "LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED",
-                "value": 287313957
+                "value": 287313957,
+                "description": "Enable or disable Low Speed Automatic Emergency Braking.\nSet true to enable Low Speed Automatic Emergency Braking or false to disable Low Speed Automatic Emergency Braking. When Low Speed Automatic Emergency Braking is enabled, the ADAS system in the vehicle should be turned on and monitoring to avoid potential collisions in low speed conditions. This property is different from the pre-existing AUTOMATIC_EMERGENCY_BRAKING_ENABLED, which should apply to higher speed applications only. If the vehicle doesn't have a separate collision avoidance system for low speed environments, this property should not be implemented.\nIn general, LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED should always return true or false. If the feature is not available due to some temporary state, such as the vehicle speed being too low, that information must be conveyed through the ErrorState values in the LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE property.\nThis property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to implement it as VehiclePropertyAccess.READ only."
             },
             {
                 "name": "LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE",
@@ -1388,12 +1658,13 @@
                     "LowSpeedAutomaticEmergencyBrakingState",
                     "ErrorState"
                 ],
-                "data_enum": "LowSpeedAutomaticEmergencyBrakingState"
+                "data_enum": "LowSpeedAutomaticEmergencyBrakingState",
+                "description": "Low Speed Automatic Emergency Braking state.\nReturns the current state of Low Speed Automatic Emergency Braking. This property must always return a valid state defined in LowSpeedAutomaticEmergencyBrakingState or ErrorState. It must not surface errors through StatusCode and must use the supported error states instead. This property is different from the pre-existing AUTOMATIC_EMERGENCY_BRAKING_STATE, which should apply to higher speed applications only. If the vehicle doesn't have a separate collision avoidance system for low speed environments, this property should not be implemented.\nIf Low Speed Automatic Emergency Braking includes collision warnings before activating the brakes, those warnings must be surfaced through use of LOW_SPEED_COLLISION_WARNING_ENABLED and LOW_SPEED_COLLISION_WARNING_STATE.\nFor the global area ID (0), the VehicleAreaConfig#supportedEnumValues array must be defined unless all states of both LowSpeedAutomaticEmergencyBrakingState (including OTHER, which is not recommended) and ErrorState are supported."
             }
         ]
     },
     {
-        "name": "LaneDepartureWarningState",
+        "name": "AutomaticEmergencyBrakingState",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
@@ -1401,21 +1672,21 @@
                 "value": 0
             },
             {
-                "name": "NO_WARNING",
+                "name": "ENABLED",
                 "value": 1
             },
             {
-                "name": "WARNING_LEFT",
+                "name": "ACTIVATED",
                 "value": 2
             },
             {
-                "name": "WARNING_RIGHT",
+                "name": "USER_OVERRIDE",
                 "value": 3
             }
         ]
     },
     {
-        "name": "HandsOnDetectionWarning",
+        "name": "BlindSpotWarningState",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
@@ -1433,6 +1704,194 @@
         ]
     },
     {
+        "name": "CameraServiceState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "UNAVAILABLE",
+                "value": 0
+            },
+            {
+                "name": "INACTIVE",
+                "value": 1
+            },
+            {
+                "name": "REQUESTED",
+                "value": 2
+            },
+            {
+                "name": "ACTIVE",
+                "value": 3
+            }
+        ]
+    },
+    {
+        "name": "CrossTrafficMonitoringWarningState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "NO_WARNING",
+                "value": 1
+            },
+            {
+                "name": "WARNING_FRONT_LEFT",
+                "value": 2
+            },
+            {
+                "name": "WARNING_FRONT_RIGHT",
+                "value": 3
+            },
+            {
+                "name": "WARNING_FRONT_BOTH",
+                "value": 4
+            },
+            {
+                "name": "WARNING_REAR_LEFT",
+                "value": 5
+            },
+            {
+                "name": "WARNING_REAR_RIGHT",
+                "value": 6
+            },
+            {
+                "name": "WARNING_REAR_BOTH",
+                "value": 7
+            }
+        ]
+    },
+    {
+        "name": "CruiseControlCommand",
+        "package": "android.hardware.automotive.vehicle",
+        "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
+            }
+        ]
+    },
+    {
+        "name": "CruiseControlState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "ENABLED",
+                "value": 1
+            },
+            {
+                "name": "ACTIVATED",
+                "value": 2
+            },
+            {
+                "name": "USER_OVERRIDE",
+                "value": 3
+            },
+            {
+                "name": "SUSPENDED",
+                "value": 4
+            },
+            {
+                "name": "FORCED_DEACTIVATION_WARNING",
+                "value": 5
+            }
+        ]
+    },
+    {
+        "name": "CruiseControlType",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "STANDARD",
+                "value": 1
+            },
+            {
+                "name": "ADAPTIVE",
+                "value": 2
+            },
+            {
+                "name": "PREDICTIVE",
+                "value": 3
+            }
+        ]
+    },
+    {
+        "name": "CustomInputType",
+        "package": "android.hardware.automotive.vehicle",
+        "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": "DriverDistractionState",
         "package": "android.hardware.automotive.vehicle",
         "values": [
@@ -1451,34 +1910,312 @@
         ]
     },
     {
-        "name": "VehicleTurnSignal",
+        "name": "DriverDistractionWarning",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
-                "name": "NONE",
+                "name": "OTHER",
                 "value": 0
             },
             {
-                "name": "RIGHT",
+                "name": "NO_WARNING",
                 "value": 1
             },
             {
-                "name": "LEFT",
+                "name": "WARNING",
                 "value": 2
             }
         ]
     },
     {
-        "name": "RotaryInputType",
+        "name": "DriverDrowsinessAttentionState",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
-                "name": "ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION",
+                "name": "OTHER",
                 "value": 0
             },
             {
-                "name": "ROTARY_INPUT_TYPE_AUDIO_VOLUME",
+                "name": "KSS_RATING_1_EXTREMELY_ALERT",
                 "value": 1
+            },
+            {
+                "name": "KSS_RATING_2_VERY_ALERT",
+                "value": 2
+            },
+            {
+                "name": "KSS_RATING_3_ALERT",
+                "value": 3
+            },
+            {
+                "name": "KSS_RATING_4_RATHER_ALERT",
+                "value": 4
+            },
+            {
+                "name": "KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY",
+                "value": 5
+            },
+            {
+                "name": "KSS_RATING_6_SOME_SLEEPINESS",
+                "value": 6
+            },
+            {
+                "name": "KSS_RATING_7_SLEEPY_NO_EFFORT",
+                "value": 7
+            },
+            {
+                "name": "KSS_RATING_8_SLEEPY_SOME_EFFORT",
+                "value": 8
+            },
+            {
+                "name": "KSS_RATING_9_VERY_SLEEPY",
+                "value": 9
+            }
+        ]
+    },
+    {
+        "name": "DriverDrowsinessAttentionWarning",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "NO_WARNING",
+                "value": 1
+            },
+            {
+                "name": "WARNING",
+                "value": 2
+            }
+        ]
+    },
+    {
+        "name": "ElectronicStabilityControlState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "ENABLED",
+                "value": 1
+            },
+            {
+                "name": "ACTIVATED",
+                "value": 2
+            }
+        ]
+    },
+    {
+        "name": "ElectronicTollCollectionCardStatus",
+        "package": "android.hardware.automotive.vehicle",
+        "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
+            }
+        ]
+    },
+    {
+        "name": "ElectronicTollCollectionCardType",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "UNKNOWN",
+                "value": 0
+            },
+            {
+                "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD",
+                "value": 1
+            },
+            {
+                "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2",
+                "value": 2
+            }
+        ]
+    },
+    {
+        "name": "EmergencyLaneKeepAssistState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "ENABLED",
+                "value": 1
+            },
+            {
+                "name": "WARNING_LEFT",
+                "value": 2
+            },
+            {
+                "name": "WARNING_RIGHT",
+                "value": 3
+            },
+            {
+                "name": "ACTIVATED_STEER_LEFT",
+                "value": 4
+            },
+            {
+                "name": "ACTIVATED_STEER_RIGHT",
+                "value": 5
+            },
+            {
+                "name": "USER_OVERRIDE",
+                "value": 6
+            }
+        ]
+    },
+    {
+        "name": "ErrorState",
+        "package": "android.hardware.automotive.vehicle",
+        "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
+            }
+        ]
+    },
+    {
+        "name": "EvChargeState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "UNKNOWN",
+                "value": 0
+            },
+            {
+                "name": "CHARGING",
+                "value": 1
+            },
+            {
+                "name": "FULLY_CHARGED",
+                "value": 2
+            },
+            {
+                "name": "NOT_CHARGING",
+                "value": 3
+            },
+            {
+                "name": "ERROR",
+                "value": 4
+            }
+        ]
+    },
+    {
+        "name": "EvConnectorType",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "UNKNOWN",
+                "value": 0
+            },
+            {
+                "name": "IEC_TYPE_1_AC",
+                "value": 1
+            },
+            {
+                "name": "IEC_TYPE_2_AC",
+                "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
+            }
+        ]
+    },
+    {
+        "name": "EvRegenerativeBrakingState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "UNKNOWN",
+                "value": 0
+            },
+            {
+                "name": "DISABLED",
+                "value": 1
+            },
+            {
+                "name": "PARTIALLY_ENABLED",
+                "value": 2
+            },
+            {
+                "name": "FULLY_ENABLED",
+                "value": 3
             }
         ]
     },
@@ -1505,19 +2242,19 @@
         ]
     },
     {
-        "name": "VehicleLightState",
+        "name": "ForwardCollisionWarningState",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
-                "name": "OFF",
+                "name": "OTHER",
                 "value": 0
             },
             {
-                "name": "ON",
+                "name": "NO_WARNING",
                 "value": 1
             },
             {
-                "name": "DAYTIME_RUNNING",
+                "name": "WARNING",
                 "value": 2
             }
         ]
@@ -1581,37 +2318,223 @@
         ]
     },
     {
-        "name": "VehicleIgnitionState",
+        "name": "GsrComplianceRequirementType",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
-                "name": "UNDEFINED",
+                "name": "GSR_COMPLIANCE_NOT_REQUIRED",
                 "value": 0
             },
             {
-                "name": "LOCK",
+                "name": "GSR_COMPLIANCE_REQUIRED_V1",
+                "value": 1
+            }
+        ]
+    },
+    {
+        "name": "HandsOnDetectionDriverState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "HANDS_ON",
                 "value": 1
             },
             {
-                "name": "OFF",
+                "name": "HANDS_OFF",
+                "value": 2
+            }
+        ]
+    },
+    {
+        "name": "HandsOnDetectionWarning",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "NO_WARNING",
+                "value": 1
+            },
+            {
+                "name": "WARNING",
+                "value": 2
+            }
+        ]
+    },
+    {
+        "name": "ImpactSensorLocation",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 1
+            },
+            {
+                "name": "FRONT",
                 "value": 2
             },
             {
-                "name": "ACC",
-                "value": 3
-            },
-            {
-                "name": "ON",
+                "name": "FRONT_LEFT_DOOR_SIDE",
                 "value": 4
             },
             {
-                "name": "START",
+                "name": "FRONT_RIGHT_DOOR_SIDE",
+                "value": 8
+            },
+            {
+                "name": "REAR_LEFT_DOOR_SIDE",
+                "value": 16
+            },
+            {
+                "name": "REAR_RIGHT_DOOR_SIDE",
+                "value": 32
+            },
+            {
+                "name": "REAR",
+                "value": 64
+            }
+        ]
+    },
+    {
+        "name": "LaneCenteringAssistCommand",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "ACTIVATE",
+                "value": 1
+            },
+            {
+                "name": "DEACTIVATE",
+                "value": 2
+            }
+        ]
+    },
+    {
+        "name": "LaneCenteringAssistState",
+        "package": "android.hardware.automotive.vehicle",
+        "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
             }
         ]
     },
     {
-        "name": "EvConnectorType",
+        "name": "LaneDepartureWarningState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "NO_WARNING",
+                "value": 1
+            },
+            {
+                "name": "WARNING_LEFT",
+                "value": 2
+            },
+            {
+                "name": "WARNING_RIGHT",
+                "value": 3
+            }
+        ]
+    },
+    {
+        "name": "LaneKeepAssistState",
+        "package": "android.hardware.automotive.vehicle",
+        "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
+            }
+        ]
+    },
+    {
+        "name": "LowSpeedAutomaticEmergencyBrakingState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "ENABLED",
+                "value": 1
+            },
+            {
+                "name": "ACTIVATED",
+                "value": 2
+            },
+            {
+                "name": "USER_OVERRIDE",
+                "value": 3
+            }
+        ]
+    },
+    {
+        "name": "LowSpeedCollisionWarningState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "NO_WARNING",
+                "value": 1
+            },
+            {
+                "name": "WARNING",
+                "value": 2
+            }
+        ]
+    },
+    {
+        "name": "PortLocationType",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
@@ -1619,52 +2542,42 @@
                 "value": 0
             },
             {
-                "name": "IEC_TYPE_1_AC",
+                "name": "FRONT_LEFT",
                 "value": 1
             },
             {
-                "name": "IEC_TYPE_2_AC",
+                "name": "FRONT_RIGHT",
                 "value": 2
             },
             {
-                "name": "IEC_TYPE_3_AC",
+                "name": "REAR_RIGHT",
                 "value": 3
             },
             {
-                "name": "IEC_TYPE_4_DC",
+                "name": "REAR_LEFT",
                 "value": 4
             },
             {
-                "name": "IEC_TYPE_1_CCS_DC",
+                "name": "FRONT",
                 "value": 5
             },
             {
-                "name": "IEC_TYPE_2_CCS_DC",
+                "name": "REAR",
                 "value": 6
+            }
+        ]
+    },
+    {
+        "name": "RotaryInputType",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION",
+                "value": 0
             },
             {
-                "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": "ROTARY_INPUT_TYPE_AUDIO_VOLUME",
+                "value": 1
             }
         ]
     },
@@ -1691,66 +2604,66 @@
         ]
     },
     {
-        "name": "DriverDrowsinessAttentionState",
+        "name": "VehicleAirbagLocation",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
                 "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "KSS_RATING_1_EXTREMELY_ALERT",
                 "value": 1
             },
             {
-                "name": "KSS_RATING_2_VERY_ALERT",
+                "name": "FRONT",
                 "value": 2
             },
             {
-                "name": "KSS_RATING_3_ALERT",
-                "value": 3
-            },
-            {
-                "name": "KSS_RATING_4_RATHER_ALERT",
+                "name": "KNEE",
                 "value": 4
             },
             {
-                "name": "KSS_RATING_5_NEITHER_ALERT_NOR_SLEEPY",
-                "value": 5
-            },
-            {
-                "name": "KSS_RATING_6_SOME_SLEEPINESS",
-                "value": 6
-            },
-            {
-                "name": "KSS_RATING_7_SLEEPY_NO_EFFORT",
-                "value": 7
-            },
-            {
-                "name": "KSS_RATING_8_SLEEPY_SOME_EFFORT",
+                "name": "LEFT_SIDE",
                 "value": 8
             },
             {
-                "name": "KSS_RATING_9_VERY_SLEEPY",
-                "value": 9
+                "name": "RIGHT_SIDE",
+                "value": 16
+            },
+            {
+                "name": "CURTAIN",
+                "value": 32
             }
         ]
     },
     {
-        "name": "DriverDistractionWarning",
+        "name": "VehicleApPowerStateShutdownParam",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "NO_WARNING",
+                "name": "SHUTDOWN_IMMEDIATELY",
                 "value": 1
             },
             {
-                "name": "WARNING",
+                "name": "CAN_SLEEP",
                 "value": 2
+            },
+            {
+                "name": "SHUTDOWN_ONLY",
+                "value": 3
+            },
+            {
+                "name": "SLEEP_IMMEDIATELY",
+                "value": 4
+            },
+            {
+                "name": "HIBERNATE_IMMEDIATELY",
+                "value": 5
+            },
+            {
+                "name": "CAN_HIBERNATE",
+                "value": 6
+            },
+            {
+                "name": "EMERGENCY_SHUTDOWN",
+                "value": 7
             }
         ]
     },
@@ -1801,6 +2714,176 @@
         ]
     },
     {
+        "name": "VehicleAutonomousState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "LEVEL_0",
+                "value": 0
+            },
+            {
+                "name": "LEVEL_1",
+                "value": 1
+            },
+            {
+                "name": "LEVEL_2",
+                "value": 2
+            },
+            {
+                "name": "LEVEL_3",
+                "value": 3
+            },
+            {
+                "name": "LEVEL_4",
+                "value": 4
+            },
+            {
+                "name": "LEVEL_5",
+                "value": 5
+            }
+        ]
+    },
+    {
+        "name": "VehicleGear",
+        "package": "android.hardware.automotive.vehicle",
+        "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
+            }
+        ]
+    },
+    {
+        "name": "VehicleHvacFanDirection",
+        "package": "android.hardware.automotive.vehicle",
+        "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": "VehicleIgnitionState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "UNDEFINED",
+                "value": 0
+            },
+            {
+                "name": "LOCK",
+                "value": 1
+            },
+            {
+                "name": "OFF",
+                "value": 2
+            },
+            {
+                "name": "ACC",
+                "value": 3
+            },
+            {
+                "name": "ON",
+                "value": 4
+            },
+            {
+                "name": "START",
+                "value": 5
+            }
+        ]
+    },
+    {
+        "name": "VehicleLightState",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "OFF",
+                "value": 0
+            },
+            {
+                "name": "ON",
+                "value": 1
+            },
+            {
+                "name": "DAYTIME_RUNNING",
+                "value": 2
+            }
+        ]
+    },
+    {
         "name": "VehicleLightSwitch",
         "package": "android.hardware.automotive.vehicle",
         "values": [
@@ -1823,260 +2906,6 @@
         ]
     },
     {
-        "name": "WindshieldWipersSwitch",
-        "package": "android.hardware.automotive.vehicle",
-        "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
-            }
-        ]
-    },
-    {
-        "name": "CrossTrafficMonitoringWarningState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "NO_WARNING",
-                "value": 1
-            },
-            {
-                "name": "WARNING_FRONT_LEFT",
-                "value": 2
-            },
-            {
-                "name": "WARNING_FRONT_RIGHT",
-                "value": 3
-            },
-            {
-                "name": "WARNING_FRONT_BOTH",
-                "value": 4
-            },
-            {
-                "name": "WARNING_REAR_LEFT",
-                "value": 5
-            },
-            {
-                "name": "WARNING_REAR_RIGHT",
-                "value": 6
-            },
-            {
-                "name": "WARNING_REAR_BOTH",
-                "value": 7
-            }
-        ]
-    },
-    {
-        "name": "LaneCenteringAssistCommand",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "ACTIVATE",
-                "value": 1
-            },
-            {
-                "name": "DEACTIVATE",
-                "value": 2
-            }
-        ]
-    },
-    {
-        "name": "VehicleSeatOccupancyState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "UNKNOWN",
-                "value": 0
-            },
-            {
-                "name": "VACANT",
-                "value": 1
-            },
-            {
-                "name": "OCCUPIED",
-                "value": 2
-            }
-        ]
-    },
-    {
-        "name": "ErrorState",
-        "package": "android.hardware.automotive.vehicle",
-        "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
-            }
-        ]
-    },
-    {
-        "name": "BlindSpotWarningState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "NO_WARNING",
-                "value": 1
-            },
-            {
-                "name": "WARNING",
-                "value": 2
-            }
-        ]
-    },
-    {
-        "name": "WindshieldWipersState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "OFF",
-                "value": 1
-            },
-            {
-                "name": "ON",
-                "value": 2
-            },
-            {
-                "name": "SERVICE",
-                "value": 3
-            }
-        ]
-    },
-    {
-        "name": "VehicleAirbagLocation",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 1
-            },
-            {
-                "name": "FRONT",
-                "value": 2
-            },
-            {
-                "name": "KNEE",
-                "value": 4
-            },
-            {
-                "name": "LEFT_SIDE",
-                "value": 8
-            },
-            {
-                "name": "RIGHT_SIDE",
-                "value": 16
-            },
-            {
-                "name": "CURTAIN",
-                "value": 32
-            }
-        ]
-    },
-    {
-        "name": "DriverDrowsinessAttentionWarning",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "NO_WARNING",
-                "value": 1
-            },
-            {
-                "name": "WARNING",
-                "value": 2
-            }
-        ]
-    },
-    {
         "name": "VehicleOilLevel",
         "package": "android.hardware.automotive.vehicle",
         "values": [
@@ -2103,19 +2932,37 @@
         ]
     },
     {
-        "name": "ForwardCollisionWarningState",
+        "name": "VehicleSeatOccupancyState",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
-                "name": "OTHER",
+                "name": "UNKNOWN",
                 "value": 0
             },
             {
-                "name": "NO_WARNING",
+                "name": "VACANT",
                 "value": 1
             },
             {
-                "name": "WARNING",
+                "name": "OCCUPIED",
+                "value": 2
+            }
+        ]
+    },
+    {
+        "name": "VehicleTurnSignal",
+        "package": "android.hardware.automotive.vehicle",
+        "values": [
+            {
+                "name": "NONE",
+                "value": 0
+            },
+            {
+                "name": "RIGHT",
+                "value": 1
+            },
+            {
+                "name": "LEFT",
                 "value": 2
             }
         ]
@@ -2263,37 +3110,7 @@
         ]
     },
     {
-        "name": "VehicleHvacFanDirection",
-        "package": "android.hardware.automotive.vehicle",
-        "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": "LowSpeedCollisionWarningState",
+        "name": "WindshieldWipersState",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
@@ -2301,628 +3118,82 @@
                 "value": 0
             },
             {
-                "name": "NO_WARNING",
+                "name": "OFF",
                 "value": 1
             },
             {
-                "name": "WARNING",
+                "name": "ON",
                 "value": 2
+            },
+            {
+                "name": "SERVICE",
+                "value": 3
             }
         ]
     },
     {
-        "name": "CruiseControlCommand",
+        "name": "WindshieldWipersSwitch",
         "package": "android.hardware.automotive.vehicle",
         "values": [
             {
-                "name": "ACTIVATE",
+                "name": "OTHER",
+                "value": 0
+            },
+            {
+                "name": "OFF",
                 "value": 1
             },
             {
-                "name": "SUSPEND",
+                "name": "MIST",
                 "value": 2
             },
             {
-                "name": "INCREASE_TARGET_SPEED",
+                "name": "INTERMITTENT_LEVEL_1",
                 "value": 3
             },
             {
-                "name": "DECREASE_TARGET_SPEED",
+                "name": "INTERMITTENT_LEVEL_2",
                 "value": 4
             },
             {
-                "name": "INCREASE_TARGET_TIME_GAP",
+                "name": "INTERMITTENT_LEVEL_3",
                 "value": 5
             },
             {
-                "name": "DECREASE_TARGET_TIME_GAP",
-                "value": 6
-            }
-        ]
-    },
-    {
-        "name": "ElectronicStabilityControlState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "ENABLED",
-                "value": 1
-            },
-            {
-                "name": "ACTIVATED",
-                "value": 2
-            }
-        ]
-    },
-    {
-        "name": "EvRegenerativeBrakingState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "UNKNOWN",
-                "value": 0
-            },
-            {
-                "name": "DISABLED",
-                "value": 1
-            },
-            {
-                "name": "PARTIALLY_ENABLED",
-                "value": 2
-            },
-            {
-                "name": "FULLY_ENABLED",
-                "value": 3
-            }
-        ]
-    },
-    {
-        "name": "LowSpeedAutomaticEmergencyBrakingState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "ENABLED",
-                "value": 1
-            },
-            {
-                "name": "ACTIVATED",
-                "value": 2
-            },
-            {
-                "name": "USER_OVERRIDE",
-                "value": 3
-            }
-        ]
-    },
-    {
-        "name": "LaneCenteringAssistState",
-        "package": "android.hardware.automotive.vehicle",
-        "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
-            }
-        ]
-    },
-    {
-        "name": "VehicleGear",
-        "package": "android.hardware.automotive.vehicle",
-        "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
-            }
-        ]
-    },
-    {
-        "name": "ElectronicTollCollectionCardType",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "UNKNOWN",
-                "value": 0
-            },
-            {
-                "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD",
-                "value": 1
-            },
-            {
-                "name": "JP_ELECTRONIC_TOLL_COLLECTION_CARD_V2",
-                "value": 2
-            }
-        ]
-    },
-    {
-        "name": "VehicleApPowerStateShutdownParam",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "SHUTDOWN_IMMEDIATELY",
-                "value": 1
-            },
-            {
-                "name": "CAN_SLEEP",
-                "value": 2
-            },
-            {
-                "name": "SHUTDOWN_ONLY",
-                "value": 3
-            },
-            {
-                "name": "SLEEP_IMMEDIATELY",
-                "value": 4
-            },
-            {
-                "name": "HIBERNATE_IMMEDIATELY",
-                "value": 5
-            },
-            {
-                "name": "CAN_HIBERNATE",
+                "name": "INTERMITTENT_LEVEL_4",
                 "value": 6
             },
             {
-                "name": "EMERGENCY_SHUTDOWN",
+                "name": "INTERMITTENT_LEVEL_5",
                 "value": 7
-            }
-        ]
-    },
-    {
-        "name": "AutomaticEmergencyBrakingState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
             },
             {
-                "name": "ENABLED",
-                "value": 1
-            },
-            {
-                "name": "ACTIVATED",
-                "value": 2
-            },
-            {
-                "name": "USER_OVERRIDE",
-                "value": 3
-            }
-        ]
-    },
-    {
-        "name": "ImpactSensorLocation",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 1
-            },
-            {
-                "name": "FRONT",
-                "value": 2
-            },
-            {
-                "name": "FRONT_LEFT_DOOR_SIDE",
-                "value": 4
-            },
-            {
-                "name": "FRONT_RIGHT_DOOR_SIDE",
+                "name": "CONTINUOUS_LEVEL_1",
                 "value": 8
             },
             {
-                "name": "REAR_LEFT_DOOR_SIDE",
-                "value": 16
+                "name": "CONTINUOUS_LEVEL_2",
+                "value": 9
             },
             {
-                "name": "REAR_RIGHT_DOOR_SIDE",
-                "value": 32
+                "name": "CONTINUOUS_LEVEL_3",
+                "value": 10
             },
             {
-                "name": "REAR",
-                "value": 64
-            }
-        ]
-    },
-    {
-        "name": "CruiseControlType",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
+                "name": "CONTINUOUS_LEVEL_4",
+                "value": 11
             },
             {
-                "name": "STANDARD",
-                "value": 1
+                "name": "CONTINUOUS_LEVEL_5",
+                "value": 12
             },
             {
-                "name": "ADAPTIVE",
-                "value": 2
+                "name": "AUTO",
+                "value": 13
             },
             {
-                "name": "PREDICTIVE",
-                "value": 3
-            }
-        ]
-    },
-    {
-        "name": "LaneKeepAssistState",
-        "package": "android.hardware.automotive.vehicle",
-        "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
-            }
-        ]
-    },
-    {
-        "name": "CustomInputType",
-        "package": "android.hardware.automotive.vehicle",
-        "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": "ElectronicTollCollectionCardStatus",
-        "package": "android.hardware.automotive.vehicle",
-        "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
-            }
-        ]
-    },
-    {
-        "name": "HandsOnDetectionDriverState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "HANDS_ON",
-                "value": 1
-            },
-            {
-                "name": "HANDS_OFF",
-                "value": 2
-            }
-        ]
-    },
-    {
-        "name": "EmergencyLaneKeepAssistState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "ENABLED",
-                "value": 1
-            },
-            {
-                "name": "WARNING_LEFT",
-                "value": 2
-            },
-            {
-                "name": "WARNING_RIGHT",
-                "value": 3
-            },
-            {
-                "name": "ACTIVATED_STEER_LEFT",
-                "value": 4
-            },
-            {
-                "name": "ACTIVATED_STEER_RIGHT",
-                "value": 5
-            },
-            {
-                "name": "USER_OVERRIDE",
-                "value": 6
-            }
-        ]
-    },
-    {
-        "name": "VehicleAutonomousState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "LEVEL_0",
-                "value": 0
-            },
-            {
-                "name": "LEVEL_1",
-                "value": 1
-            },
-            {
-                "name": "LEVEL_2",
-                "value": 2
-            },
-            {
-                "name": "LEVEL_3",
-                "value": 3
-            },
-            {
-                "name": "LEVEL_4",
-                "value": 4
-            },
-            {
-                "name": "LEVEL_5",
-                "value": 5
-            }
-        ]
-    },
-    {
-        "name": "EvChargeState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "UNKNOWN",
-                "value": 0
-            },
-            {
-                "name": "CHARGING",
-                "value": 1
-            },
-            {
-                "name": "FULLY_CHARGED",
-                "value": 2
-            },
-            {
-                "name": "NOT_CHARGING",
-                "value": 3
-            },
-            {
-                "name": "ERROR",
-                "value": 4
-            }
-        ]
-    },
-    {
-        "name": "CameraServiceState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "UNAVAILABLE",
-                "value": 0
-            },
-            {
-                "name": "INACTIVE",
-                "value": 1
-            },
-            {
-                "name": "REQUESTED",
-                "value": 2
-            },
-            {
-                "name": "ACTIVE",
-                "value": 3
-            }
-        ]
-    },
-    {
-        "name": "GsrComplianceRequirementType",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "GSR_COMPLIANCE_NOT_REQUIRED",
-                "value": 0
-            },
-            {
-                "name": "GSR_COMPLIANCE_REQUIRED_V1",
-                "value": 1
-            }
-        ]
-    },
-    {
-        "name": "PortLocationType",
-        "package": "android.hardware.automotive.vehicle",
-        "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": "CruiseControlState",
-        "package": "android.hardware.automotive.vehicle",
-        "values": [
-            {
-                "name": "OTHER",
-                "value": 0
-            },
-            {
-                "name": "ENABLED",
-                "value": 1
-            },
-            {
-                "name": "ACTIVATED",
-                "value": 2
-            },
-            {
-                "name": "USER_OVERRIDE",
-                "value": 3
-            },
-            {
-                "name": "SUSPENDED",
-                "value": 4
-            },
-            {
-                "name": "FORCED_DEACTIVATION_WARNING",
-                "value": 5
+                "name": "SERVICE",
+                "value": 14
             }
         ]
     }
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/AccessForVehicleProperty.h
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
rename to automotive/vehicle/aidl/generated_lib/3/cpp/AccessForVehicleProperty.h
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp b/automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
similarity index 95%
rename from automotive/vehicle/aidl/generated_lib/cpp/Android.bp
rename to automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
index d14cbc2..7ff27a4 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/3/cpp/Android.bp
@@ -19,7 +19,7 @@
 }
 
 cc_library_headers {
-    name: "IVehicleGeneratedHeaders",
+    name: "IVehicleGeneratedHeaders-V3",
     vendor_available: true,
     local_include_dirs: ["."],
     export_include_dirs: ["."],
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/ChangeModeForVehicleProperty.h
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/cpp/ChangeModeForVehicleProperty.h
rename to automotive/vehicle/aidl/generated_lib/3/cpp/ChangeModeForVehicleProperty.h
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h
similarity index 98%
rename from automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
rename to automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h
index 1c1035d..0e80bd8 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/3/cpp/VersionForVehicleProperty.h
@@ -84,7 +84,7 @@
         {VehicleProperty::TRACTION_CONTROL_ACTIVE, 2},
         {VehicleProperty::EV_STOPPING_MODE, 2},
         {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, 3},
-        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, 2},
+        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, 3},
         {VehicleProperty::HVAC_FAN_SPEED, 2},
         {VehicleProperty::HVAC_FAN_DIRECTION, 2},
         {VehicleProperty::HVAC_TEMPERATURE_CURRENT, 2},
@@ -172,8 +172,8 @@
         {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_AIRBAG_ENABLED, 2},
+        {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, 3},
         {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, 2},
         {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, 2},
         {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, 2},
@@ -293,7 +293,7 @@
         {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_ENABLED, 3},
         {VehicleProperty::DRIVER_DISTRACTION_WARNING, 3},
         {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, 3},
         {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, 3},
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/AccessForVehicleProperty.java
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
rename to automotive/vehicle/aidl/generated_lib/3/java/AccessForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/Android.bp b/automotive/vehicle/aidl/generated_lib/3/java/Android.bp
similarity index 94%
rename from automotive/vehicle/aidl/generated_lib/java/Android.bp
rename to automotive/vehicle/aidl/generated_lib/3/java/Android.bp
index 1d612e8..b98fcbd 100644
--- a/automotive/vehicle/aidl/generated_lib/java/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/3/java/Android.bp
@@ -19,7 +19,7 @@
 }
 
 filegroup {
-    name: "IVehicleGeneratedJavaFiles",
+    name: "IVehicleGeneratedJavaFiles-V3",
     srcs: [
         "*.java",
     ],
diff --git a/automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/ChangeModeForVehicleProperty.java
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/java/ChangeModeForVehicleProperty.java
rename to automotive/vehicle/aidl/generated_lib/3/java/ChangeModeForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/EnumForVehicleProperty.java
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
rename to automotive/vehicle/aidl/generated_lib/3/java/EnumForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/UnitsForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/3/java/UnitsForVehicleProperty.java
similarity index 100%
rename from automotive/vehicle/aidl/generated_lib/java/UnitsForVehicleProperty.java
rename to automotive/vehicle/aidl/generated_lib/3/java/UnitsForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h
new file mode 100644
index 0000000..6d07fe5
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/AccessForVehicleProperty.h
@@ -0,0 +1,312 @@
+/*
+ * 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 <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = {
+        {VehicleProperty::INFO_VIN, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MAKE, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MODEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MODEL_YEAR, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_FUEL_CAPACITY, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_FUEL_TYPE, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_EV_BATTERY_CAPACITY, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_EV_CONNECTOR_TYPE, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_FUEL_DOOR_LOCATION, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_EV_PORT_LOCATION, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_DRIVER_SEAT, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, VehiclePropertyAccess::READ},
+        {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_ODOMETER, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_VEHICLE_SPEED, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_STEERING_ANGLE, VehiclePropertyAccess::READ},
+        {VehicleProperty::PERF_REAR_STEERING_ANGLE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_COOLANT_TEMP, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_OIL_LEVEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_OIL_TEMP, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_RPM, VehiclePropertyAccess::READ},
+        {VehicleProperty::WHEEL_TICK, VehiclePropertyAccess::READ},
+        {VehicleProperty::FUEL_LEVEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::FUEL_DOOR_OPEN, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_BATTERY_LEVEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_CHARGE_PORT_OPEN, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::RANGE_REMAINING, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TIRE_PRESSURE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::IMPACT_DETECTED, VehiclePropertyAccess::READ},
+        {VehicleProperty::GEAR_SELECTION, VehiclePropertyAccess::READ},
+        {VehicleProperty::CURRENT_GEAR, VehiclePropertyAccess::READ},
+        {VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyAccess::READ},
+        {VehicleProperty::PARKING_BRAKE_AUTO_APPLY, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FUEL_LEVEL_LOW, VehiclePropertyAccess::READ},
+        {VehicleProperty::NIGHT_MODE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TURN_SIGNAL_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::IGNITION_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ABS_ACTIVE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess::READ},
+        {VehicleProperty::HVAC_TEMPERATURE_SET, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_DEFROSTER, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_AC_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_MAX_AC_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_MAX_DEFROST_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_RECIRC_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_DUAL_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_AUTO_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_SEAT_TEMPERATURE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_SIDE_MIRROR_HEAT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_STEERING_WHEEL_HEAT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyAccess::READ},
+        {VehicleProperty::HVAC_POWER_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HVAC_AUTO_RECIRC_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_SEAT_VENTILATION, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DISTANCE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_BATTERY_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EXTERNAL_CAR_TIME, VehiclePropertyAccess::READ},
+        {VehicleProperty::ANDROID_EPOCH_TIME, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::ENV_OUTSIDE_TEMPERATURE, VehiclePropertyAccess::READ},
+        {VehicleProperty::AP_POWER_STATE_REQ, VehiclePropertyAccess::READ},
+        {VehicleProperty::AP_POWER_STATE_REPORT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyAccess::READ},
+        {VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HW_KEY_INPUT, VehiclePropertyAccess::READ},
+        {VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyAccess::READ},
+        {VehicleProperty::HW_MOTION_INPUT, VehiclePropertyAccess::READ},
+        {VehicleProperty::HW_ROTARY_INPUT, VehiclePropertyAccess::READ},
+        {VehicleProperty::HW_CUSTOM_INPUT, VehiclePropertyAccess::READ},
+        {VehicleProperty::DOOR_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DOOR_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DOOR_LOCK, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DOOR_CHILD_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_Z_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_Z_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_Y_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_Y_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_LOCK, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_FOLD, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::MIRROR_AUTO_TILT_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_MEMORY_SELECT, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::SEAT_MEMORY_SET, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::SEAT_BELT_BUCKLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BELT_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BELT_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_DEPTH_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_DEPTH_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_TILT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_TILT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, VehiclePropertyAccess::READ},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyAccess::READ},
+        {VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyAccess::READ},
+        {VehicleProperty::WINDOW_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::WINDOW_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::WINDOW_LOCK, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::WINDSHIELD_WIPERS_PERIOD, VehiclePropertyAccess::READ},
+        {VehicleProperty::WINDSHIELD_WIPERS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::WINDSHIELD_WIPERS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::GLOVE_BOX_DOOR_POS, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyAccess::READ},
+        {VehicleProperty::ULTRASONICS_SENSOR_POSITION, VehiclePropertyAccess::READ},
+        {VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyAccess::READ},
+        {VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess::READ},
+        {VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyAccess::READ},
+        {VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyAccess::READ},
+        {VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyAccess::READ},
+        {VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyAccess::READ},
+        {VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess::READ},
+        {VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::HEADLIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HAZARD_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HEADLIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HAZARD_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CABIN_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CABIN_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::READING_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::READING_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyAccess::READ},
+        {VehicleProperty::DISABLED_OPTIONAL_FEATURES, VehiclePropertyAccess::READ},
+        {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::SWITCH_USER, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CREATE_USER, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::REMOVE_USER, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EVS_SERVICE_REQUEST, VehiclePropertyAccess::READ},
+        {VehicleProperty::POWER_POLICY_REQ, VehiclePropertyAccess::READ},
+        {VehicleProperty::POWER_POLICY_GROUP_REQ, VehiclePropertyAccess::READ},
+        {VehicleProperty::CURRENT_POWER_POLICY, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::WATCHDOG_ALIVE, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::WATCHDOG_TERMINATED_PROCESS, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::VHAL_HEARTBEAT, VehiclePropertyAccess::READ},
+        {VehicleProperty::CLUSTER_SWITCH_UI, VehiclePropertyAccess::READ},
+        {VehicleProperty::CLUSTER_DISPLAY_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CLUSTER_REPORT_STATE, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::CLUSTER_REQUEST_DISPLAY, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::CLUSTER_NAVIGATION_STATE, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyAccess::READ},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyAccess::READ},
+        {VehicleProperty::FRONT_FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::REAR_FOG_LIGHTS_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::REAR_FOG_LIGHTS_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_PERCENT_LIMIT, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_CHARGE_SWITCH, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EV_CHARGE_TIME_REMAINING, VehiclePropertyAccess::READ},
+        {VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::TRAILER_PRESENT, VehiclePropertyAccess::READ},
+        {VehicleProperty::VEHICLE_CURB_WEIGHT, VehiclePropertyAccess::READ},
+        {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyAccess::READ},
+        {VehicleProperty::SUPPORTED_PROPERTY_IDS, VehiclePropertyAccess::READ},
+        {VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::VEHICLE_IN_USE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess::READ},
+        {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyAccess::READ},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::BLIND_SPOT_WARNING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CRUISE_CONTROL_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CRUISE_CONTROL_TYPE, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CRUISE_CONTROL_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CRUISE_CONTROL_COMMAND, VehiclePropertyAccess::WRITE},
+        {VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyAccess::READ},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess::READ},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyAccess::READ},
+        {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess::READ},
+        {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess::READ},
+        {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess::READ_WRITE},
+        {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess::READ},
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+}  // aidl
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp b/automotive/vehicle/aidl/generated_lib/4/cpp/Android.bp
similarity index 79%
copy from automotive/vehicle/aidl/generated_lib/cpp/Android.bp
copy to automotive/vehicle/aidl/generated_lib/4/cpp/Android.bp
index d14cbc2..5bee849 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/Android.bp
@@ -26,3 +26,12 @@
     defaults: ["VehicleHalInterfaceDefaults"],
     host_supported: true,
 }
+
+cc_library_headers {
+    name: "IVehicleGeneratedHeaders-V4",
+    vendor_available: true,
+    local_include_dirs: ["."],
+    export_include_dirs: ["."],
+    defaults: ["VehicleHalInterfaceDefaults"],
+    host_supported: true,
+}
diff --git a/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
new file mode 100644
index 0000000..5ecee95
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/ChangeModeForVehicleProperty.h
@@ -0,0 +1,312 @@
+/*
+ * 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 <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
+
+#include <unordered_map>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+
+std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = {
+        {VehicleProperty::INFO_VIN, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MAKE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MODEL, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MODEL_YEAR, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_FUEL_CAPACITY, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_FUEL_TYPE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_EV_BATTERY_CAPACITY, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_EV_CONNECTOR_TYPE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_FUEL_DOOR_LOCATION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_EV_PORT_LOCATION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_DRIVER_SEAT, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_EXTERIOR_DIMENSIONS, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::PERF_ODOMETER, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::PERF_VEHICLE_SPEED, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::PERF_STEERING_ANGLE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::PERF_REAR_STEERING_ANGLE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::ENGINE_COOLANT_TEMP, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::ENGINE_OIL_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ENGINE_OIL_TEMP, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::ENGINE_RPM, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::WHEEL_TICK, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::FUEL_LEVEL, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::FUEL_DOOR_OPEN, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_BATTERY_LEVEL, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_PORT_OPEN, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::RANGE_REMAINING, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::TIRE_PRESSURE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::IMPACT_DETECTED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::GEAR_SELECTION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CURRENT_GEAR, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::PARKING_BRAKE_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::PARKING_BRAKE_AUTO_APPLY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FUEL_LEVEL_LOW, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::NIGHT_MODE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TURN_SIGNAL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::IGNITION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ABS_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_STOPPING_MODE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_TEMPERATURE_SET, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_DEFROSTER, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_AC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_MAX_AC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_MAX_DEFROST_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_RECIRC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_DUAL_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_AUTO_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_SEAT_TEMPERATURE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_SIDE_MIRROR_HEAT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_STEERING_WHEEL_HEAT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_POWER_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::HVAC_AUTO_RECIRC_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_SEAT_VENTILATION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DISTANCE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_BATTERY_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EXTERNAL_CAR_TIME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ANDROID_EPOCH_TIME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ENV_OUTSIDE_TEMPERATURE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::AP_POWER_STATE_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::AP_POWER_STATE_REPORT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VALET_MODE_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HEAD_UP_DISPLAY_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_KEY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_KEY_INPUT_V2, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_MOTION_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_ROTARY_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HW_CUSTOM_INPUT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DOOR_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DOOR_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DOOR_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DOOR_CHILD_LOCK_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_Z_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_Z_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_Y_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_Y_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_FOLD, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::MIRROR_AUTO_TILT_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_MEMORY_SELECT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_MEMORY_SET, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BELT_BUCKLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BELT_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BELT_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_DEPTH_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_DEPTH_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_TILT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_TILT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_WALK_IN_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SEAT_OCCUPANCY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDOW_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDOW_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDOW_LOCK, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDSHIELD_WIPERS_PERIOD, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDSHIELD_WIPERS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WINDSHIELD_WIPERS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::GLOVE_BOX_DOOR_POS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::GLOVE_BOX_LOCKED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ULTRASONICS_SENSOR_POSITION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::OBD2_LIVE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::OBD2_FREEZE_FRAME, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HEADLIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HAZARD_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HEADLIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HAZARD_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CABIN_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CABIN_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::READING_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::READING_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::DISABLED_OPTIONAL_FEATURES, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::INITIAL_USER_INFO, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::SWITCH_USER, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CREATE_USER, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::REMOVE_USER, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EVS_SERVICE_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::POWER_POLICY_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::POWER_POLICY_GROUP_REQ, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CURRENT_POWER_POLICY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WATCHDOG_ALIVE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::WATCHDOG_TERMINATED_PROCESS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VHAL_HEARTBEAT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_SWITCH_UI, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_DISPLAY_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_REPORT_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_REQUEST_DISPLAY, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_NAVIGATION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FRONT_FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::REAR_FOG_LIGHTS_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::REAR_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_PERCENT_LIMIT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_SWITCH, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EV_CHARGE_TIME_REMAINING, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::TRAILER_PRESENT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_CURB_WEIGHT, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::SUPPORTED_PROPERTY_IDS, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::SHUTDOWN_REQUEST, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_IN_USE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CLUSTER_HEARTBEAT, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyChangeMode::STATIC},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::FORWARD_COLLISION_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::BLIND_SPOT_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::BLIND_SPOT_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_DEPARTURE_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LANE_CENTERING_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_TYPE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_COMMAND, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyChangeMode::CONTINUOUS},
+        {VehicleProperty::HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_DISTRACTION_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::DRIVER_DISTRACTION_WARNING, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode::ON_CHANGE},
+        {VehicleProperty::LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode::ON_CHANGE},
+};
+
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
+}  // aidl
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h
similarity index 97%
copy from automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
copy to automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h
index 1c1035d..8b9c1bd 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/VersionForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/4/cpp/VersionForVehicleProperty.h
@@ -84,7 +84,7 @@
         {VehicleProperty::TRACTION_CONTROL_ACTIVE, 2},
         {VehicleProperty::EV_STOPPING_MODE, 2},
         {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_ENABLED, 3},
-        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, 2},
+        {VehicleProperty::ELECTRONIC_STABILITY_CONTROL_STATE, 3},
         {VehicleProperty::HVAC_FAN_SPEED, 2},
         {VehicleProperty::HVAC_FAN_DIRECTION, 2},
         {VehicleProperty::HVAC_TEMPERATURE_CURRENT, 2},
@@ -172,8 +172,8 @@
         {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_AIRBAG_ENABLED, 2},
+        {VehicleProperty::SEAT_AIRBAGS_DEPLOYED, 3},
         {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_POS, 2},
         {VehicleProperty::SEAT_CUSHION_SIDE_SUPPORT_MOVE, 2},
         {VehicleProperty::SEAT_LUMBAR_VERTICAL_POS, 2},
@@ -262,6 +262,7 @@
         {VehicleProperty::CLUSTER_HEARTBEAT, 3},
         {VehicleProperty::VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, 3},
         {VehicleProperty::CAMERA_SERVICE_CURRENT_STATE, 3},
+        {VehicleProperty::PER_DISPLAY_MAX_BRIGHTNESS, 3},
         {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_ENABLED, 2},
         {VehicleProperty::AUTOMATIC_EMERGENCY_BRAKING_STATE, 2},
         {VehicleProperty::FORWARD_COLLISION_WARNING_ENABLED, 2},
@@ -293,7 +294,7 @@
         {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_ENABLED, 3},
         {VehicleProperty::DRIVER_DISTRACTION_WARNING, 3},
         {VehicleProperty::LOW_SPEED_COLLISION_WARNING_ENABLED, 3},
         {VehicleProperty::LOW_SPEED_COLLISION_WARNING_STATE, 3},
diff --git a/automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java
new file mode 100644
index 0000000..e9f35a5
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/4/java/AccessForVehicleProperty.java
@@ -0,0 +1,301 @@
+/*
+ * 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
+
+package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class AccessForVehicleProperty {
+
+    public static final Map<Integer, Integer> values = Map.ofEntries(
+        Map.entry(VehicleProperty.INFO_VIN, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MAKE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MODEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MODEL_YEAR, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_FUEL_CAPACITY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_FUEL_TYPE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_EV_BATTERY_CAPACITY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_EV_CONNECTOR_TYPE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_FUEL_DOOR_LOCATION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_EV_PORT_LOCATION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_DRIVER_SEAT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_ODOMETER, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_RPM, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.WHEEL_TICK, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FUEL_LEVEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FUEL_DOOR_OPEN, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_BATTERY_LEVEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_CHARGE_PORT_OPEN, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_PORT_CONNECTED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.RANGE_REMAINING, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.IMPACT_DETECTED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.PARKING_BRAKE_AUTO_APPLY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FUEL_LEVEL_LOW, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.NIGHT_MODE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TURN_SIGNAL_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_SET, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_DEFROSTER, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_AC_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_MAX_AC_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_MAX_DEFROST_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_RECIRC_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_DUAL_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_AUTO_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_SEAT_TEMPERATURE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_SIDE_MIRROR_HEAT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_STEERING_WHEEL_HEAT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HVAC_POWER_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HVAC_AUTO_RECIRC_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_SEAT_VENTILATION, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DISTANCE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_BATTERY_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EXTERNAL_CAR_TIME, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ANDROID_EPOCH_TIME, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.ENV_OUTSIDE_TEMPERATURE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.AP_POWER_STATE_REQ, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.AP_POWER_STATE_REPORT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HEAD_UP_DISPLAY_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HW_ROTARY_INPUT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HW_CUSTOM_INPUT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DOOR_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DOOR_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DOOR_LOCK, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DOOR_CHILD_LOCK_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_Z_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_Z_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_Y_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_Y_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_LOCK, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_FOLD, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.MIRROR_AUTO_TILT_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_MEMORY_SELECT, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.SEAT_MEMORY_SET, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.SEAT_BELT_BUCKLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_DEPTH_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_DEPTH_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_TILT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_TILT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_AIRBAGS_DEPLOYED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_WALK_IN_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.WINDOW_LOCK, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_PERIOD, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LOCKED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.GLOVE_BOX_DOOR_POS, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_POSITION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.HEADLIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HAZARD_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HEADLIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HAZARD_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CABIN_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CABIN_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.READING_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.READING_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DISABLED_OPTIONAL_FEATURES, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.SWITCH_USER, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CREATE_USER, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EVS_SERVICE_REQUEST, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.POWER_POLICY_REQ, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.POWER_POLICY_GROUP_REQ, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CURRENT_POWER_POLICY, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.WATCHDOG_ALIVE, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.WATCHDOG_TERMINATED_PROCESS, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.VHAL_HEARTBEAT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CLUSTER_SWITCH_UI, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CLUSTER_DISPLAY_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CLUSTER_REPORT_STATE, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.CLUSTER_REQUEST_DISPLAY, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.CLUSTER_NAVIGATION_STATE, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.REAR_FOG_LIGHTS_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.REAR_FOG_LIGHTS_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_PERCENT_LIMIT, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_CHARGE_SWITCH, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EV_CHARGE_TIME_REMAINING, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.TRAILER_PRESENT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.VEHICLE_CURB_WEIGHT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SUPPORTED_PROPERTY_IDS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_TYPE, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, VehiclePropertyAccess.WRITE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyAccess.READ),
+        Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyAccess.READ_WRITE),
+        Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyAccess.READ)
+    );
+
+}
diff --git a/automotive/vehicle/aidl/generated_lib/java/Android.bp b/automotive/vehicle/aidl/generated_lib/4/java/Android.bp
similarity index 89%
copy from automotive/vehicle/aidl/generated_lib/java/Android.bp
copy to automotive/vehicle/aidl/generated_lib/4/java/Android.bp
index 1d612e8..f3c96f5 100644
--- a/automotive/vehicle/aidl/generated_lib/java/Android.bp
+++ b/automotive/vehicle/aidl/generated_lib/4/java/Android.bp
@@ -24,3 +24,10 @@
         "*.java",
     ],
 }
+
+filegroup {
+    name: "IVehicleGeneratedJavaFiles-V4",
+    srcs: [
+        "*.java",
+    ],
+}
diff --git a/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
new file mode 100644
index 0000000..3fb52b7
--- /dev/null
+++ b/automotive/vehicle/aidl/generated_lib/4/java/ChangeModeForVehicleProperty.java
@@ -0,0 +1,301 @@
+/*
+ * 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
+
+package android.hardware.automotive.vehicle;
+
+import java.util.Map;
+
+public final class ChangeModeForVehicleProperty {
+
+    public static final Map<Integer, Integer> values = Map.ofEntries(
+        Map.entry(VehicleProperty.INFO_VIN, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MAKE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MODEL, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MODEL_YEAR, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_FUEL_CAPACITY, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_FUEL_TYPE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_EV_BATTERY_CAPACITY, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_EV_CONNECTOR_TYPE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_FUEL_DOOR_LOCATION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_EV_PORT_LOCATION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_DRIVER_SEAT, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_EXTERIOR_DIMENSIONS, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INFO_MULTI_EV_PORT_LOCATIONS, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.PERF_ODOMETER, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.PERF_VEHICLE_SPEED, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.PERF_VEHICLE_SPEED_DISPLAY, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.PERF_STEERING_ANGLE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.PERF_REAR_STEERING_ANGLE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.ENGINE_COOLANT_TEMP, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.ENGINE_OIL_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ENGINE_OIL_TEMP, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.ENGINE_RPM, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.WHEEL_TICK, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.FUEL_LEVEL, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.FUEL_DOOR_OPEN, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_BATTERY_LEVEL, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.EV_CURRENT_BATTERY_CAPACITY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_PORT_OPEN, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_PORT_CONNECTED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_BATTERY_INSTANTANEOUS_CHARGE_RATE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.RANGE_REMAINING, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.EV_BATTERY_AVERAGE_TEMPERATURE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.TIRE_PRESSURE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.CRITICALLY_LOW_TIRE_PRESSURE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ENGINE_IDLE_AUTO_STOP_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.IMPACT_DETECTED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.GEAR_SELECTION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CURRENT_GEAR, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.PARKING_BRAKE_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.PARKING_BRAKE_AUTO_APPLY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_BRAKE_REGENERATION_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FUEL_LEVEL_LOW, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.NIGHT_MODE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TURN_SIGNAL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_STOPPING_MODE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ELECTRONIC_STABILITY_CONTROL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_SET, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_DEFROSTER, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_AC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_MAX_AC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_MAX_DEFROST_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_RECIRC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_DUAL_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_AUTO_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_SEAT_TEMPERATURE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_SIDE_MIRROR_HEAT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_STEERING_WHEEL_HEAT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_ACTUAL_FAN_SPEED_RPM, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_POWER_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_FAN_DIRECTION_AVAILABLE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.HVAC_AUTO_RECIRC_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_SEAT_VENTILATION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_ELECTRIC_DEFROSTER_ON, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HVAC_TEMPERATURE_VALUE_SUGGESTION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DISTANCE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FUEL_VOLUME_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TIRE_PRESSURE_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_BATTERY_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_SPEED_DISPLAY_UNITS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EXTERNAL_CAR_TIME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ANDROID_EPOCH_TIME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STORAGE_ENCRYPTION_BINDING_SEED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ENV_OUTSIDE_TEMPERATURE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.AP_POWER_STATE_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.AP_POWER_STATE_REPORT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.AP_POWER_BOOTUP_REASON, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.PER_DISPLAY_BRIGHTNESS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VALET_MODE_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HEAD_UP_DISPLAY_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_KEY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_KEY_INPUT_V2, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_MOTION_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_ROTARY_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HW_CUSTOM_INPUT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DOOR_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DOOR_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DOOR_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DOOR_CHILD_LOCK_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_Z_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_Z_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_Y_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_Y_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_FOLD, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_AUTO_FOLD_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.MIRROR_AUTO_TILT_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_MEMORY_SELECT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_MEMORY_SET, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BELT_BUCKLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BELT_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_1_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BACKREST_ANGLE_2_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_DEPTH_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_DEPTH_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_TILT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_TILT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_POS_V2, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_ANGLE_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_HEADREST_FORE_AFT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_FOOTWELL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_AIRBAG_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_AIRBAGS_DEPLOYED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_CUSHION_SIDE_SUPPORT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_LUMBAR_VERTICAL_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_WALK_IN_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_BELT_PRETENSIONER_DEPLOYED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SEAT_OCCUPANCY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDOW_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDOW_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDOW_LOCK, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_PERIOD, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WINDSHIELD_WIPERS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_DEPTH_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_HEIGHT_MOVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_THEFT_LOCK_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_EASY_ACCESS_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.GLOVE_BOX_DOOR_POS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.GLOVE_BOX_LOCKED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_MAP_SERVICE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LOCATION_CHARACTERIZATION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_POSITION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_ORIENTATION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_FIELD_OF_VIEW, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_DETECTION_RANGE, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_SUPPORTED_RANGES, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.ULTRASONICS_SENSOR_MEASURED_DISTANCE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.OBD2_LIVE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_INFO, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HEADLIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HAZARD_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HEADLIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HIGH_BEAM_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HAZARD_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CABIN_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CABIN_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.READING_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.READING_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.STEERING_WHEEL_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SUPPORT_CUSTOMIZE_VENDOR_PERMISSION, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.DISABLED_OPTIONAL_FEATURES, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.INITIAL_USER_INFO, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.SWITCH_USER, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CREATE_USER, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.REMOVE_USER, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.USER_IDENTIFICATION_ASSOCIATION, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EVS_SERVICE_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.POWER_POLICY_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.POWER_POLICY_GROUP_REQ, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CURRENT_POWER_POLICY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WATCHDOG_ALIVE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.WATCHDOG_TERMINATED_PROCESS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VHAL_HEARTBEAT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_SWITCH_UI, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_DISPLAY_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_REPORT_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_REQUEST_DISPLAY, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_NAVIGATION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_TYPE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ELECTRONIC_TOLL_COLLECTION_CARD_STATUS, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FRONT_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.REAR_FOG_LIGHTS_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.REAR_FOG_LIGHTS_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_CURRENT_DRAW_LIMIT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_PERCENT_LIMIT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_SWITCH, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EV_CHARGE_TIME_REMAINING, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.EV_REGENERATIVE_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.TRAILER_PRESENT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_CURB_WEIGHT, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.SUPPORTED_PROPERTY_IDS, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.SHUTDOWN_REQUEST, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_IN_USE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CLUSTER_HEARTBEAT, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CAMERA_SERVICE_CURRENT_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.PER_DISPLAY_MAX_BRIGHTNESS, VehiclePropertyChangeMode.STATIC),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.FORWARD_COLLISION_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.BLIND_SPOT_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_DEPARTURE_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_COMMAND, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LANE_CENTERING_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.EMERGENCY_LANE_KEEP_ASSIST_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_TYPE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_COMMAND, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CRUISE_CONTROL_TARGET_SPEED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_TARGET_TIME_GAP, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.ADAPTIVE_CRUISE_CONTROL_LEAD_VEHICLE_MEASURED_DISTANCE, VehiclePropertyChangeMode.CONTINUOUS),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_DRIVER_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.HANDS_ON_DETECTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_DROWSINESS_ATTENTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_DISTRACTION_SYSTEM_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_DISTRACTION_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.DRIVER_DISTRACTION_WARNING, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LOW_SPEED_COLLISION_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.CROSS_TRAFFIC_MONITORING_WARNING_STATE, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_ENABLED, VehiclePropertyChangeMode.ON_CHANGE),
+        Map.entry(VehicleProperty.LOW_SPEED_AUTOMATIC_EMERGENCY_BRAKING_STATE, VehiclePropertyChangeMode.ON_CHANGE)
+    );
+
+}
diff --git a/automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/EnumForVehicleProperty.java
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/java/EnumForVehicleProperty.java
copy to automotive/vehicle/aidl/generated_lib/4/java/EnumForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/generated_lib/java/UnitsForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/4/java/UnitsForVehicleProperty.java
similarity index 100%
copy from automotive/vehicle/aidl/generated_lib/java/UnitsForVehicleProperty.java
copy to automotive/vehicle/aidl/generated_lib/4/java/UnitsForVehicleProperty.java
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
index d1974ac..28c95ce 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/Android.bp
@@ -27,7 +27,7 @@
     defaults: ["VehicleHalDefaults"],
     static_libs: ["VehicleHalUtils"],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: ["libjsoncpp"],
 }
@@ -44,7 +44,7 @@
     defaults: ["VehicleHalDefaults"],
     static_libs: ["VehicleHalUtils"],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
         "libbinder_headers",
     ],
     cflags: ["-DENABLE_VEHICLE_HAL_TEST_PROPERTIES"],
@@ -60,7 +60,7 @@
     defaults: ["VehicleHalDefaults"],
     static_libs: ["VehicleHalUtils"],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: ["libjsoncpp"],
 }
diff --git a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
index ea1437e..57af04c 100644
--- a/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
+++ b/automotive/vehicle/aidl/impl/default_config/JsonConfigLoader/src/JsonConfigLoader.cpp
@@ -104,6 +104,8 @@
         {"HVAC_ALL", HVAC_ALL},
         {"HVAC_LEFT", HVAC_LEFT},
         {"HVAC_RIGHT", HVAC_RIGHT},
+        {"HVAC_FRONT_ROW", HVAC_FRONT_ROW},
+        {"HVAC_REAR_ROW", HVAC_REAR_ROW},
         {"WINDOW_1_LEFT", WINDOW_1_LEFT},
         {"WINDOW_1_RIGHT", WINDOW_1_RIGHT},
         {"WINDOW_2_LEFT", WINDOW_2_LEFT},
diff --git a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
index 0a859af..2d1e9ab 100644
--- a/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
+++ b/automotive/vehicle/aidl/impl/default_config/config/DefaultProperties.json
@@ -2033,19 +2033,10 @@
             },
             "areas": [
                 {
-                    "areaId": "Constants::SEAT_1_LEFT"
+                    "areaId": "Constants::HVAC_FRONT_ROW"
                 },
                 {
-                    "areaId": "Constants::SEAT_1_RIGHT"
-                },
-                {
-                    "areaId": "Constants::SEAT_2_LEFT"
-                },
-                {
-                    "areaId": "Constants::SEAT_2_RIGHT"
-                },
-                {
-                    "areaId": "Constants::SEAT_2_CENTER"
+                    "areaId": "Constants::HVAC_REAR_ROW"
                 }
             ]
         },
diff --git a/automotive/vehicle/aidl/impl/default_config/test/Android.bp b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
index 651ed90..70933be 100644
--- a/automotive/vehicle/aidl/impl/default_config/test/Android.bp
+++ b/automotive/vehicle/aidl/impl/default_config/test/Android.bp
@@ -31,7 +31,7 @@
         "libgtest",
     ],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: [
         "libjsoncpp",
@@ -57,7 +57,7 @@
         "-DENABLE_VEHICLE_HAL_TEST_PROPERTIES",
     ],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     shared_libs: [
         "libjsoncpp",
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 237a4c4..54dcca2 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -1875,7 +1875,7 @@
         for (const auto& areaConfig : config.areaConfigs) {
             areaIds.push_back(areaConfig.areaId);
         }
-        ss << rowNumber++ << ": " << propIdToString(config.prop) << ", propID: " << std::showbase
+        ss << rowNumber++ << ": " << PROP_ID_TO_CSTR(config.prop) << ", propID: " << std::showbase
            << std::hex << config.prop << std::noshowbase << std::dec
            << ", areaIDs: " << vecToStringOfHexValues(areaIds) << std::endl;
     }
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
index 78b61f7..f2327e1 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/PropertyUtils.h
@@ -97,6 +97,8 @@
 constexpr int HVAC_LEFT = SEAT_1_LEFT | SEAT_2_LEFT | SEAT_2_CENTER;
 constexpr int HVAC_RIGHT = SEAT_1_RIGHT | SEAT_2_RIGHT;
 constexpr int HVAC_ALL = HVAC_LEFT | HVAC_RIGHT;
+constexpr int HVAC_FRONT_ROW = SEAT_1_LEFT | SEAT_1_RIGHT;
+constexpr int HVAC_REAR_ROW = SEAT_2_LEFT | SEAT_2_CENTER | SEAT_2_RIGHT;
 
 }  // namespace vehicle
 }  // namespace automotive
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index 3d0a524..a7caeb1 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -153,10 +153,9 @@
                 propValue->status = oldStatus;
             }
 
+            // areaId and propId must be the same between valueToUpdate and propValue.
             valueUpdated = (valueToUpdate->value != propValue->value ||
-                            valueToUpdate->status != propValue->status ||
-                            valueToUpdate->prop != propValue->prop ||
-                            valueToUpdate->areaId != propValue->areaId);
+                            valueToUpdate->status != propValue->status);
         } else if (!updateStatus) {
             propValue->status = VehiclePropertyStatus::AVAILABLE;
         }
diff --git a/automotive/vehicle/aidl/impl/vhal/Android.bp b/automotive/vehicle/aidl/impl/vhal/Android.bp
index ae1102f..5cc071d 100644
--- a/automotive/vehicle/aidl/impl/vhal/Android.bp
+++ b/automotive/vehicle/aidl/impl/vhal/Android.bp
@@ -66,7 +66,7 @@
     ],
     header_libs: [
         "IVehicleHardware",
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     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 250b30c..fa2a310 100644
--- a/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
+++ b/automotive/vehicle/aidl/impl/vhal/include/DefaultVehicleHal.h
@@ -42,10 +42,11 @@
 namespace automotive {
 namespace vehicle {
 
-class DefaultVehicleHal final : public aidl::android::hardware::automotive::vehicle::BnVehicle {
+namespace aidlvhal = ::aidl::android::hardware::automotive::vehicle;
+
+class DefaultVehicleHal final : public aidlvhal::BnVehicle {
   public:
-    using CallbackType =
-            std::shared_ptr<aidl::android::hardware::automotive::vehicle::IVehicleCallback>;
+    using CallbackType = std::shared_ptr<aidlvhal::IVehicleCallback>;
 
     explicit DefaultVehicleHal(std::unique_ptr<IVehicleHardware> hardware);
 
@@ -54,26 +55,16 @@
 
     ~DefaultVehicleHal();
 
-    ndk::ScopedAStatus getAllPropConfigs(
-            aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
-            override;
-    ndk::ScopedAStatus getValues(
-            const CallbackType& callback,
-            const aidl::android::hardware::automotive::vehicle::GetValueRequests& requests)
-            override;
-    ndk::ScopedAStatus setValues(
-            const CallbackType& callback,
-            const aidl::android::hardware::automotive::vehicle::SetValueRequests& requests)
-            override;
-    ndk::ScopedAStatus getPropConfigs(
-            const std::vector<int32_t>& props,
-            aidl::android::hardware::automotive::vehicle::VehiclePropConfigs* returnConfigs)
-            override;
-    ndk::ScopedAStatus subscribe(
-            const CallbackType& callback,
-            const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
-                    options,
-            int32_t maxSharedMemoryFileCount) override;
+    ndk::ScopedAStatus getAllPropConfigs(aidlvhal::VehiclePropConfigs* returnConfigs) override;
+    ndk::ScopedAStatus getValues(const CallbackType& callback,
+                                 const aidlvhal::GetValueRequests& requests) override;
+    ndk::ScopedAStatus setValues(const CallbackType& callback,
+                                 const aidlvhal::SetValueRequests& requests) override;
+    ndk::ScopedAStatus getPropConfigs(const std::vector<int32_t>& props,
+                                      aidlvhal::VehiclePropConfigs* returnConfigs) override;
+    ndk::ScopedAStatus subscribe(const CallbackType& callback,
+                                 const std::vector<aidlvhal::SubscribeOptions>& options,
+                                 int32_t maxSharedMemoryFileCount) override;
     ndk::ScopedAStatus unsubscribe(const CallbackType& callback,
                                    const std::vector<int32_t>& propIds) override;
     ndk::ScopedAStatus returnSharedMemory(const CallbackType& callback,
@@ -86,12 +77,8 @@
     // friend class for unit testing.
     friend class DefaultVehicleHalTest;
 
-    using GetValuesClient =
-            GetSetValuesClient<aidl::android::hardware::automotive::vehicle::GetValueResult,
-                               aidl::android::hardware::automotive::vehicle::GetValueResults>;
-    using SetValuesClient =
-            GetSetValuesClient<aidl::android::hardware::automotive::vehicle::SetValueResult,
-                               aidl::android::hardware::automotive::vehicle::SetValueResults>;
+    using GetValuesClient = GetSetValuesClient<aidlvhal::GetValueResult, aidlvhal::GetValueResults>;
+    using SetValuesClient = GetSetValuesClient<aidlvhal::SetValueResult, aidlvhal::SetValueResults>;
 
     // A wrapper for binder lifecycle operations to enable stubbing for test.
     class BinderLifecycleInterface {
@@ -137,28 +124,27 @@
     bool mShouldRefreshPropertyConfigs;
     std::unique_ptr<IVehicleHardware> mVehicleHardware;
 
-    // mConfigsByPropId and mConfigFile are only modified during initialization, so no need to
-    // lock guard them.
-    std::unordered_map<int32_t, aidl::android::hardware::automotive::vehicle::VehiclePropConfig>
-            mConfigsByPropId;
-    // Only modified in constructor, so thread-safe.
-    std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile;
     // PendingRequestPool is thread-safe.
     std::shared_ptr<PendingRequestPool> mPendingRequestPool;
     // SubscriptionManager is thread-safe.
     std::shared_ptr<SubscriptionManager> mSubscriptionManager;
     // ConcurrentQueue is thread-safe.
-    std::shared_ptr<ConcurrentQueue<aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
-            mBatchedEventQueue;
+    std::shared_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>> mBatchedEventQueue;
     // BatchingConsumer is thread-safe.
-    std::shared_ptr<
-            BatchingConsumer<aidl::android::hardware::automotive::vehicle::VehiclePropValue>>
+    std::shared_ptr<BatchingConsumer<aidlvhal::VehiclePropValue>>
             mPropertyChangeEventsBatchingConsumer;
     // Only set once during initialization.
     std::chrono::nanoseconds mEventBatchingWindow;
     // Only used for testing.
     int32_t mTestInterfaceVersion = 0;
 
+    // mConfigsByPropId and mConfigFile is lazy initialized.
+    mutable std::mutex mConfigInitLock;
+    mutable bool mConfigInit GUARDED_BY(mConfigInitLock) = false;
+    mutable std::unordered_map<int32_t, aidlvhal::VehiclePropConfig> mConfigsByPropId
+            GUARDED_BY(mConfigInitLock);
+    mutable std::unique_ptr<ndk::ScopedFileDescriptor> mConfigFile GUARDED_BY(mConfigInitLock);
+
     std::mutex mLock;
     std::unordered_map<const AIBinder*, std::unique_ptr<OnBinderDiedContext>> mOnBinderDiedContexts
             GUARDED_BY(mLock);
@@ -182,32 +168,23 @@
     // A thread to handle onBinderDied or onBinderUnlinked event.
     std::thread mOnBinderDiedUnlinkedHandlerThread;
 
-    android::base::Result<void> checkProperty(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& propValue);
+    android::base::Result<void> checkProperty(const aidlvhal::VehiclePropValue& propValue);
 
     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
-            const std::vector<aidl::android::hardware::automotive::vehicle::GetValueRequest>&
-                    requests);
+            const std::vector<aidlvhal::GetValueRequest>& requests);
 
     android::base::Result<std::vector<int64_t>> checkDuplicateRequests(
-            const std::vector<aidl::android::hardware::automotive::vehicle::SetValueRequest>&
-                    requests);
-    VhalResult<void> checkSubscribeOptions(
-            const std::vector<aidl::android::hardware::automotive::vehicle::SubscribeOptions>&
-                    options);
+            const std::vector<aidlvhal::SetValueRequest>& requests);
+    VhalResult<void> checkSubscribeOptions(const std::vector<aidlvhal::SubscribeOptions>& options);
 
-    VhalResult<void> checkPermissionHelper(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value,
-            aidl::android::hardware::automotive::vehicle::VehiclePropertyAccess accessToTest) const;
+    VhalResult<void> checkPermissionHelper(const aidlvhal::VehiclePropValue& value,
+                                           aidlvhal::VehiclePropertyAccess accessToTest) const;
 
-    VhalResult<void> checkReadPermission(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
+    VhalResult<void> checkReadPermission(const aidlvhal::VehiclePropValue& value) const;
 
-    VhalResult<void> checkWritePermission(
-            const aidl::android::hardware::automotive::vehicle::VehiclePropValue& value) const;
+    VhalResult<void> checkWritePermission(const aidlvhal::VehiclePropValue& value) const;
 
-    android::base::Result<const aidl::android::hardware::automotive::vehicle::VehiclePropConfig*>
-    getConfig(int32_t propId) const;
+    android::base::Result<const aidlvhal::VehiclePropConfig*> getConfig(int32_t propId) const;
 
     void onBinderDiedWithContext(const AIBinder* clientId);
 
@@ -219,7 +196,7 @@
 
     bool checkDumpPermission();
 
-    bool getAllPropConfigsFromHardware();
+    bool getAllPropConfigsFromHardwareLocked() const REQUIRES(mConfigInitLock);
 
     // The looping handler function to process all onBinderDied or onBinderUnlinked events in
     // mBinderEvents.
@@ -228,19 +205,19 @@
     size_t countSubscribeClients();
 
     // Handles the property change events in batch.
-    void handleBatchedPropertyEvents(
-            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
-                    batchedEvents);
+    void handleBatchedPropertyEvents(std::vector<aidlvhal::VehiclePropValue>&& batchedEvents);
 
-    int32_t getVhalInterfaceVersion();
+    int32_t getVhalInterfaceVersion() const;
+
+    // Gets mConfigsByPropId, lazy init it if necessary.
+    const std::unordered_map<int32_t, aidlvhal::VehiclePropConfig>& getConfigsByPropId() const;
+    // Gets mConfigFile, lazy init it if necessary.
+    const ndk::ScopedFileDescriptor* getConfigFile() const;
 
     // Puts the property change events into a queue so that they can handled in batch.
     static void batchPropertyChangeEvent(
-            const std::weak_ptr<ConcurrentQueue<
-                    aidl::android::hardware::automotive::vehicle::VehiclePropValue>>&
-                    batchedEventQueue,
-            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
-                    updatedValues);
+            const std::weak_ptr<ConcurrentQueue<aidlvhal::VehiclePropValue>>& batchedEventQueue,
+            std::vector<aidlvhal::VehiclePropValue>&& updatedValues);
 
     // Gets or creates a {@code T} object for the client to or from {@code clients}.
     template <class T>
@@ -248,10 +225,8 @@
             std::unordered_map<const AIBinder*, std::shared_ptr<T>>* clients,
             const CallbackType& callback, std::shared_ptr<PendingRequestPool> pendingRequestPool);
 
-    static void onPropertyChangeEvent(
-            const std::weak_ptr<SubscriptionManager>& subscriptionManager,
-            std::vector<aidl::android::hardware::automotive::vehicle::VehiclePropValue>&&
-                    updatedValues);
+    static void onPropertyChangeEvent(const std::weak_ptr<SubscriptionManager>& subscriptionManager,
+                                      std::vector<aidlvhal::VehiclePropValue>&& updatedValues);
 
     static void onPropertySetErrorEvent(
             const std::weak_ptr<SubscriptionManager>& subscriptionManager,
diff --git a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
index a29861f..9dc039d 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/DefaultVehicleHal.cpp
@@ -24,6 +24,7 @@
 #include <VehicleUtils.h>
 #include <VersionForVehicleProperty.h>
 
+#include <android-base/logging.h>
 #include <android-base/result.h>
 #include <android-base/stringprintf.h>
 #include <android/binder_ibinder.h>
@@ -71,6 +72,7 @@
 
 using ::ndk::ScopedAIBinder_DeathRecipient;
 using ::ndk::ScopedAStatus;
+using ::ndk::ScopedFileDescriptor;
 
 std::string toString(const std::unordered_set<int64_t>& values) {
     std::string str = "";
@@ -103,10 +105,7 @@
     : mVehicleHardware(std::move(vehicleHardware)),
       mPendingRequestPool(std::make_shared<PendingRequestPool>(TIMEOUT_IN_NANO)),
       mTestInterfaceVersion(testInterfaceVersion) {
-    if (!getAllPropConfigsFromHardware()) {
-        return;
-    }
-
+    ALOGD("DefaultVehicleHal init");
     IVehicleHardware* vehicleHardwarePtr = mVehicleHardware.get();
     mSubscriptionManager = std::make_shared<SubscriptionManager>(vehicleHardwarePtr);
     mEventBatchingWindow = mVehicleHardware->getPropertyOnChangeEventBatchingWindow();
@@ -319,16 +318,18 @@
     mPendingRequestPool = std::make_unique<PendingRequestPool>(timeoutInNano);
 }
 
-int32_t DefaultVehicleHal::getVhalInterfaceVersion() {
+int32_t DefaultVehicleHal::getVhalInterfaceVersion() const {
     if (mTestInterfaceVersion != 0) {
         return mTestInterfaceVersion;
     }
     int32_t myVersion = 0;
-    getInterfaceVersion(&myVersion);
+    // getInterfaceVersion is in-reality a const method.
+    const_cast<DefaultVehicleHal*>(this)->getInterfaceVersion(&myVersion);
     return myVersion;
 }
 
-bool DefaultVehicleHal::getAllPropConfigsFromHardware() {
+bool DefaultVehicleHal::getAllPropConfigsFromHardwareLocked() const {
+    ALOGD("Get all property configs from hardware");
     auto configs = mVehicleHardware->getAllPropertyConfigs();
     std::vector<VehiclePropConfig> filteredConfigs;
     int32_t myVersion = getVhalInterfaceVersion();
@@ -373,22 +374,46 @@
     return true;
 }
 
+const ScopedFileDescriptor* DefaultVehicleHal::getConfigFile() const {
+    std::scoped_lock lockGuard(mConfigInitLock);
+    if (!mConfigInit) {
+        CHECK(getAllPropConfigsFromHardwareLocked())
+                << "Failed to get property configs from hardware";
+        mConfigInit = true;
+    }
+    return mConfigFile.get();
+}
+
+const std::unordered_map<int32_t, VehiclePropConfig>& DefaultVehicleHal::getConfigsByPropId()
+        const {
+    std::scoped_lock lockGuard(mConfigInitLock);
+    if (!mConfigInit) {
+        CHECK(getAllPropConfigsFromHardwareLocked())
+                << "Failed to get property configs from hardware";
+        mConfigInit = true;
+    }
+    return mConfigsByPropId;
+}
+
 ScopedAStatus DefaultVehicleHal::getAllPropConfigs(VehiclePropConfigs* output) {
-    if (mConfigFile != nullptr) {
+    const ScopedFileDescriptor* configFile = getConfigFile();
+    const auto& configsByPropId = getConfigsByPropId();
+    if (configFile != nullptr) {
         output->payloads.clear();
-        output->sharedMemoryFd.set(dup(mConfigFile->get()));
+        output->sharedMemoryFd.set(dup(configFile->get()));
         return ScopedAStatus::ok();
     }
-    output->payloads.reserve(mConfigsByPropId.size());
-    for (const auto& [_, config] : mConfigsByPropId) {
+    output->payloads.reserve(configsByPropId.size());
+    for (const auto& [_, config] : configsByPropId) {
         output->payloads.push_back(config);
     }
     return ScopedAStatus::ok();
 }
 
 Result<const VehiclePropConfig*> DefaultVehicleHal::getConfig(int32_t propId) const {
-    auto it = mConfigsByPropId.find(propId);
-    if (it == mConfigsByPropId.end()) {
+    const auto& configsByPropId = getConfigsByPropId();
+    auto it = configsByPropId.find(propId);
+    if (it == configsByPropId.end()) {
         return Error() << "no config for property, ID: " << propId;
     }
     return &(it->second);
@@ -634,9 +659,11 @@
 ScopedAStatus DefaultVehicleHal::getPropConfigs(const std::vector<int32_t>& props,
                                                 VehiclePropConfigs* output) {
     std::vector<VehiclePropConfig> configs;
+    const auto& configsByPropId = getConfigsByPropId();
     for (int32_t prop : props) {
-        if (mConfigsByPropId.find(prop) != mConfigsByPropId.end()) {
-            configs.push_back(mConfigsByPropId[prop]);
+        auto it = configsByPropId.find(prop);
+        if (it != configsByPropId.end()) {
+            configs.push_back(it->second);
         } else {
             return ScopedAStatus::fromServiceSpecificErrorWithMessage(
                     toInt(StatusCode::INVALID_ARG),
@@ -665,13 +692,15 @@
 
 VhalResult<void> DefaultVehicleHal::checkSubscribeOptions(
         const std::vector<SubscribeOptions>& options) {
+    const auto& configsByPropId = getConfigsByPropId();
     for (const auto& option : options) {
         int32_t propId = option.propId;
-        if (mConfigsByPropId.find(propId) == mConfigsByPropId.end()) {
+        auto it = configsByPropId.find(propId);
+        if (it == configsByPropId.end()) {
             return StatusError(StatusCode::INVALID_ARG)
                    << StringPrintf("no config for property, ID: %" PRId32, propId);
         }
-        const VehiclePropConfig& config = mConfigsByPropId[propId];
+        const VehiclePropConfig& config = it->second;
         std::vector<VehicleAreaConfig> areaConfigs;
         if (option.areaIds.empty()) {
             areaConfigs = config.areaConfigs;
@@ -744,10 +773,11 @@
     }
     std::vector<SubscribeOptions> onChangeSubscriptions;
     std::vector<SubscribeOptions> continuousSubscriptions;
+    const auto& configsByPropId = getConfigsByPropId();
     for (const auto& option : options) {
         int32_t propId = option.propId;
         // We have already validate config exists.
-        const VehiclePropConfig& config = mConfigsByPropId[propId];
+        const VehiclePropConfig& config = configsByPropId.at(propId);
 
         SubscribeOptions optionCopy = option;
         // If areaIds is empty, subscribe to all areas.
@@ -871,7 +901,7 @@
         (areaConfig == nullptr || !hasRequiredAccess(areaConfig->access, accessToTest))) {
         return StatusError(StatusCode::ACCESS_DENIED)
                << StringPrintf("Property %" PRId32 " does not have the following access: %" PRId32,
-                               propId, accessToTest);
+                               propId, static_cast<int32_t>(accessToTest));
     }
     return {};
 }
@@ -936,17 +966,19 @@
     }
     DumpResult result = mVehicleHardware->dump(options);
     if (result.refreshPropertyConfigs) {
-        getAllPropConfigsFromHardware();
+        std::scoped_lock lockGuard(mConfigInitLock);
+        getAllPropConfigsFromHardwareLocked();
     }
     dprintf(fd, "%s", (result.buffer + "\n").c_str());
     if (!result.callerShouldDumpState) {
         return STATUS_OK;
     }
     dprintf(fd, "Vehicle HAL State: \n");
+    const auto& configsByPropId = getConfigsByPropId();
     {
         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, "Containing %zu property configs\n", configsByPropId.size());
         dprintf(fd, "Currently have %zu getValues clients\n", mGetValuesClients.size());
         dprintf(fd, "Currently have %zu setValues clients\n", mSetValuesClients.size());
         dprintf(fd, "Currently have %zu subscribe clients\n", countSubscribeClients());
diff --git a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp b/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
index f1106ee..14ee707 100644
--- a/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/src/SubscriptionManager.cpp
@@ -40,6 +40,7 @@
 using ::android::base::StringPrintf;
 using ::ndk::ScopedAStatus;
 
+constexpr float EPSILON = 0.0000001;
 constexpr float ONE_SECOND_IN_NANOS = 1'000'000'000.;
 
 SubscribeOptions newSubscribeOptions(int32_t propId, int32_t areaId, float sampleRateHz,
@@ -88,7 +89,7 @@
     }
 
     float log = std::log10(resolution);
-    return log == (int)log;
+    return std::abs(log - std::round(log)) < EPSILON;
 }
 
 void ContSubConfigs::refreshCombinedConfig() {
@@ -433,6 +434,9 @@
         }
 
         for (const auto& [client, callback] : mClientsByPropIdAreaId[propIdAreaId]) {
+            // if propId is on-change, propIdAreaId will not exist in mContSubConfigsByPropIdArea,
+            // returning an empty ContSubConfigs value for subConfigs i.e. with resolution = 0 and
+            // enableVur = false.
             auto& subConfigs = mContSubConfigsByPropIdArea[propIdAreaId];
             // Clients must be sent different VehiclePropValues with different levels of granularity
             // as requested by the client using resolution.
diff --git a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp b/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
index f377202..440a9f9 100644
--- a/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
+++ b/automotive/vehicle/aidl/impl/vhal/test/SubscriptionManagerTest.cpp
@@ -521,6 +521,8 @@
 }
 
 TEST_F(SubscriptionManagerTest, testCheckResolutionValid) {
+    ASSERT_TRUE(SubscriptionManager::checkResolution(0.0));
+    ASSERT_TRUE(SubscriptionManager::checkResolution(0.1));
     ASSERT_TRUE(SubscriptionManager::checkResolution(1.0));
 }
 
diff --git a/automotive/vehicle/aidl_property/Android.bp b/automotive/vehicle/aidl_property/Android.bp
index 2aaf6b6..b8a978b 100644
--- a/automotive/vehicle/aidl_property/Android.bp
+++ b/automotive/vehicle/aidl_property/Android.bp
@@ -28,7 +28,7 @@
         // This HAL was originally part of android.hardware.automotive.vehicle
         "android/hardware/automotive/vehicle/*.aidl",
     ],
-    frozen: true,
+    frozen: false,
     stability: "vintf",
     backend: {
         cpp: {
diff --git a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
index be8d3ac..4c5dad2 100644
--- a/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/aidl_api/android.hardware.automotive.vehicle.property/current/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -262,6 +262,7 @@
   CLUSTER_HEARTBEAT = (((0x0F4B + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.MIXED) /* 299896651 */,
   VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL = (((0x0F4C + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289410892 */,
   CAMERA_SERVICE_CURRENT_STATE = (((0x0F4D + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 289476429 */,
+  PER_DISPLAY_MAX_BRIGHTNESS = (((0x0F4E + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32_VEC) /* 289476430 */,
   AUTOMATIC_EMERGENCY_BRAKING_ENABLED = (((0x1000 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313920 */,
   AUTOMATIC_EMERGENCY_BRAKING_STATE = (((0x1001 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.INT32) /* 289411073 */,
   FORWARD_COLLISION_WARNING_ENABLED = (((0x1002 + android.hardware.automotive.vehicle.VehiclePropertyGroup.SYSTEM) + android.hardware.automotive.vehicle.VehicleArea.GLOBAL) + android.hardware.automotive.vehicle.VehiclePropertyType.BOOLEAN) /* 287313922 */,
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
index 540c663..1421f89 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/AutomaticEmergencyBrakingState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Automatic Emergency Braking (AEB).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
index 3f567c0..3c85f29 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/BlindSpotWarningState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Blind Spot Warning State (BSW).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl
index 05be65d..85428b1 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CrossTrafficMonitoringWarningState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Cross Traffic Monitoring Warning system.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
index 18e1405..ab745ce 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlCommand.aidl
@@ -20,6 +20,9 @@
  * Used to enumerate the Cruise Control (CC) commands.
  *
  * This enum could be extended in future releases to include additional feature states.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl
index 0e55e00..b410e41 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlState.aidl
@@ -20,6 +20,9 @@
  * Used to enumerate the current state of Cruise Control (CC).
  *
  * This enum could be extended in future releases to include additional feature states.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl
index 2367b82..ebae16d 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/CruiseControlType.aidl
@@ -20,6 +20,9 @@
  * Used to enumerate the current type of Cruise Control (CC).
  *
  * This enum could be extended in future releases to include additional feature states.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
index f350a6c..d03431d 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionState.aidl
@@ -20,6 +20,9 @@
  * Used to enumerate the current state of driver distraction monitoring.
  *
  * This enum could be extended in future releases to include additional feature states.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
index a4b1984..e145be2 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDistractionWarning.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the current warning state of the driver distraction monitoring system.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
index d2aec1f..f94479b 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionState.aidl
@@ -20,6 +20,9 @@
  * Used to enumerate the current state of driver drowsiness and attention monitoring.
  *
  * This enum could be extended in future releases to include additional feature states.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
index 53b66b9..efa12a4 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/DriverDrowsinessAttentionWarning.aidl
@@ -19,6 +19,9 @@
 /**
  * Used to enumerate the current warning state of the driver drowsiness and attention monitoring
  * system.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl
index 006bbf2..bc9148a 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicStabilityControlState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Electronic Stability Control (ESC).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
index 94209ba..ce4def1 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardStatus.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used by ELECTRONIC_TOLL_COLLECTION_CARD_STATUS.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
index 46c5f48..0be981c 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ElectronicTollCollectionCardType.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used by ELECTRONIC_TOLL_COLLECTION_CARD_TYPE.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
index 302b9af..bbc8d3b 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EmergencyLaneKeepAssistState.aidl
@@ -20,6 +20,9 @@
  * Used by emergency lane keep assist to enumerate state.
  *
  * This enum could be extended in future releases to include additional feature states.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl
index ba44672..5b13ec9 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ErrorState.aidl
@@ -19,6 +19,9 @@
 /**
  * Used to enumerate the possible error states. For version 2 of this interface, ErrorState is used
  * by ADAS STATE properties, but its use may be expanded in future releases.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvChargeState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvChargeState.aidl
index e095fc4..ec533e1 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvChargeState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvChargeState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used by EV charging properties to enumerate the current state of the battery charging.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
index 6e77f53..7891dd9 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvConnectorType.aidl
@@ -28,16 +28,65 @@
      * type.
      */
     UNKNOWN = 0,
+    /**
+     * IEC 62196 Type 1 connector
+     *
+     * Also known as the "Yazaki connector" or "J1772 connector".
+     */
     IEC_TYPE_1_AC = 1,
+    /**
+     * IEC 62196 Type 2 connector
+     *
+     * Also known as the "Mennekes connector".
+     */
     IEC_TYPE_2_AC = 2,
+    /**
+     * IEC 62196 Type 3 connector
+     *
+     * Also known as the "Scame connector".
+     */
     IEC_TYPE_3_AC = 3,
+    /**
+     * IEC 62196 Type AA connector
+     *
+     * Also known as the "Chademo connector".
+     */
     IEC_TYPE_4_DC = 4,
+    /**
+     * IEC 62196 Type EE connector
+     *
+     * Also known as the “CCS1 connector” or “Combo1 connector".
+     */
     IEC_TYPE_1_CCS_DC = 5,
+    /**
+     * IEC 62196 Type EE connector
+     *
+     * Also known as the “CCS2 connector” or “Combo2 connector”.
+     */
     IEC_TYPE_2_CCS_DC = 6,
+    /**
+     * DO NOT USE
+     *
+     * Connector of Tesla Roadster.
+     */
     TESLA_ROADSTER = 7,
+    /**
+     * DO NOT USE
+     * Use TESLA_SUPERCHARGER instead.
+     *
+     * High Power Wall Charger of Tesla.
+     */
     TESLA_HPWC = 8,
+    /**
+     * SAE J3400 connector
+     *
+     * Also known as the "North American Charging Standard" (NACS)
+     * or the "Tesla charging standard" connector.
+     */
     TESLA_SUPERCHARGER = 9,
+    /** GBT_AC Fast Charging Standard */
     GBT_AC = 10,
+    /** GBT_DC Fast Charging Standard */
     GBT_DC = 11,
     /**
      * Connector type to use when no other types apply. Before using this
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
index 4382287..15372f7 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvRegenerativeBrakingState.aidl
@@ -19,6 +19,9 @@
 /**
  * Used by the regenerative braking property to enumerate the current state
  * of the regenerative braking.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl
index 8c5ac46..c82b8a8 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/EvStoppingMode.aidl
@@ -20,6 +20,9 @@
  * Used by EV_STOPPING_MODE to enumerate the current state of the stopping mode.
  *
  * This enum may be extended to include more states in the future.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
index b20cf25..69dce89 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ForwardCollisionWarningState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Forward Collision Warning State (FCW).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
index 4a36999..c9f9322 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionDriverState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the current driver state of Hands On Detection (HOD).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
index c1a58ce..dd6a78f 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/HandsOnDetectionWarning.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the current warning state of Hands On Detection (HOD).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
index 0fc1a50..b0a6a60 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/ImpactSensorLocation.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the various impact sensor locations on the car.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
index d8b0e65..bf8a6df 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistCommand.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used by Lane Centering Assist (LCA) to enumerate commands.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
index 340a669..eb8e9c8 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneCenteringAssistState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Lane Centering Assist (LCA).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
index c12c5765..21eeaa5 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneDepartureWarningState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Lane Departure Warning (LDW).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
index c1c15a0..8c77086 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LaneKeepAssistState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Lane Keep Assist (LKA).
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
index 978da25..c2cb51a 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedAutomaticEmergencyBrakingState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Low Speed Automatic Emergency Braking.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
index 028a2d9..fd410d8 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/LowSpeedCollisionWarningState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the state of Low Speed Collision Warning State.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl
index ef65374..d31fb25 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/TrailerState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the current state of VehicleProperty#TRAILER_PRESENT.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
index e4c43f7..a029ed8 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAirbagLocation.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the various airbag locations per seat.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
index 3860e7f..4a48e97 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleAutonomousState.aidl
@@ -19,6 +19,9 @@
 /**
  * Used to enumerate the various level of automation that can be expressed by the
  * VEHICLE_DRIVING_AUTOMATION_CURRENT_LEVEL property.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleGear.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleGear.aidl
index 40e492e..2fd94c7 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleGear.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleGear.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Various gears which can be selected by user and chosen in system.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
index f5b77de..dc1379d 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleHvacFanDirection.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Bit flags for fan direction
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
index 4de97f6..bcdc3eb 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleIgnitionState.aidl
@@ -16,6 +16,12 @@
 
 package android.hardware.automotive.vehicle;
 
+/**
+ * Used to enumerate the different states the ignition of the vehicle can be in.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
+ */
 @VintfStability
 @Backing(type="int")
 enum VehicleIgnitionState {
@@ -28,6 +34,10 @@
      * Steering wheel is not locked, engine and all accessories are OFF. If
      * car can be in LOCK and OFF state at the same time than HAL must report
      * LOCK state.
+     *
+     * If IGNITION_STATE is implemented on a BEV, then this state must
+     * communicate that the BEV's High Voltage battery is disconnected and thus
+     * the vehicle is OFF.
      */
     OFF,
     /**
@@ -38,6 +48,10 @@
     /**
      * Ignition is in state ON. Accessories and instrument cluster available,
      * engine might be running or ready to be started.
+     *
+     * If IGNITION_STATE is implemented on a BEV, then this state must
+     * communicate that the BEV's High Voltage battery is connected and thus the
+     * vehicle is ON.
      */
     ON,
     /**
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightState.aidl
index ede20b7..e7ed13c 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightState.aidl
@@ -21,6 +21,9 @@
  *
  * Most XXX_LIGHTS_STATE properties will only report ON and OFF states.  Only
  * the HEADLIGHTS_STATE property will report DAYTIME_RUNNING.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
index 247e731..d147404 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleLightSwitch.aidl
@@ -22,6 +22,9 @@
  * XXX_LIGHTS_SWITCH properties report the switch settings that the user
  * selects.  The switch setting may be decoupled from the state reported if the
  * user selects AUTOMATIC.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
index 3c722ba..acc4201 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleOilLevel.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the current level of VehicleProperty#ENGINE_OIL_LEVEL.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
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 6f5c0c1..0863adf 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleProperty.aidl
@@ -59,6 +59,8 @@
     /**
      * Manufacturer of vehicle
      *
+     * This property must communicate the vehicle's public brand name.
+     *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @version 2
@@ -68,6 +70,8 @@
     /**
      * Model of vehicle
      *
+     * This property must communicate the vehicle's public model name.
+     *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @version 2
@@ -87,6 +91,11 @@
     /**
      * Fuel capacity of the vehicle in milliliters
      *
+     * This property must communicate the maximum amount of the fuel that can be stored in the
+     * vehicle in milliliters. This property does not apply to electric vehicles. That is, if
+     * INFO_FUEL_TYPE only contains FuelType::FUEL_TYPE_ELECTRIC, this property must not be
+     * implemented. For EVs, implement INFO_EV_BATTERY_CAPACITY.
+     *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit.MILLILITER
@@ -102,7 +111,7 @@
      *   An FHEV (Fully Hybrid Electric Vehicle) must not include FuelType::FUEL_TYPE_ELECTRIC in
      *   INFO_FUEL_TYPE's INT32_VEC value. So INFO_FUEL_TYPE can be populated as such:
      *     int32Values = { FuelType::FUEL_TYPE_UNLEADED }
-     *   On the other hand, a PHEV (Partially Hybrid Electric Vehicle) is plug in rechargeable, and
+     *   On the other hand, a PHEV (Plug-in Hybrid Electric Vehicle) is plug in rechargeable, and
      *   hence should include FuelType::FUEL_TYPE_ELECTRIC in INFO_FUEL_TYPE's INT32_VEC value. So
      *   INFO_FUEL_TYPE can be populated as such:
      *     int32Values = { FuelType::FUEL_TYPE_UNLEADED, FuelType::FUEL_TYPE_ELECTRIC }
@@ -115,12 +124,13 @@
     INFO_FUEL_TYPE = 0x0105 + 0x10000000 + 0x01000000
             + 0x00410000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32_VEC
     /**
-     * Nominal battery capacity for EV or hybrid vehicle
+     * Nominal usable battery capacity for EV or hybrid vehicle
      *
-     * Returns the nominal battery capacity, if EV or hybrid. This is the battery capacity when the
-     * vehicle is new. This value might be different from EV_CURRENT_BATTERY_CAPACITY because
-     * EV_CURRENT_BATTERY_CAPACITY returns the real-time battery capacity taking into account
-     * factors such as battery aging and temperature dependency.
+     * Returns the nominal battery capacity, if EV or hybrid. This is the total usable battery
+     * capacity when the vehicle is new. This value might be different from
+     * EV_CURRENT_BATTERY_CAPACITY because EV_CURRENT_BATTERY_CAPACITY returns the real-time usable
+     * battery capacity taking into account factors such as battery aging and temperature
+     * dependency.
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
@@ -132,6 +142,9 @@
     /**
      * List of connectors this EV may use
      *
+     * If the vehicle has multiple charging ports, this property must return all possible connector
+     * types that can be used by at least one charging port on the vehicle.
+     *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @data_enum EvConnectorType
      * @access VehiclePropertyAccess.READ
@@ -142,6 +155,11 @@
     /**
      * Fuel door location
      *
+     * This property must communicate the location of the fuel door on the vehicle. This property
+     * does not apply to electric vehicles. That is, if INFO_FUEL_TYPE only contains
+     * FuelType::FUEL_TYPE_ELECTRIC, this property must not be implemented. For EVs, implement
+     * INFO_EV_PORT_LOCATION or INFO_MULTI_EV_PORT_LOCATIONS.
+     *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @data_enum PortLocationType
      * @access VehiclePropertyAccess.READ
@@ -152,6 +170,11 @@
     /**
      * EV port location
      *
+     * This property must communicate the location of the charging port on the EV using the
+     * PortLocationType enum. If there are multiple ports available on the vehicle, this property
+     * must return the port that allows the fastest charging. To communicate all port locations,
+     * use INFO_MULTI_EV_PORT_LOCATIONS.
+     *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
      * @data_enum PortLocationType
@@ -196,7 +219,10 @@
      * Port locations are defined in PortLocationType.
      * For example, a car has one port in front left and one port in rear left:
      *   int32Values[0] = PortLocationType::FRONT_LEFT
-     *   int32Values[0] = PortLocationType::REAR_LEFT
+     *   int32Values[1] = PortLocationType::REAR_LEFT
+     *
+     * If only one port exists on the vehicle, this property's value should list just one element.
+     * See INFO_EV_PORT_LOCATION for describing just one port location.
      *
      * @change_mode VehiclePropertyChangeMode.STATIC
      * @access VehiclePropertyAccess.READ
@@ -249,6 +275,10 @@
      *
      * Angle is in degrees.  Left is negative.
      *
+     * This property is independent of the angle of the steering wheel. This property must
+     * communicate the angle of the front wheels with respect to the vehicle, not the angle of the
+     * steering wheel.
+     *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit.DEGREES
@@ -261,6 +291,10 @@
      *
      * Angle is in degrees.  Left is negative.
      *
+     * This property is independent of the angle of the steering wheel. This property must
+     * communicate the angle of the rear wheels with respect to the vehicle, not the angle of the
+     * steering wheel.
+     *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit.DEGREES
@@ -350,9 +384,14 @@
     WHEEL_TICK = 0x0306 + 0x10000000 + 0x01000000
             + 0x00510000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64_VEC
     /**
-     * Fuel remaining in the vehicle, in milliliters
+     * Fuel level in milliliters
      *
-     * Value may not exceed INFO_FUEL_CAPACITY
+     * This property must communicate the current amount of fuel remaining in the vehicle in
+     * milliliters. This property does not apply to electric vehicles. That is, if INFO_FUEL_TYPE
+     * only contains FuelType::FUEL_TYPE_ELECTRIC, this property must not be implemented. For EVs,
+     * implement EV_BATTERY_LEVEL.
+     *
+     * Value may not exceed INFO_FUEL_CAPACITY.
      *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
@@ -364,6 +403,11 @@
     /**
      * Fuel door open
      *
+     * This property must communicate whether the fuel door on the vehicle is open or not. This
+     * property does not apply to electric vehicles. That is, if INFO_FUEL_TYPE only contains
+     * FuelType::FUEL_TYPE_ELECTRIC, this property must not be implemented. For EVs, implement
+     * EV_CHARGE_PORT_OPEN.
+     *
      * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
      * implement it as VehiclePropertyAccess.READ only.
      *
@@ -389,12 +433,13 @@
     EV_BATTERY_LEVEL = 0x0309 + 0x10000000 + 0x01000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:FLOAT
     /**
-     * Current battery capacity for EV or hybrid vehicle
+     * Current usable battery capacity for EV or hybrid vehicle
      *
      * Returns the actual value of battery capacity, if EV or hybrid. This property captures the
-     * real-time battery capacity taking into account factors such as battery aging and temperature
-     * dependency. Therefore, this value might be different from INFO_EV_BATTERY_CAPACITY because
-     * INFO_EV_BATTERY_CAPACITY returns the nominal battery capacity from when the vehicle was new.
+     * real-time usable battery capacity taking into account factors such as battery aging and
+     * temperature dependency. Therefore, this value might be different from
+     * INFO_EV_BATTERY_CAPACITY because INFO_EV_BATTERY_CAPACITY returns the nominal battery
+     * capacity from when the vehicle was new.
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
@@ -406,6 +451,9 @@
     /**
      * EV charge port open
      *
+     * If the vehicle has multiple charging ports, this property must return true if any of the
+     * charge ports are open.
+     *
      * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
      * implement it as VehiclePropertyAccess.READ only.
      *
@@ -419,6 +467,9 @@
     /**
      * EV charge port connected
      *
+     * If the vehicle has multiple charging ports, this property must return true if any of the
+     * charge ports are connected.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @version 2
@@ -625,8 +676,12 @@
      * The maxInt32Value and minInt32Value in VehicleAreaConfig must be defined. All values between
      * minInt32Value and maxInt32Value must be supported. The minInt32Value must be 0.
      *
-     * The maxInt32Value indicates the maximum amount of energy regenerated from braking. The
-     * minInt32Value indicates no regenerative braking.
+     * The maxInt32Value indicates the setting for the maximum amount of energy regenerated from
+     * braking. The minInt32Value indicates the setting for no regenerative braking.
+     *
+     * This property is a more granular form of EV_REGENERATIVE_BRAKING_STATE. It allows the user to
+     * set a more specific level of regenerative braking if the states in EvRegenerativeBrakingState
+     * are not granular enough for the OEM.
      *
      * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
      * implement it as VehiclePropertyAccess.READ only.
@@ -772,7 +827,7 @@
      * @access VehiclePropertyAccess.READ
      * @data_enum ElectronicStabilityControlState
      * @data_enum ErrorState
-     * @version 2
+     * @version 3
      */
     ELECTRONIC_STABILITY_CONTROL_STATE =
             0x040F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.INT32,
@@ -868,10 +923,18 @@
     HVAC_TEMPERATURE_CURRENT = 0x0502 + 0x10000000 + 0x05000000
             + 0x00600000, // VehiclePropertyGroup:SYSTEM,VehicleArea:SEAT,VehiclePropertyType:FLOAT
     /**
-     * HVAC, target temperature set.
+     * HVAC target temperature set in Celsius.
      *
-     * The configArray is used to indicate the valid values for HVAC in Fahrenheit and Celsius.
-     * Android might use it in the HVAC app UI.
+     * The minFloatValue and maxFloatValue in VehicleAreaConfig must be defined.
+     *
+     * The minFloatValue indicates the minimum temperature setting in Celsius.
+     * The maxFloatValue indicates the maximum temperature setting in Celsius.
+     *
+     * If all the values between minFloatValue and maxFloatValue are not supported, the configArray
+     * can be used to list the valid temperature values that can be set. It also describes a lookup
+     * table to convert the temperature from Celsius to Fahrenheit and vice versa for this vehicle.
+     * The configArray must be defined if standard unit conversion is not supported on this vehicle.
+     *
      * The configArray is set as follows:
      *      configArray[0] = [the lower bound of the supported temperature in Celsius] * 10.
      *      configArray[1] = [the upper bound of the supported temperature in Celsius] * 10.
@@ -879,14 +942,35 @@
      *      configArray[3] = [the lower bound of the supported temperature in Fahrenheit] * 10.
      *      configArray[4] = [the upper bound of the supported temperature in Fahrenheit] * 10.
      *      configArray[5] = [the increment in Fahrenheit] * 10.
+     *
+     * The minFloatValue and maxFloatValue in VehicleAreaConfig must be equal to configArray[0] and
+     * configArray[1] respectively.
+     *
      * For example, if the vehicle supports temperature values as:
      *      [16.0, 16.5, 17.0 ,..., 28.0] in Celsius
-     *      [60.5, 61.5, 62.5 ,..., 85.5] in Fahrenheit.
-     * The configArray should be configArray = {160, 280, 5, 605, 825, 10}.
+     *      [60.5, 61.5, 62.5 ,..., 84.5] in Fahrenheit
+     * The configArray should be configArray = {160, 280, 5, 605, 845, 10}.
      *
-     * If the vehicle supports HVAC_TEMPERATURE_VALUE_SUGGESTION, the application can use
-     * that property to get the suggested value before setting HVAC_TEMPERATURE_SET. Otherwise,
-     * the application may choose the value in HVAC_TEMPERATURE_SET configArray by itself.
+     * Ideally, the ratio of the Celsius increment to the Fahrenheit increment should be as close to
+     * the actual ratio of 1 degree Celsius to 1.8 degrees Fahrenheit.
+     *
+     * There must be a one to one mapping of all Celsius values to Fahrenheit values defined by the
+     * configArray. The configArray will be used by clients to convert this property's temperature
+     * from Celsius to Fahrenheit. Also, it will let clients know what Celsius value to set the
+     * property to achieve their desired Fahreneheit value for the system. If the ECU does not have
+     * a one to one mapping of all Celsius values to Fahrenheit values, then the config array should
+     * only define the list of Celsius and Fahrenheit values that do have a one to one mapping.
+     *
+     * For example, if the ECU supports Celsius values from 16 to 28 and Fahrenheit values from 60
+     * to 85 both with an increment of 1, then one possible configArray would be {160, 280, 10, 600,
+     * 840, 20}. In this case, 85 would not be a supported temperature.
+     *
+     * Any value set in between a valid value should be rounded to the closest valid value.
+     *
+     * It is highly recommended that the OEM also implement the HVAC_TEMPERATURE_VALUE_SUGGESTION
+     * vehicle property because it provides applications a simple method for determining temperature
+     * values that can be set for this vehicle and for converting values between Celsius and
+     * Fahrenheit.
      *
      * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
      * implement it as VehiclePropertyAccess.READ only.
@@ -1295,7 +1379,22 @@
      *
      * An application calls set(VehiclePropValue propValue) with the requested value and unit for
      * the value. OEMs need to return the suggested values in floatValues[2] and floatValues[3] by
-     * onPropertyEvent() callbacks.
+     * onPropertyEvent() callbacks. The suggested values must conform to the values that can be
+     * derived from the HVAC_TEMPERATURE_SET configArray. In other words, the suggested values and
+     * the table of values from the configArray should be the same. It is recommended for the OEM to
+     * add custom logic in their VHAL implementation in order to avoid making requests to the HVAC
+     * ECU.
+     *
+     * The logic can be as follows:
+     * For converting the temperature from celsius to fahrenheit use the following:
+     * // Given tempC and the configArray
+     * float minTempC = configArray[0] / 10.0;
+     * float temperatureIncrementCelsius = configArray[2] / 10.0;
+     * float minTempF = configArray[3] / 10.0;
+     * float temperatureIncrementFahrenheit = configArray[5] / 10.0;
+     * // Round to the closest increment
+     * int numIncrements = round((tempC - minTempC) / temperatureIncrementCelsius);
+     * tempF = temperatureIncrementFahrenheit * numIncrements + minTempF;
      *
      * For example, when a user uses the voice assistant to set HVAC temperature to 66.2 in
      * Fahrenheit.
@@ -1557,6 +1656,11 @@
     /**
      * Outside temperature
      *
+     * This property must communicate the temperature reading of the environment outside the
+     * vehicle. If there are multiple sensors for measuring the outside temperature, this property
+     * should be populated with the mean or a meaningful weighted average of the readings that will
+     * best represent the temperature of the outside environment.
+     *
      * @change_mode VehiclePropertyChangeMode.CONTINUOUS
      * @access VehiclePropertyAccess.READ
      * @unit VehicleUnit.CELSIUS
@@ -1630,8 +1734,13 @@
      * change display brightness from Settings, but that must not be reflected
      * to other displays.
      *
+     * If this is writable, writing this property must cause an on property
+     * change event even if the new display brightness is the same as the
+     * current value.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
+     * @access VehiclePropertyAccess.READ
      * @version 2
      */
     DISPLAY_BRIGHTNESS = 0x0A03 + 0x10000000 + 0x01000000
@@ -1648,9 +1757,24 @@
      * implemented. If both are available, PER_DISPLAY_BRIGHTNESS is used by
      * AAOS.
      *
+     * If this is supported, PER_DISPLAY_MAX_BRIGHTNESS must be supported to represent the max
+     * display brightness for each display. Otherwise, the max display brightness is by default 1.
+     * The VehicleAreaConfig.maxInt32Value must not be used to represent max display brightness,
+     * because maxInt32Value is defined to be the max value for all the elements inside the integer
+     * value, which includes display port and brightness. So it is not meaningful.
+     *
      * The display port uniquely identifies a physical connector on the device
      * for display output, ranging from 0 to 255.
      *
+     * Writing this property must cause an on property change event that
+     * contains the same [display port, brightness] tuple even if the new
+     * display brightness is the same as the current value.
+     *
+     * To get the display brightness for a specific display port, the
+     * GetValueRequest must contain a VehiclePropValue, which contains one
+     * int32Value: displayPort. Getting this property without specifying the
+     * the display port is undefined behavior.
+     *
      * int32Values[0] : display port
      * int32Values[1] : brightness
      *
@@ -2909,7 +3033,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
-     * @version 3
+     * @version 2
      */
     SEAT_AIRBAG_ENABLED =
             0x0B9E + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.BOOLEAN,
@@ -2932,7 +3056,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum VehicleAirbagLocation
-     * @version 2
+     * @version 3
      */
     SEAT_AIRBAGS_DEPLOYED =
             0x0BA5 + VehiclePropertyGroup.SYSTEM + VehicleArea.SEAT + VehiclePropertyType.INT32,
@@ -3182,9 +3306,9 @@
     WINDOW_MOVE = 0x0BC1 + 0x10000000 + 0x03000000
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:WINDOW,VehiclePropertyType:INT32
     /**
-     * Window Lock
+     * Window Child Lock
      *
-     * True indicates windows are locked and can't be moved.
+     * True indicates the window is child-locked.
      *
      * This property is defined as VehiclePropertyAccess.READ_WRITE, but OEMs have the option to
      * implement it as VehiclePropertyAccess.READ only.
@@ -4822,6 +4946,10 @@
      *
      * Returns the current charging state of the car.
      *
+     * If the vehicle has a target charge percentage other than 100, this property must return
+     * EvChargeState::STATE_FULLY_CHARGED when the battery charge level has reached the target
+     * level. See EV_CHARGE_PERCENT_LIMIT for more context.
+     *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
      * @data_enum EvChargeState
@@ -4861,10 +4989,13 @@
             + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32
 
     /**
-     * Regenerative braking or one-pedal drive state of the car
+     * Regenerative braking or one-pedal drive setting of the car
      *
-     * Returns the current state associated with the regenerative braking
-     * setting in the car
+     * Returns the current setting associated with the regenerative braking setting in the car
+     *
+     * If the OEM requires more setting than those provided in EvRegenerativeBrakingState, the
+     * EV_BRAKE_REGENERATION_LEVEL property can be used instead, which provides a more granular
+     * way of providing the same information.
      *
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ
@@ -5089,6 +5220,27 @@
     CAMERA_SERVICE_CURRENT_STATE = 0x0F4D + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL
             + VehiclePropertyType.INT32_VEC,
 
+    /**
+     * Property to represent max brightness of the displays which are controlled separately.
+     *
+     * This is only used if PER_DISPLAY_BRIGHTNESS is supported.
+     *
+     * The display port uniquely identifies a physical connector on the device
+     * for display output, ranging from 0 to 255.
+     *
+     * int32Values[0] : display port number
+     * int32Values[1] : max brightness for display port number specified at int32Values[0]
+     * int32Values[2] : display port number
+     * int32Values[3] : max brightness for display port number specified at int32Values[2]
+     * ...
+     *
+     * @change_mode VehiclePropertyChangeMode.STATIC
+     * @access VehiclePropertyAccess.READ
+     * @version 3
+     */
+    PER_DISPLAY_MAX_BRIGHTNESS = 0x0F4E + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL
+            + VehiclePropertyType.INT32_VEC,
+
     /***********************************************************************************************
      * Start of ADAS Properties
      *
@@ -5868,7 +6020,7 @@
      * @change_mode VehiclePropertyChangeMode.ON_CHANGE
      * @access VehiclePropertyAccess.READ_WRITE
      * @access VehiclePropertyAccess.READ
-     * @version 2
+     * @version 3
      */
     DRIVER_DISTRACTION_WARNING_ENABLED =
             0x101F + VehiclePropertyGroup.SYSTEM + VehicleArea.GLOBAL + VehiclePropertyType.BOOLEAN,
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
index 3a08a51..266d3f9 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/VehicleSeatOccupancyState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used by seat occupancy to enumerate the current occupancy state of the seat.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
index 820fcc8..953a80d 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersState.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the current state of VehicleProperty#WINDSHIELD_WIPERS_STATE.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
index 911d7eb..4ef16b5 100644
--- a/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
+++ b/automotive/vehicle/aidl_property/android/hardware/automotive/vehicle/WindshieldWipersSwitch.aidl
@@ -18,6 +18,9 @@
 
 /**
  * Used to enumerate the current position of VehicleProperty#WINDSHIELD_WIPERS_SWITCH.
+ *
+ * Through the use of VehicleAreaConfig#supportedEnumValues, OEMs may specify they only support a
+ * subset of the enums that are defined here.
  */
 @VintfStability
 @Backing(type="int")
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
index f279767..460e9f9 100755
--- a/automotive/vehicle/tools/generate_annotation_enums.py
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -17,9 +17,9 @@
 """A script to generate Java files and CPP header files based on annotations in VehicleProperty.aidl
 
    Need ANDROID_BUILD_TOP environmental variable to be set. This script will update
-   ChangeModeForVehicleProperty.h and AccessForVehicleProperty.h under generated_lib/cpp and
+   ChangeModeForVehicleProperty.h and AccessForVehicleProperty.h under generated_lib/version/cpp and
    ChangeModeForVehicleProperty.java, AccessForVehicleProperty.java, EnumForVehicleProperty.java
-   UnitsForVehicleProperty.java under generated_lib/java.
+   UnitsForVehicleProperty.java under generated_lib/version/java.
 
    Usage:
    $ python generate_annotation_enums.py
@@ -31,22 +31,20 @@
 import sys
 import tempfile
 
+# Keep this updated with the latest in-development property version.
+PROPERTY_VERSION = '4'
+
 PROP_AIDL_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl_property/android/hardware/' +
     'automotive/vehicle/VehicleProperty.aidl')
-CHANGE_MODE_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
-    'ChangeModeForVehicleProperty.h')
-ACCESS_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
-    'AccessForVehicleProperty.h')
-CHANGE_MODE_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
-    'ChangeModeForVehicleProperty.java')
-ACCESS_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
-    'AccessForVehicleProperty.java')
-ENUM_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
-                         'EnumForVehicleProperty.java')
-UNITS_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
-                       'UnitsForVehicleProperty.java')
-VERSION_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
-    'VersionForVehicleProperty.h')
+GENERATED_LIB = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/' + PROPERTY_VERSION +
+        '/')
+CHANGE_MODE_CPP_FILE_PATH = GENERATED_LIB + '/cpp/ChangeModeForVehicleProperty.h'
+ACCESS_CPP_FILE_PATH = GENERATED_LIB + '/cpp/AccessForVehicleProperty.h'
+CHANGE_MODE_JAVA_FILE_PATH = GENERATED_LIB + '/java/ChangeModeForVehicleProperty.java'
+ACCESS_JAVA_FILE_PATH = GENERATED_LIB + '/java/AccessForVehicleProperty.java'
+ENUM_JAVA_FILE_PATH = GENERATED_LIB + '/java/EnumForVehicleProperty.java'
+UNITS_JAVA_FILE_PATH = GENERATED_LIB + '/java/UnitsForVehicleProperty.java'
+VERSION_CPP_FILE_PATH = GENERATED_LIB + '/cpp/VersionForVehicleProperty.h'
 SCRIPT_PATH = 'hardware/interfaces/automotive/vehicle/tools/generate_annotation_enums.py'
 
 TAB = '    '
diff --git a/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java b/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
index 8e12f67..bea5951 100644
--- a/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
+++ b/automotive/vehicle/tools/generate_emu_metadata/src/com/android/car/tool/EmuMetadataGenerator.java
@@ -47,7 +47,9 @@
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.lang.reflect.Field;
+import java.text.Collator;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -93,6 +95,8 @@
     private static final String CHECK_FILE_PATH =
             "${ANDROID_BUILD_TOP}/hardware/interfaces/automotive/vehicle/aidl/emu_metadata/"
             + "android.hardware.automotive.vehicle-types-meta.json";
+    private static final List<String> ANNOTATIONS =
+            List.of("@change_mode", "@access", "@version", "@data_enum", "@unit");
 
     // Emulator can display at least this many characters before cutting characters.
     private static final int MAX_PROPERTY_NAME_LENGTH = 30;
@@ -139,6 +143,7 @@
         public String name;
         public Integer value;
         public final List<String> dataEnums = new ArrayList<>();
+        public String description = "";
 
         ValueField(String name, Integer value) {
             this.name = name;
@@ -311,17 +316,38 @@
 
             int propertyId = parseIntEnumField(propertyDef);
             // We use the first paragraph as the property's name
-            String propertyDescription = doc.getDescription().toText().split("\n\n")[0];
-            String name = propertyDescription;
-            if (propertyDescription.indexOf("\n") != -1
-                    || propertyDescription.length() > MAX_PROPERTY_NAME_LENGTH) {
+            String propertyDescription = doc.getDescription().toText();
+            String firstLine = propertyDescription.split("\n\n")[0];
+            String name = firstLine;
+            if (firstLine.indexOf("\n") != -1 || firstLine.length() > MAX_PROPERTY_NAME_LENGTH) {
                 // The description is too long, we just use the property name.
                 name = propertyName;
             }
+
             ValueField field = new ValueField(name, propertyId);
+            String fieldDescription = "";
+            for (String line : propertyDescription.split("\n")) {
+                String stripped = line.strip();
+                // If this is an empty line, starts a new paragraph.
+                if (stripped.isEmpty()) {
+                    fieldDescription += "\n";
+                }
+                // Ignore annotation lines.
+                for (int j = 0; j < ANNOTATIONS.size(); j++) {
+                    if (stripped.startsWith(ANNOTATIONS.get(j))) {
+                        continue;
+                    }
+                }
+                // If this is a new line, we concat it with the previous line with a space.
+                if (!fieldDescription.isEmpty()
+                        && fieldDescription.charAt(fieldDescription.length() - 1) != '\n') {
+                    fieldDescription += " ";
+                }
+                fieldDescription += stripped;
+            }
+            field.description = fieldDescription.strip();
 
             List<JavadocBlockTag> blockTags = doc.getBlockTags();
-            List<Integer> dataEnums = new ArrayList<>();
             for (int j = 0; j < blockTags.size(); j++) {
                 String commentTagName = blockTags.get(j).getTagName();
                 String commentTagContent = blockTags.get(j).getContent().toText();
@@ -344,6 +370,16 @@
             enumTypes.add(dataEnum);
         }
 
+        // Sort the enum types based on their packageName, name.
+        // Make sure VehicleProperty is always at the first.
+        Collections.sort(enumTypes.subList(1, enumTypes.size()), (Enum enum1, Enum enum2) -> {
+            var collator = Collator.getInstance();
+            if (enum1.packageName.equals(enum2.packageName)) {
+                return collator.compare(enum1.name, enum2.name);
+            }
+            return collator.compare(enum1.packageName, enum2.packageName);
+        });
+
         // Output enumTypes as JSON to output.
         JSONArray jsonEnums = new JSONArray();
         for (int i = 0; i < enumTypes.size(); i++) {
@@ -370,6 +406,9 @@
                     // entry.
                     jsonValueField.put("data_enum", valueField.dataEnums.get(0));
                 }
+                if (!valueField.description.isEmpty()) {
+                    jsonValueField.put("description", valueField.description);
+                }
                 values.put(jsonValueField);
             }
 
@@ -379,6 +418,7 @@
         try (FileOutputStream outputStream = new FileOutputStream(parsedArgs.output)) {
             outputStream.write(jsonEnums.toString(4).getBytes());
         }
+
         System.out.println("Input at folder: " + parsedArgs.inputDir
                 + " successfully parsed. Output at: " + parsedArgs.output);
 
diff --git a/automotive/vehicle/tools/translate_aidl_enums.py b/automotive/vehicle/tools/translate_aidl_enums.py
index d224f6f..a7c1808 100644
--- a/automotive/vehicle/tools/translate_aidl_enums.py
+++ b/automotive/vehicle/tools/translate_aidl_enums.py
@@ -110,7 +110,7 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import android.test.suitebuilder.annotation.SmallTest;
+import androidx.test.filters.SmallTest;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -228,4 +228,4 @@
         f.write("".join(parser.outputMsgCtsTest))
 
 if __name__ == "__main__":
-    main()
\ No newline at end of file
+    main()
diff --git a/automotive/vehicle/vts/Android.bp b/automotive/vehicle/vts/Android.bp
index 67d0d34..40aec59 100644
--- a/automotive/vehicle/vts/Android.bp
+++ b/automotive/vehicle/vts/Android.bp
@@ -43,7 +43,7 @@
         "vhalclient_defaults",
     ],
     header_libs: [
-        "IVehicleGeneratedHeaders",
+        "IVehicleGeneratedHeaders-V3",
     ],
     test_suites: [
         "general-tests",
diff --git a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
index 4ea6dfe..608a328 100644
--- a/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
+++ b/automotive/vehicle/vts/src/VtsHalAutomotiveVehicle_TargetTest.cpp
@@ -603,6 +603,7 @@
                      << "skip testing";
     }
 
+    // Subscribe to PERF_VEHICLE_SPEED using the max sample rate.
     auto client = mVhalClient->getSubscriptionClient(mCallback);
     ASSERT_NE(client, nullptr) << "Failed to get subscription client";
     SubscribeOptionsBuilder builder(propId);
@@ -616,18 +617,17 @@
                                              ", error: %s",
                                              propId, result.error().message().c_str());
 
-    ASSERT_TRUE(mCallback->waitForExpectedEvents(propId, 1, std::chrono::seconds(2)))
-            << "Must get at least 1 events within 2 seconds after subscription for rate: "
-            << maxSampleRate;
-
     // Sleep for 1 seconds to wait for more possible events to arrive.
     std::this_thread::sleep_for(std::chrono::seconds(1));
 
     client->unsubscribe({propId});
 
     auto events = mCallback->getEvents(propId);
-    if (events.size() == 1) {
-        // We only received one event, the value is not changing so nothing to check here.
+    if (events.size() <= 1) {
+        // We received 0 or 1 event, the value is not changing so nothing to check here.
+        // If all VHAL clients are subscribing to PERF_VEHICLE_SPEED with VUR on, then we
+        // will receive 0 event. If there are other VHAL clients subscribing to PERF_VEHICLE_SPEED
+        // with VUR off, then we will receive 1 event which is the initial value.
         return;
     }
 
@@ -752,9 +752,15 @@
         }
     }
 
-    if (readOnlyPresent && !writeOnlyPresent) {
+    if (readOnlyPresent) {
+        ASSERT_FALSE(writeOnlyPresent) << StringPrintf(
+                "Found both READ_ONLY and WRITE_ONLY access modes in area configs, which is not "
+                "supported");
         maximalAreaAccessSubset = toInt(VehiclePropertyAccess::READ);
     } else if (writeOnlyPresent) {
+        ASSERT_FALSE(readWritePresent) << StringPrintf(
+                "Found both WRITE_ONLY and READ_WRITE access modes in area configs, which is not "
+                "supported");
         maximalAreaAccessSubset = toInt(VehiclePropertyAccess::WRITE);
     } else if (readWritePresent) {
         maximalAreaAccessSubset = toInt(VehiclePropertyAccess::READ_WRITE);
diff --git a/biometrics/OWNERS b/biometrics/OWNERS
index 58998c1..a0a5e51 100644
--- a/biometrics/OWNERS
+++ b/biometrics/OWNERS
@@ -1,8 +1,10 @@
-ilyamaty@google.com
+# Bug component: 879035
+
+include platform/frameworks/base:/services/core/java/com/android/server/biometrics/OWNERS
+
 jeffpu@google.com
 jbolinger@google.com
 joshmccloskey@google.com
 diyab@google.com
 austindelgado@google.com
 spdonghao@google.com
-wenhuiy@google.com
diff --git a/biometrics/common/TEST_MAPPING b/biometrics/common/TEST_MAPPING
new file mode 100644
index 0000000..06e9c53
--- /dev/null
+++ b/biometrics/common/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "postsubmit": [
+    {
+      "name": "android.hardware.biometrics.common.ConfigTest"
+    },
+    {
+      "name": "android.hardware.biometrics.common.WorkerThreadTest"
+    }
+  ]
+}
diff --git a/biometrics/common/config/Config.cpp b/biometrics/common/config/Config.cpp
index 01ae864..49f7cc8 100644
--- a/biometrics/common/config/Config.cpp
+++ b/biometrics/common/config/Config.cpp
@@ -34,7 +34,7 @@
     else if (value == "false")
         res.emplace(false);
     else
-        LOG(ERROR) << "ERROR: invalid bool " << value;
+        LOG(FATAL) << "ERROR: invalid bool " << value;
     return res;
 }
 
@@ -48,7 +48,11 @@
     OptInt32 res;
     if (!value.empty()) {
         std::int32_t val;
-        if (ParseInt(value, &val)) res.emplace(val);
+        if (ParseInt(value, &val)) {
+            res.emplace(val);
+        } else {
+            LOG(FATAL) << "ERROR: Could not parse " << value << " as Int32";
+        }
     }
     return res;
 }
@@ -59,6 +63,8 @@
         std::int64_t val = std::strtoull(value.c_str(), nullptr, 10);
         if (val != 0LL or (val == 0LL && value == "0")) {
             res.emplace(val);
+        } else {
+            LOG(FATAL) << "ERROR: Could not parse " << value << " as Int64";
         }
     }
     return res;
@@ -87,7 +93,7 @@
 bool Config::setParam(const std::string& name, const std::string& value) {
     auto it = mMap.find(name);
     if (it == mMap.end()) {
-        LOG(ERROR) << "ERROR: setParam unknown config name " << name;
+        LOG(FATAL) << "ERROR: setParam unknown config name " << name;
         return false;
     }
     LOG(INFO) << "setParam name=" << name << "=" << value;
@@ -102,7 +108,7 @@
 ConfigValue Config::getInternal(const std::string& name) {
     ConfigValue res;
 
-    auto data = mMap[name];
+    auto& data = mMap[name];
     switch (mSource) {
         case ConfigSourceType::SOURCE_SYSPROP:
             res = data.getter();
@@ -111,10 +117,10 @@
             res = data.value;
             break;
         case ConfigSourceType::SOURCE_FILE:
-            LOG(WARNING) << "Unsupported";
+            UNIMPLEMENTED(ERROR) << " File-based config is not supported yet";
             break;
         default:
-            LOG(ERROR) << " wrong srouce type " << (int)mSource;
+            LOG(FATAL) << "Wrong srouce type " << (int)mSource;
             break;
     }
 
@@ -126,8 +132,9 @@
 }
 
 bool Config::setInternal(const std::string& name, const ConfigValue& val) {
+    LOG(INFO) << "Config::set " << name << " to " << toString(val);
     bool res = false;
-    auto data = mMap[name];
+    auto& data = mMap[name];
 
     switch (mSource) {
         case ConfigSourceType::SOURCE_SYSPROP:
@@ -138,10 +145,10 @@
             res = true;
             break;
         case ConfigSourceType::SOURCE_FILE:
-            LOG(WARNING) << "Unsupported";
+            UNIMPLEMENTED(ERROR) << " File-based config is not supported yet";
             break;
         default:
-            LOG(ERROR) << " wrong srouce type " << (int)mSource;
+            LOG(FATAL) << "Wrong srouce type " << (int)mSource;
             break;
     }
 
diff --git a/biometrics/common/config/include/config/Config.h b/biometrics/common/config/include/config/Config.h
index 864e164..0367832 100644
--- a/biometrics/common/config/include/config/Config.h
+++ b/biometrics/common/config/include/config/Config.h
@@ -84,6 +84,33 @@
     virtual Config::Data* getConfigData(int* size) = 0;
     bool setParam(const std::string& name, const std::string& value);
 
+    void sourcedFromAidl() { mSource = ConfigSourceType::SOURCE_AIDL; }
+    std::string toString(const ConfigValue& v) const {
+        std::ostringstream os;
+        if (std::holds_alternative<OptInt32>(v)) {
+            OptInt32 ov = std::get<OptInt32>(v);
+            if (ov.has_value()) os << ov.value();
+        } else if (std::holds_alternative<OptInt64>(v)) {
+            OptInt64 ov = std::get<OptInt64>(v);
+            if (ov.has_value()) os << ov.value();
+        } else if (std::holds_alternative<OptBool>(v)) {
+            OptBool ov = std::get<OptBool>(v);
+            if (ov.has_value()) os << ov.value();
+            os << std::get<OptBool>(v).value();
+        } else if (std::holds_alternative<OptIntVec>(v)) {
+            for (auto x : std::get<OptIntVec>(v))
+                if (x.has_value()) os << x.value() << " ";
+        }
+        return os.str();
+    }
+    std::string toString() const {
+        std::ostringstream os;
+        for (auto const& [k, v] : mMap) {
+            os << k << ":" << toString(v.value) << std::endl;
+        }
+        return os.str();
+    }
+
     ConfigValue parseBool(const std::string& value);
     ConfigValue parseString(const std::string& name);
     ConfigValue parseInt32(const std::string& value);
diff --git a/biometrics/common/config/tests/ConfigTest.cpp b/biometrics/common/config/tests/ConfigTest.cpp
index d922040..9794b25 100644
--- a/biometrics/common/config/tests/ConfigTest.cpp
+++ b/biometrics/common/config/tests/ConfigTest.cpp
@@ -115,7 +115,7 @@
     void SetUp() override { cfg.init(); }
     void TearDown() override {}
 
-    void switch2aidl() { cfg.setParam("astring", "astring"); }
+    void switch2aidl() { cfg.sourcedFromAidl(); }
 
     TestConfig cfg;
 };
@@ -129,7 +129,6 @@
             {"1234", 1234},
             {"0", 0},
             {"", defval},
-            {"xyz", defval},
     };
     for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
         ASSERT_EQ((std::get<OptInt32>(cfg.parseInt32(values[i].strval))).value_or(defval),
@@ -143,8 +142,10 @@
         std::string strval;
         std::int64_t expval;
     } values[] = {
-            {"1234", 1234},  {"12345678909876", 12345678909876}, {"0", 0}, {"", defval},
-            {"xyz", defval},
+            {"1234", 1234},
+            {"12345678909876", 12345678909876},
+            {"0", 0},
+            {"", defval},
     };
     for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
         ASSERT_EQ((std::get<OptInt64>(cfg.parseInt64(values[i].strval))).value_or(defval),
@@ -160,8 +161,6 @@
     } values[] = {
             {"false", false},
             {"true", true},
-            {"", defval},
-            {"xyz", defval},
     };
     for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
         ASSERT_EQ((std::get<OptBool>(cfg.parseBool(values[i].strval))).value_or(defval),
@@ -174,9 +173,7 @@
     struct {
         std::string strval;
         std::vector<std::optional<int>> expval;
-    } values[] = {
-            {"1", {1}}, {"1,2,3", {1, 2, 3}}, {"1,2,b", defval}, {"", defval}, {"xyz", defval},
-    };
+    } values[] = {{"1", {1}}, {"1,2,3", {1, 2, 3}}, {"1,2,b", defval}, {"", defval}};
     for (int i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
         ASSERT_EQ(std::get<OptIntVec>(cfg.parseIntVec(values[i].strval)), values[i].expval);
     }
@@ -255,12 +252,4 @@
     EXPECT_EQ(cfg.getopt<OptIntVec>("avector"), val_avector_new);
 }
 
-TEST_F(ConfigTest, setParam) {
-    ASSERT_TRUE(cfg.setParam("aint32", "789"));
-    ASSERT_EQ(cfg.get<std::int32_t>("aint32"), 789);
-    ASSERT_TRUE(cfg.setParam("avector", "7,8,9,10"));
-    OptIntVec val_avector_new{7, 8, 9, 10};
-    EXPECT_EQ(cfg.getopt<OptIntVec>("avector"), val_avector_new);
-    ASSERT_FALSE(cfg.setParam("unknown", "any"));
-}
 }  // namespace aidl::android::hardware::biometrics
diff --git a/biometrics/face/aidl/TEST_MAPPING b/biometrics/face/aidl/TEST_MAPPING
new file mode 100644
index 0000000..817fd01
--- /dev/null
+++ b/biometrics/face/aidl/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+  "postsubmit": [
+    {
+      "name": "android.hardware.biometrics.face.FakeFaceEngineTest"
+    },
+    {
+      "name": "android.hardware.biometrics.face.FakeLockoutTrackerTest"
+    },
+    {
+      "name": "VtsHalBiometricsFaceTargetTest"
+    }
+  ]
+}
diff --git a/biometrics/fingerprint/aidl/Android.bp b/biometrics/fingerprint/aidl/Android.bp
index 282a702..a395c01 100644
--- a/biometrics/fingerprint/aidl/Android.bp
+++ b/biometrics/fingerprint/aidl/Android.bp
@@ -57,5 +57,5 @@
         },
 
     ],
-    frozen: true,
+    frozen: false,
 }
diff --git a/biometrics/fingerprint/aidl/TEST_MAPPING b/biometrics/fingerprint/aidl/TEST_MAPPING
new file mode 100644
index 0000000..84cca2f
--- /dev/null
+++ b/biometrics/fingerprint/aidl/TEST_MAPPING
@@ -0,0 +1,22 @@
+{
+  "postsubmit": [
+    {
+      "name": "android.hardware.biometrics.fingerprint.FakeFingerprintEngineTest"
+    },
+    {
+      "name": "android.hardware.biometrics.fingerprint.FakeFingerprintEngineUdfpsTest"
+    },
+    {
+      "name": "android.hardware.biometrics.fingerprint.FakeLockoutTrackerTest"
+    },
+    {
+      "name": "android.hardware.biometrics.fingerprint.SessionTest"
+    },
+    {
+      "name": "android.hardware.biometrics.fingerprint.VirtualHalTest"
+    },
+    {
+      "name": "VtsHalBiometricsFingerprintTargetTest"
+    }
+  ]
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
new file mode 100644
index 0000000..c1dc51c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.fingerprint;
+/* @hide */
+@VintfStability
+union AcquiredInfoAndVendorCode {
+  android.hardware.biometrics.fingerprint.AcquiredInfo acquiredInfo = android.hardware.biometrics.fingerprint.AcquiredInfo.UNKNOWN;
+  int vendorCode;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
new file mode 100644
index 0000000..173ac17
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.fingerprint;
+/* @hide */
+@VintfStability
+parcelable EnrollmentProgressStep {
+  int durationMs;
+  android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
new file mode 100644
index 0000000..33ae83c
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.fingerprint;
+/* @hide */
+@VintfStability
+interface IVirtualHal {
+  oneway void setEnrollments(in int[] id);
+  oneway void setEnrollmentHit(in int hit_id);
+  oneway void setNextEnrollment(in android.hardware.biometrics.fingerprint.NextEnrollment next_enrollment);
+  oneway void setAuthenticatorId(in long id);
+  oneway void setChallenge(in long challenge);
+  oneway void setOperationAuthenticateFails(in boolean fail);
+  oneway void setOperationAuthenticateLatency(in int[] latencyMs);
+  oneway void setOperationAuthenticateDuration(in int durationMs);
+  oneway void setOperationAuthenticateError(in int error);
+  oneway void setOperationAuthenticateAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquired);
+  oneway void setOperationEnrollError(in int error);
+  oneway void setOperationEnrollLatency(in int[] latencyMs);
+  oneway void setOperationDetectInteractionLatency(in int[] latencyMs);
+  oneway void setOperationDetectInteractionError(in int error);
+  oneway void setOperationDetectInteractionDuration(in int durationMs);
+  oneway void setOperationDetectInteractionAcquired(in android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode[] acquired);
+  oneway void setLockout(in boolean lockout);
+  oneway void setLockoutEnable(in boolean enable);
+  oneway void setLockoutTimedThreshold(in int threshold);
+  oneway void setLockoutTimedDuration(in int durationMs);
+  oneway void setLockoutPermanentThreshold(in int threshold);
+  oneway void resetConfigurations();
+  oneway void setType(in android.hardware.biometrics.fingerprint.FingerprintSensorType type);
+  oneway void setSensorId(in int id);
+  oneway void setSensorStrength(in android.hardware.biometrics.common.SensorStrength strength);
+  oneway void setMaxEnrollmentPerUser(in int max);
+  oneway void setSensorLocation(in android.hardware.biometrics.fingerprint.SensorLocation loc);
+  oneway void setNavigationGuesture(in boolean v);
+  oneway void setDetectInteraction(in boolean v);
+  oneway void setDisplayTouch(in boolean v);
+  oneway void setControlIllumination(in boolean v);
+  const int STATUS_INVALID_PARAMETER = 1;
+}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
new file mode 100644
index 0000000..75ed070
--- /dev/null
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// 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.fingerprint;
+/* @hide */
+@VintfStability
+parcelable NextEnrollment {
+  int id;
+  android.hardware.biometrics.fingerprint.EnrollmentProgressStep[] progressSteps;
+  boolean result = true;
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
new file mode 100644
index 0000000..c7be950
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/AcquiredInfoAndVendorCode.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+import android.hardware.biometrics.fingerprint.AcquiredInfo;
+
+/**
+ * @hide
+ */
+@VintfStability
+union AcquiredInfoAndVendorCode {
+    /**
+     * Acquired info as specified in AcqauiredInfo.aidl
+     */
+    AcquiredInfo acquiredInfo = AcquiredInfo.UNKNOWN;
+
+    /**
+     * Vendor specific code
+     */
+    int vendorCode;
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
new file mode 100644
index 0000000..bf038f6
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/EnrollmentProgressStep.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+import android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode;
+
+/**
+ * @hide
+ */
+@VintfStability
+parcelable EnrollmentProgressStep {
+    /**
+     * The duration of the enrollment step in milli-seconds
+     */
+    int durationMs;
+
+    /**
+     * The sequence of acquired info and vendor code to be issued by HAL during the step.
+     * The codes are evenly spreaded over the duration
+     */
+    AcquiredInfoAndVendorCode[] acquiredInfoAndVendorCodes;
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
new file mode 100644
index 0000000..cb9135e
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IVirtualHal.aidl
@@ -0,0 +1,318 @@
+/*
+ * 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.fingerprint;
+
+import android.hardware.biometrics.common.SensorStrength;
+import android.hardware.biometrics.fingerprint.AcquiredInfoAndVendorCode;
+import android.hardware.biometrics.fingerprint.FingerprintSensorType;
+import android.hardware.biometrics.fingerprint.NextEnrollment;
+import android.hardware.biometrics.fingerprint.SensorLocation;
+
+/**
+ * @hide
+ */
+@VintfStability
+oneway interface IVirtualHal {
+    /**
+     * The operation failed due to invalid input parameters, the error messages should
+     * gives more details
+     */
+    const int STATUS_INVALID_PARAMETER = 1;
+
+    /**
+     * Set Fingerprint Virtual HAL behavior parameters
+     */
+
+    /**
+     * setEnrollments
+     *
+     * Set the ids of the fingerprints that were currently enrolled in the Virtual HAL,
+     *
+     * @param ids ids can contain 1 or more ids, each must be larger than 0
+     */
+    void setEnrollments(in int[] id);
+
+    /**
+     * setEnrollmentHit
+     *
+     * Set current fingerprint enrollment ids in Fingerprint Virtual HAL,
+     *
+     * @param ids ids can contain 1 or more ids, each must be larger than 0
+     */
+    void setEnrollmentHit(in int hit_id);
+
+    /**
+     * setNextEnrollment
+     *
+     * Set the next enrollment behavior
+     *
+     * @param next_enrollment specifies enrollment id, progress stages and final result
+     */
+    void setNextEnrollment(in NextEnrollment next_enrollment);
+
+    /**
+     * setAuthenticatorId
+     *
+     * Set authenticator id in virtual HAL, the id is returned in ISession#getAuthenticatorId() call
+     *
+     * @param id authenticator id value, only applied to the sensor with SensorStrength::STRONG.
+     */
+    void setAuthenticatorId(in long id);
+
+    /**
+     * setChallenge
+     *
+     * Set the challenge generated by the virtual HAL, which is returned in
+     * ISessionCallback#onChallengeGenerated()
+     *
+     * @param challenge
+     */
+    void setChallenge(in long challenge);
+
+    /**
+     * setOperationAuthenticateFails
+     *
+     * Set whether to force authentication to fail. If true, the virtual hal will report failure on
+     * authentication attempt until it is set to false
+     *
+     * @param fail  if true, then the next authentication will fail
+     */
+    void setOperationAuthenticateFails(in boolean fail);
+
+    /**
+     * setOperationAuthenticateLatency
+     *
+     * Set authentication latency in the virtual hal in a fixed value (single element) or random
+     * values (two elements representing the bound values)
+     * The latency simulates the delay from the time framework requesting HAL to authetication to
+     * the time when HAL is ready to perform authentication operations.
+     *
+     * This method fails with STATUS_INVALID_PARAMETERS if the passed-in array falls in any of
+     * the following conditions
+     *   1. the array contains no element
+     *   2. the array contains more than two elements
+     *   3. the array contains any negative value
+     * The accompanying error message gives more detail
+     *
+     * @param latencyMs[]  value(s) are in milli-seconds
+     */
+    void setOperationAuthenticateLatency(in int[] latencyMs);
+
+    /**
+     * setOperationAuthenticateDuration
+     *
+     * Set authentication duration covering the HAL authetication from start to end, including
+     * fingerprint capturing, and matching, acquired info reporting. In case a sequence of acquired
+     * info code are specified via setOperationAuthenticateAcquired(), the reporting is evenly
+     * distributed over the duration.
+     *
+     * This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
+     *
+     * @param duration  value is in milli-seconds
+     */
+    void setOperationAuthenticateDuration(in int durationMs);
+
+    /**
+     * setOperationAuthenticateError
+     *
+     * Force authentication to error out for non-zero error
+     * Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid error codes
+     *
+     * @param error if error < 1000
+     *                  non-vendor error
+     *              else
+     *                  vendor error
+     */
+    void setOperationAuthenticateError(in int error);
+
+    /**
+     * setOperationAuthenticateAcquired
+     *
+     * Set one of more acquired info codes for the virtual hal to report during authentication
+     * Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid acquired
+     * info codes
+     *
+     * @param acquired[], one or more acquired info codes
+     */
+    void setOperationAuthenticateAcquired(in AcquiredInfoAndVendorCode[] acquired);
+
+    /**
+     * setOperationEnrollError
+     *
+     * Force enrollment operation to error out for non-zero error
+     * Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid error codes
+     *
+     * @param error if error < 1000
+     *                  non-vendor error
+     *              else
+     *                  vendor error
+     */
+    void setOperationEnrollError(in int error);
+
+    /**
+     * setOperationEnrollLatency
+     *
+     * Set enrollment latency in the virtual hal in a fixed value (single element) or random
+     * values (two elements representing the bound values)
+     * The latency simulates the delay from the time framework requesting HAL to enroll to the
+     * time when HAL is ready to perform enrollment operations.
+     *
+     * This method fails with STATUS_INVALID_PARAMETERS if the passed-in array falls in any of
+     * the following conditions
+     *   1. the array contains no element
+     *   2. the array contains more than two elements
+     *   3. the array contains any negative value
+     * The accompanying error message gives more detail
+     *
+     * @param latencyMs[]  value(s) are in milli-seconds
+     */
+    void setOperationEnrollLatency(in int[] latencyMs);
+
+    /**
+     * setOperationDetectInteractionLatency
+     *
+     * Set detect interaction latency in the virtual hal in a fixed value (single element) or random
+     * values (two elements representing the bound values)
+     * The latency simulates the delay from the time framework requesting HAL to detect interaction
+     * to the time when HAL is ready to perform detect interaction operations.
+     *
+     * This method fails with STATUS_INVALID_PARAMETERS if the passed-in array falls in any of
+     * the following conditions
+     *   1. the array contains no element
+     *   2. the array contains more than two elements
+     *   3. the array contains any negative value
+     * The accompanying error message gives more detail
+     *
+     * @param latencyMs[]  value(s) are in milli-seconds
+     */
+    void setOperationDetectInteractionLatency(in int[] latencyMs);
+
+    /**
+     * setOperationDetectInteractionError
+     *
+     * Force detect interaction operation to error out for non-zero error
+     * Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid error codes
+     *
+     * @param error if error < 1000
+     *                  non-vendor error
+     *              else
+     *                  vendor error
+     */
+    void setOperationDetectInteractionError(in int error);
+
+    /**
+     * setOperationDetectInteractionDuration
+     *
+     * Set detect interaction duration covering the HAL authetication from start to end, including
+     * fingerprint detect and acquired info reporting. In case a sequence of acquired info code are
+     * specified via setOperationDetectInteractionAcquired(), the reporting is evenly distributed
+     * over the duration.
+     *
+     * This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
+     *
+     * @param duration  value is in milli-seconds
+     */
+    void setOperationDetectInteractionDuration(in int durationMs);
+
+    /**
+     * setOperationDetectInteractionAcquired
+     *
+     * Set one of more acquired info codes for the virtual hal to report during detect interaction
+     * Check hardware/interfaces/biometrics/fingerprint/aidl/default/README.md for valid acquired
+     * info codes
+     *
+     * @param acquired[], one or more acquired info codes
+     */
+    void setOperationDetectInteractionAcquired(in AcquiredInfoAndVendorCode[] acquired);
+
+    /**
+     * setLockout
+     *
+     * Whether to force to lockout on authentcation operation. If true, the virtual hal will report
+     * permanent lockout in processing authentication requrest, regardless of whether
+     * setLockoutEnable(true) is called or not.
+     *
+     * @param lockout, set to true if lockout is desired
+     */
+    void setLockout(in boolean lockout);
+
+    /**
+     * setLockoutEnable
+     *
+     * Whether to enable authentication-fail-based lockout tracking or not. The lock tracking
+     * includes both timed-based (aka temporary) lockout and permanent lockout.
+     *
+     * @param enable, set true to enable the lockout tracking
+     */
+    void setLockoutEnable(in boolean enable);
+
+    /**
+     * setLockoutTimedThreshold
+     *
+     * Set the number of consecutive authentication failures that triggers the timed-based lock to
+     * occur
+     *
+     * This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
+     *
+     * @param threshold, the number of consecutive failures
+     */
+    void setLockoutTimedThreshold(in int threshold);
+
+    /**
+     * setLockoutTimedDuration
+     *
+     * Set the duration to expire timed-based lock during which there is no authentication failure
+     *
+     * This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
+     *
+     * @param duration, in milli-seconds
+     */
+    void setLockoutTimedDuration(in int durationMs);
+
+    /**
+     * setLockoutPermanentThreshold
+     *
+     * Set the number of consecutive authentication failures that triggers the permanent lock to
+     * occur
+     *
+     * This method fails with STATUS_INVALID_PARAMETERS if the passed-in value is negative
+     *
+     * @param threshold, the number of consecutive failures
+     */
+    void setLockoutPermanentThreshold(in int threshold);
+
+    /**
+     * resetConfigurations
+     *
+     * Reset all virtual hal configurations to default values
+     */
+    void resetConfigurations();
+
+    /**
+     * The following functions are used to configure Fingerprint Virtual HAL sensor properties
+     *  refer to SensorProps.aidl and CommonProps.aidl for details of each property
+     */
+    void setType(in FingerprintSensorType type);
+    void setSensorId(in int id);
+    void setSensorStrength(in SensorStrength strength);
+    void setMaxEnrollmentPerUser(in int max);
+    void setSensorLocation(in SensorLocation loc);
+    void setNavigationGuesture(in boolean v);
+    void setDetectInteraction(in boolean v);
+    void setDisplayTouch(in boolean v);
+    void setControlIllumination(in boolean v);
+}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
new file mode 100644
index 0000000..4b50850
--- /dev/null
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/NextEnrollment.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.biometrics.fingerprint;
+
+/**
+ * @hide
+ */
+@VintfStability
+parcelable NextEnrollment {
+    /**
+     *  Identifier of the next enrollment if successful
+     */
+    int id;
+
+    /**
+     *  Specification of the progress steps of the next enrollment, each step consists of duration
+     *  and sequence of acquired info codes to be generated by HAL.
+     *  See EnrollmentProgressStep.aidl for more details
+     */
+    android.hardware.biometrics.fingerprint.EnrollmentProgressStep[] progressSteps;
+
+    /**
+     * Success or failure of the next enrollment
+     */
+    boolean result = true;
+}
diff --git a/biometrics/fingerprint/aidl/default/Android.bp b/biometrics/fingerprint/aidl/default/Android.bp
index 2a73f5d..9b72c87 100644
--- a/biometrics/fingerprint/aidl/default/Android.bp
+++ b/biometrics/fingerprint/aidl/default/Android.bp
@@ -22,6 +22,7 @@
         "Fingerprint.cpp",
         "Session.cpp",
         "FingerprintConfig.cpp",
+        "VirtualHal.cpp",
         "main.cpp",
     ],
     stl: "c++_static",
@@ -32,7 +33,7 @@
     static_libs: [
         "libandroid.hardware.biometrics.fingerprint.VirtualProps",
         "libbase",
-        "android.hardware.biometrics.fingerprint-V4-ndk",
+        "android.hardware.biometrics.fingerprint-V5-ndk",
         "android.hardware.biometrics.common-V4-ndk",
         "android.hardware.biometrics.common.thread",
         "android.hardware.biometrics.common.util",
@@ -62,7 +63,7 @@
     ],
     static_libs: [
         "libandroid.hardware.biometrics.fingerprint.VirtualProps",
-        "android.hardware.biometrics.fingerprint-V4-ndk",
+        "android.hardware.biometrics.fingerprint-V5-ndk",
         "android.hardware.biometrics.common-V4-ndk",
         "android.hardware.keymaster-V4-ndk",
         "android.hardware.biometrics.common.util",
@@ -90,7 +91,7 @@
     ],
     static_libs: [
         "libandroid.hardware.biometrics.fingerprint.VirtualProps",
-        "android.hardware.biometrics.fingerprint-V4-ndk",
+        "android.hardware.biometrics.fingerprint-V5-ndk",
         "android.hardware.biometrics.common-V4-ndk",
         "android.hardware.keymaster-V4-ndk",
         "android.hardware.biometrics.common.util",
@@ -116,7 +117,7 @@
     ],
     static_libs: [
         "libandroid.hardware.biometrics.fingerprint.VirtualProps",
-        "android.hardware.biometrics.fingerprint-V4-ndk",
+        "android.hardware.biometrics.fingerprint-V5-ndk",
         "android.hardware.biometrics.common-V4-ndk",
         "android.hardware.keymaster-V4-ndk",
         "android.hardware.biometrics.common.util",
@@ -144,7 +145,7 @@
     ],
     static_libs: [
         "libandroid.hardware.biometrics.fingerprint.VirtualProps",
-        "android.hardware.biometrics.fingerprint-V4-ndk",
+        "android.hardware.biometrics.fingerprint-V5-ndk",
         "android.hardware.biometrics.common-V4-ndk",
         "android.hardware.keymaster-V4-ndk",
         "android.hardware.biometrics.common.util",
@@ -156,6 +157,44 @@
     require_root: true,
 }
 
+cc_test {
+    name: "android.hardware.biometrics.fingerprint.VirtualHalTest",
+    local_include_dirs: ["include"],
+    srcs: [
+        "tests/VirtualHalTest.cpp",
+        "Session.cpp",
+        "VirtualHal.cpp",
+        "FakeFingerprintEngineRear.cpp",
+        "FakeFingerprintEngineUdfps.cpp",
+        "FakeFingerprintEngineSide.cpp",
+        "FakeFingerprintEngine.cpp",
+        "FakeLockoutTracker.cpp",
+        "Fingerprint.cpp",
+        "FingerprintConfig.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "libandroid.hardware.biometrics.fingerprint.VirtualProps",
+        "android.hardware.biometrics.fingerprint-V5-ndk",
+        "android.hardware.biometrics.common-V4-ndk",
+        "android.hardware.keymaster-V4-ndk",
+        "android.hardware.biometrics.common.util",
+        "android.hardware.biometrics.common.thread",
+        "android.hardware.biometrics.common.config",
+    ],
+    product_variables: {
+        debuggable: {
+            cflags: ["-DFPS_DEBUGGABLE"],
+        },
+    },
+    vendor: true,
+    test_suites: ["general-tests"],
+    require_root: true,
+}
+
 sysprop_library {
     name: "android.hardware.biometrics.fingerprint.VirtualProps",
     srcs: ["fingerprint.sysprop"],
diff --git a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
index 8b8d046..67eb837 100644
--- a/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
+++ b/biometrics/fingerprint/aidl/default/FakeFingerprintEngine.cpp
@@ -544,6 +544,10 @@
 
 void FakeFingerprintEngine::waitForFingerDown(ISessionCallback* cb,
                                               const std::future<void>& cancel) {
+    if (mFingerIsDown) {
+        LOG(WARNING) << "waitForFingerDown: mFingerIsDown==true already!";
+    }
+
     while (!mFingerIsDown) {
         if (shouldCancel(cancel)) {
             LOG(ERROR) << "waitForFingerDown, Fail: cancel";
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index dded54b..3055da1 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -125,6 +125,8 @@
     }
     ::android::base::WriteStringToFd(mEngine->toString(), fd);
 
+    ::android::base::WriteStringToFd(Fingerprint::cfg().toString(), fd);
+
     fsync(fd);
     return STATUS_OK;
 }
@@ -171,7 +173,7 @@
 }
 
 void Fingerprint::clearConfigSysprop() {
-    LOG(INFO) << __func__ << ": clear all systprop configuration";
+    LOG(INFO) << __func__ << ": clear all sysprop configuration";
 #define RESET_CONFIG_O(__NAME__) \
     if (FingerprintHalProperties::__NAME__()) FingerprintHalProperties::__NAME__(std::nullopt)
 #define RESET_CONFIG_V(__NAME__)                       \
@@ -209,4 +211,19 @@
     RESET_CONFIG_O(lockout_permanent_threshold);
 }
 
+const char* Fingerprint::type2String(FingerprintSensorType type) {
+    switch (type) {
+        case FingerprintSensorType::REAR:
+            return "rear";
+        case FingerprintSensorType::POWER_BUTTON:
+            return "side";
+        case FingerprintSensorType::UNDER_DISPLAY_OPTICAL:
+            return "udfps";
+        case FingerprintSensorType::UNDER_DISPLAY_ULTRASONIC:
+            return "udfps";
+        default:
+            return "unknown";
+    }
+}
+
 }  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/VirtualHal.cpp b/biometrics/fingerprint/aidl/default/VirtualHal.cpp
new file mode 100644
index 0000000..e107d2f
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/VirtualHal.cpp
@@ -0,0 +1,336 @@
+/*
+ * 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 <unordered_map>
+
+#include "VirtualHal.h"
+
+#include <android-base/logging.h>
+
+#include "util/CancellationSignal.h"
+
+#undef LOG_TAG
+#define LOG_TAG "FingerprintVirtualHalAidl"
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+using Tag = AcquiredInfoAndVendorCode::Tag;
+
+::ndk::ScopedAStatus VirtualHal::setEnrollments(const std::vector<int32_t>& enrollments) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().setopt<OptIntVec>("enrollments", intVec2OptIntVec(enrollments));
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setEnrollmentHit(int32_t enrollment_hit) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<std::int32_t>("enrollment_hit", enrollment_hit);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setNextEnrollment(
+        const ::aidl::android::hardware::biometrics::fingerprint::NextEnrollment& next_enrollment) {
+    Fingerprint::cfg().sourcedFromAidl();
+    std::ostringstream os;
+    os << next_enrollment.id << ":";
+
+    int stepSize = next_enrollment.progressSteps.size();
+    for (int i = 0; i < stepSize; i++) {
+        auto& step = next_enrollment.progressSteps[i];
+        os << step.durationMs;
+        int acSize = step.acquiredInfoAndVendorCodes.size();
+        for (int j = 0; j < acSize; j++) {
+            if (j == 0) os << "-[";
+            auto& acquiredInfoAndVendorCode = step.acquiredInfoAndVendorCodes[j];
+            if (acquiredInfoAndVendorCode.getTag() == AcquiredInfoAndVendorCode::vendorCode)
+                os << acquiredInfoAndVendorCode.get<Tag::vendorCode>();
+            else if (acquiredInfoAndVendorCode.getTag() == AcquiredInfoAndVendorCode::acquiredInfo)
+                os << (int)acquiredInfoAndVendorCode.get<Tag::acquiredInfo>();
+            else
+                LOG(FATAL) << "ERROR: wrong AcquiredInfoAndVendorCode union tag";
+            if (j == acSize - 1)
+                os << "]";
+            else
+                os << ",";
+        }
+        if (i == stepSize - 1)
+            os << ":";
+        else
+            os << ",";
+    }
+
+    os << (next_enrollment.result ? "true" : "false");
+    Fingerprint::cfg().set<std::string>("next_enrollment", os.str());
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setAuthenticatorId(int64_t in_id) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int64_t>("authenticator_id", in_id);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setChallenge(int64_t in_challenge) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int64_t>("challenge", in_challenge);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateFails(bool in_fail) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<bool>("operation_authenticate_fails", in_fail);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateLatency(
+        const std::vector<int32_t>& in_latency) {
+    ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
+    if (!status.isOk()) {
+        return status;
+    }
+
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_latency",
+                                         intVec2OptIntVec(in_latency));
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateDuration(int32_t in_duration) {
+    if (in_duration < 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
+    }
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("operation_authenticate_duration", in_duration);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateError(int32_t in_error) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("operation_authenticate_error", in_error);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationAuthenticateAcquired(
+        const std::vector<AcquiredInfoAndVendorCode>& in_acquired) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().setopt<OptIntVec>("operation_authenticate_acquired",
+                                         acquiredInfoVec2OptIntVec(in_acquired));
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationEnrollError(int32_t in_error) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("operation_enroll_error", in_error);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationEnrollLatency(const std::vector<int32_t>& in_latency) {
+    ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
+    if (!status.isOk()) {
+        return status;
+    }
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().setopt<OptIntVec>("operation_enroll_latency", intVec2OptIntVec(in_latency));
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionLatency(
+        const std::vector<int32_t>& in_latency) {
+    ndk::ScopedAStatus status = sanityCheckLatency(in_latency);
+    if (!status.isOk()) {
+        return status;
+    }
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interact_latency",
+                                         intVec2OptIntVec(in_latency));
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionError(int32_t in_error) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("operation_detect_interaction_error", in_error);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionDuration(int32_t in_duration) {
+    if (in_duration < 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
+    }
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("operation_detect_interaction_duration", in_duration);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setOperationDetectInteractionAcquired(
+        const std::vector<AcquiredInfoAndVendorCode>& in_acquired) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().setopt<OptIntVec>("operation_detect_interaction_acquired",
+                                         acquiredInfoVec2OptIntVec(in_acquired));
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setLockout(bool in_lockout) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<bool>("lockout", in_lockout);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setLockoutEnable(bool in_enable) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<bool>("lockout_enable", in_enable);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setLockoutTimedThreshold(int32_t in_threshold) {
+    if (in_threshold < 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IVirtualHal::STATUS_INVALID_PARAMETER, "Error: threshold can not be negative"));
+    }
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("lockout_timed_threshold", in_threshold);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setLockoutTimedDuration(int32_t in_duration) {
+    if (in_duration < 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IVirtualHal::STATUS_INVALID_PARAMETER, "Error: duration can not be negative"));
+    }
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("lockout_timed_duration", in_duration);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setLockoutPermanentThreshold(int32_t in_threshold) {
+    if (in_threshold < 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IVirtualHal::STATUS_INVALID_PARAMETER, "Error: threshold can not be negative"));
+    }
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("lockout_permanent_threshold", in_threshold);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::resetConfigurations() {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().init();
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setType(
+        ::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType in_type) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<std::string>("type", Fingerprint::type2String(in_type));
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setSensorId(int32_t in_id) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("sensor_id", in_id);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setSensorStrength(SensorStrength in_strength) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("sensor_strength", (int32_t)in_strength);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setMaxEnrollmentPerUser(int32_t in_max) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<int32_t>("max_enrollments", in_max);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setSensorLocation(const SensorLocation& in_loc) {
+    std::string str = std::to_string(in_loc.sensorLocationX) + ":" +
+                      std::to_string(in_loc.sensorLocationY) + ":" +
+                      std::to_string(in_loc.sensorRadius);
+    ;
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<std::string>("sensor_location", str);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setNavigationGuesture(bool in_v) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<bool>("navigation_guesture", in_v);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setDetectInteraction(bool in_v) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<bool>("detect_interaction", in_v);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setDisplayTouch(bool in_v) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<bool>("display_touch", in_v);
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus VirtualHal::setControlIllumination(bool in_v) {
+    Fingerprint::cfg().sourcedFromAidl();
+    Fingerprint::cfg().set<bool>("control_illumination", in_v);
+    return ndk::ScopedAStatus::ok();
+}
+
+OptIntVec VirtualHal::intVec2OptIntVec(const std::vector<int32_t>& in_vec) {
+    OptIntVec optIntVec;
+    std::transform(in_vec.begin(), in_vec.end(), std::back_inserter(optIntVec),
+                   [](int value) { return std::optional<int>(value); });
+    return optIntVec;
+}
+
+OptIntVec VirtualHal::acquiredInfoVec2OptIntVec(
+        const std::vector<AcquiredInfoAndVendorCode>& in_vec) {
+    OptIntVec optIntVec;
+    std::transform(in_vec.begin(), in_vec.end(), std::back_inserter(optIntVec),
+                   [](AcquiredInfoAndVendorCode ac) {
+                       int value;
+                       if (ac.getTag() == AcquiredInfoAndVendorCode::acquiredInfo)
+                           value = (int)ac.get<Tag::acquiredInfo>();
+                       else if (ac.getTag() == AcquiredInfoAndVendorCode::vendorCode)
+                           value = ac.get<Tag::vendorCode>();
+                       else
+                           LOG(FATAL) << "ERROR: wrong AcquiredInfoAndVendorCode tag";
+                       return std::optional<int>(value);
+                   });
+    return optIntVec;
+}
+
+::ndk::ScopedAStatus VirtualHal::sanityCheckLatency(const std::vector<int32_t>& in_latency) {
+    if (in_latency.size() == 0 || in_latency.size() > 2) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IVirtualHal::STATUS_INVALID_PARAMETER,
+                "Error: input input array must contain 1 or 2 elements"));
+    }
+
+    for (auto x : in_latency) {
+        if (x < 0) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IVirtualHal::STATUS_INVALID_PARAMETER,
+                    "Error: input data must not be negative"));
+        }
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/fingerprint-example.xml b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
index 827813f..ee529e9 100644
--- a/biometrics/fingerprint/aidl/default/fingerprint-example.xml
+++ b/biometrics/fingerprint/aidl/default/fingerprint-example.xml
@@ -1,7 +1,7 @@
 <manifest version="1.0" type="device">
     <hal format="aidl">
         <name>android.hardware.biometrics.fingerprint</name>
-        <version>4</version>
+        <version>5</version>
         <fqname>IFingerprint/virtual</fqname>
     </hal>
 </manifest>
diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
index 1576f07..90f89cb 100644
--- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
@@ -40,6 +40,7 @@
                                      std::shared_ptr<ISession>* out) override;
     binder_status_t dump(int fd, const char** args, uint32_t numArgs);
     binder_status_t handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc);
+    bool connected() { return mEngine != nullptr; }
 
     static FingerprintConfig& cfg() {
         static FingerprintConfig* cfg = nullptr;
@@ -49,9 +50,10 @@
         }
         return *cfg;
     }
+    void resetConfigToDefault();
+    static const char* type2String(FingerprintSensorType type);
 
   private:
-    void resetConfigToDefault();
     void onHelp(int);
     void onSimFingerDown();
     void clearConfigSysprop();
diff --git a/biometrics/fingerprint/aidl/default/include/VirtualHal.h b/biometrics/fingerprint/aidl/default/include/VirtualHal.h
new file mode 100644
index 0000000..e5f62fc
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/include/VirtualHal.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/biometrics/fingerprint/BnVirtualHal.h>
+
+#include "Fingerprint.h"
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class VirtualHal : public BnVirtualHal {
+  public:
+    VirtualHal(Fingerprint* fp) : mFp(fp) {}
+
+    ::ndk::ScopedAStatus setEnrollments(const std::vector<int32_t>& in_id) override;
+    ::ndk::ScopedAStatus setEnrollmentHit(int32_t in_hit_id) override;
+    ::ndk::ScopedAStatus setNextEnrollment(
+            const ::aidl::android::hardware::biometrics::fingerprint::NextEnrollment&
+                    in_next_enrollment) override;
+    ::ndk::ScopedAStatus setAuthenticatorId(int64_t in_id) override;
+    ::ndk::ScopedAStatus setChallenge(int64_t in_challenge) override;
+    ::ndk::ScopedAStatus setOperationAuthenticateFails(bool in_fail) override;
+    ::ndk::ScopedAStatus setOperationAuthenticateLatency(
+            const std::vector<int32_t>& in_latency) override;
+    ::ndk::ScopedAStatus setOperationAuthenticateDuration(int32_t in_duration) override;
+    ::ndk::ScopedAStatus setOperationAuthenticateError(int32_t in_error) override;
+    ::ndk::ScopedAStatus setOperationAuthenticateAcquired(
+            const std::vector<AcquiredInfoAndVendorCode>& in_acquired) override;
+    ::ndk::ScopedAStatus setOperationEnrollError(int32_t in_error) override;
+    ::ndk::ScopedAStatus setOperationEnrollLatency(const std::vector<int32_t>& in_latency) override;
+    ::ndk::ScopedAStatus setOperationDetectInteractionLatency(
+            const std::vector<int32_t>& in_latency) override;
+    ::ndk::ScopedAStatus setOperationDetectInteractionError(int32_t in_error) override;
+    ::ndk::ScopedAStatus setOperationDetectInteractionDuration(int32_t in_duration) override;
+    ::ndk::ScopedAStatus setOperationDetectInteractionAcquired(
+            const std::vector<AcquiredInfoAndVendorCode>& in_acquired) override;
+    ::ndk::ScopedAStatus setLockout(bool in_lockout) override;
+    ::ndk::ScopedAStatus setLockoutEnable(bool in_enable) override;
+    ::ndk::ScopedAStatus setLockoutTimedThreshold(int32_t in_threshold) override;
+    ::ndk::ScopedAStatus setLockoutTimedDuration(int32_t in_duration) override;
+    ::ndk::ScopedAStatus setLockoutPermanentThreshold(int32_t in_threshold) override;
+    ::ndk::ScopedAStatus resetConfigurations() override;
+    ::ndk::ScopedAStatus setType(
+            ::aidl::android::hardware::biometrics::fingerprint::FingerprintSensorType in_type)
+            override;
+    ::ndk::ScopedAStatus setSensorId(int32_t in_id) override;
+    ::ndk::ScopedAStatus setSensorStrength(SensorStrength in_strength) override;
+    ::ndk::ScopedAStatus setMaxEnrollmentPerUser(int32_t in_max) override;
+    ::ndk::ScopedAStatus setSensorLocation(
+            const ::aidl::android::hardware::biometrics::fingerprint::SensorLocation& in_loc)
+            override;
+    ::ndk::ScopedAStatus setNavigationGuesture(bool in_v) override;
+    ::ndk::ScopedAStatus setDetectInteraction(bool in_v) override;
+    ::ndk::ScopedAStatus setDisplayTouch(bool in_v) override;
+    ::ndk::ScopedAStatus setControlIllumination(bool in_v) override;
+
+  private:
+    OptIntVec intVec2OptIntVec(const std::vector<int32_t>& intVec);
+    OptIntVec acquiredInfoVec2OptIntVec(const std::vector<AcquiredInfoAndVendorCode>& intVec);
+    ::ndk::ScopedAStatus sanityCheckLatency(const std::vector<int32_t>& in_latency);
+    Fingerprint* mFp;
+};
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/main.cpp b/biometrics/fingerprint/aidl/default/main.cpp
index 7df015b..ba0c8ec 100644
--- a/biometrics/fingerprint/aidl/default/main.cpp
+++ b/biometrics/fingerprint/aidl/default/main.cpp
@@ -15,23 +15,34 @@
  */
 
 #include "Fingerprint.h"
+#include "VirtualHal.h"
 
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 
 using aidl::android::hardware::biometrics::fingerprint::Fingerprint;
+using aidl::android::hardware::biometrics::fingerprint::VirtualHal;
 
 int main() {
     LOG(INFO) << "Fingerprint HAL started";
     ABinderProcess_setThreadPoolMaxThreadCount(0);
     std::shared_ptr<Fingerprint> hal = ndk::SharedRefBase::make<Fingerprint>();
+    auto binder = hal->asBinder();
 
-    const std::string instance = std::string(Fingerprint::descriptor) + "/virtual";
-    binder_status_t status =
-            AServiceManager_registerLazyService(hal->asBinder().get(), instance.c_str());
-    CHECK_EQ(status, STATUS_OK);
-    AServiceManager_forceLazyServicesPersist(true);
+    std::shared_ptr<VirtualHal> hal_ext = ndk::SharedRefBase::make<VirtualHal>(hal.get());
+    auto binder_ext = hal_ext->asBinder();
+
+    if (hal->connected()) {
+        CHECK(STATUS_OK == AIBinder_setExtension(binder.get(), binder_ext.get()));
+        const std::string instance = std::string(Fingerprint::descriptor) + "/virtual";
+        binder_status_t status =
+                AServiceManager_registerLazyService(binder.get(), instance.c_str());
+        CHECK_EQ(status, STATUS_OK);
+        AServiceManager_forceLazyServicesPersist(true);
+    } else {
+        LOG(ERROR) << "Fingerprint HAL is not connected";
+    }
 
     ABinderProcess_joinThreadPool();
     return EXIT_FAILURE;  // should not reach
diff --git a/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp b/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
new file mode 100644
index 0000000..3fe0b2a
--- /dev/null
+++ b/biometrics/fingerprint/aidl/default/tests/VirtualHalTest.cpp
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_process.h>
+#include <fingerprint.sysprop.h>
+#include <gtest/gtest.h>
+
+#include <android-base/logging.h>
+
+#include "Fingerprint.h"
+#include "VirtualHal.h"
+
+using namespace ::android::fingerprint::virt;
+using namespace ::aidl::android::hardware::biometrics::fingerprint;
+
+namespace aidl::android::hardware::biometrics::fingerprint {
+
+class VirtualHalTest : public ::testing::Test {
+  public:
+    static const int32_t STATUS_FAILED_TO_SET_PARAMETER = 2;
+
+  protected:
+    void SetUp() override {
+        mHal = ndk::SharedRefBase::make<Fingerprint>();
+        mVhal = ndk::SharedRefBase::make<VirtualHal>(mHal.get());
+        ASSERT_TRUE(mVhal != nullptr);
+        mHal->resetConfigToDefault();
+    }
+
+    void TearDown() override { mHal->resetConfigToDefault(); }
+
+    std::shared_ptr<VirtualHal> mVhal;
+
+    ndk::ScopedAStatus validateNonNegativeInputOfInt32(const char* name,
+                                                       ndk::ScopedAStatus (VirtualHal::*f)(int32_t),
+                                                       const std::vector<int32_t>& in_good);
+
+  private:
+    std::shared_ptr<Fingerprint> mHal;
+};
+
+ndk::ScopedAStatus VirtualHalTest::validateNonNegativeInputOfInt32(
+        const char* name, ndk::ScopedAStatus (VirtualHal::*f)(int32_t),
+        const std::vector<int32_t>& in_params_good) {
+    ndk::ScopedAStatus status;
+    for (auto& param : in_params_good) {
+        status = (*mVhal.*f)(param);
+        if (!status.isOk()) return status;
+        if (Fingerprint::cfg().get<int32_t>(name) != param) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    VirtualHalTest::STATUS_FAILED_TO_SET_PARAMETER,
+                    "Error: fail to set non-negative parameter"));
+        }
+    }
+
+    int32_t old_param = Fingerprint::cfg().get<int32_t>(name);
+    status = (*mVhal.*f)(-1);
+    if (status.isOk()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                VirtualHalTest::STATUS_FAILED_TO_SET_PARAMETER, "Error: should return NOK"));
+    }
+    if (status.getServiceSpecificError() != IVirtualHal::STATUS_INVALID_PARAMETER) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                VirtualHalTest::STATUS_FAILED_TO_SET_PARAMETER,
+                "Error: unexpected return error code"));
+    }
+    if (Fingerprint::cfg().get<int32_t>(name) != old_param) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                VirtualHalTest::STATUS_FAILED_TO_SET_PARAMETER,
+                "Error: unexpected parameter change on failed attempt"));
+    }
+    return ndk::ScopedAStatus::ok();
+}
+
+TEST_F(VirtualHalTest, init) {
+    mVhal->setLockout(false);
+    ASSERT_TRUE(Fingerprint::cfg().get<bool>("lockout") == false);
+    ASSERT_TRUE(Fingerprint::cfg().get<std::string>("type") == "rear");
+    ASSERT_TRUE(Fingerprint::cfg().get<std::int32_t>("sensor_strength") == 2);
+    std::int64_t id = Fingerprint::cfg().get<std::int64_t>("authenticator_id");
+    ASSERT_TRUE(Fingerprint::cfg().get<std::int64_t>("authenticator_id") == 0);
+    ASSERT_TRUE(Fingerprint::cfg().getopt<OptIntVec>("enrollments") == OptIntVec());
+}
+
+TEST_F(VirtualHalTest, enrollment_hit_int32) {
+    mVhal->setEnrollmentHit(11);
+    ASSERT_TRUE(Fingerprint::cfg().get<int32_t>("enrollment_hit") == 11);
+}
+
+TEST_F(VirtualHalTest, next_enrollment) {
+    struct {
+        std::string nextEnrollmentStr;
+        fingerprint::NextEnrollment nextEnrollment;
+    } testData[] = {
+            {"1:20:true", {1, {{20}}, true}},
+            {"1:50,60,70:true", {1, {{50}, {60}, {70}}, true}},
+            {"2:50-[8],60,70-[2,1002,1]:false",
+             {2,
+              {{50, {{AcquiredInfo::START}}},
+               {60},
+               {70, {{AcquiredInfo::PARTIAL}, {1002}, {AcquiredInfo::GOOD}}}},
+              false}},
+    };
+
+    for (auto& d : testData) {
+        mVhal->setNextEnrollment(d.nextEnrollment);
+        ASSERT_TRUE(Fingerprint::cfg().get<std::string>("next_enrollment") == d.nextEnrollmentStr);
+    }
+}
+
+TEST_F(VirtualHalTest, authenticator_id_int64) {
+    mVhal->setAuthenticatorId(12345678900);
+    ASSERT_TRUE(Fingerprint::cfg().get<int64_t>("authenticator_id") == 12345678900);
+}
+
+TEST_F(VirtualHalTest, opeationAuthenticateFails_bool) {
+    mVhal->setOperationAuthenticateFails(true);
+    ASSERT_TRUE(Fingerprint::cfg().get<bool>("operation_authenticate_fails"));
+}
+
+TEST_F(VirtualHalTest, operationAuthenticateAcquired_int32_vector) {
+    using Tag = AcquiredInfoAndVendorCode::Tag;
+    std::vector<AcquiredInfoAndVendorCode> ac{
+            {AcquiredInfo::START}, {AcquiredInfo::PARTIAL}, {1023}};
+    mVhal->setOperationAuthenticateAcquired(ac);
+    OptIntVec ac_get = Fingerprint::cfg().getopt<OptIntVec>("operation_authenticate_acquired");
+    ASSERT_TRUE(ac_get.size() == ac.size());
+    for (int i = 0; i < ac.size(); i++) {
+        int acCode = (ac[i].getTag() == Tag::acquiredInfo) ? (int)ac[i].get<Tag::acquiredInfo>()
+                                                           : ac[i].get<Tag::vendorCode>();
+        ASSERT_TRUE(acCode == ac_get[i]);
+    }
+}
+
+TEST_F(VirtualHalTest, type) {
+    struct {
+        FingerprintSensorType type;
+        const char* typeStr;
+    } typeMap[] = {{FingerprintSensorType::REAR, "rear"},
+                   {FingerprintSensorType::POWER_BUTTON, "side"},
+                   {FingerprintSensorType::UNDER_DISPLAY_OPTICAL, "udfps"},
+                   {FingerprintSensorType::UNDER_DISPLAY_ULTRASONIC, "udfps"},
+                   {FingerprintSensorType::UNKNOWN, "unknown"}};
+    for (auto const& x : typeMap) {
+        mVhal->setType(x.type);
+        ASSERT_TRUE(Fingerprint::cfg().get<std::string>("type") == x.typeStr);
+    }
+}
+
+TEST_F(VirtualHalTest, sensorStrength) {
+    SensorStrength strengths[] = {SensorStrength::CONVENIENCE, SensorStrength::WEAK,
+                                  SensorStrength::STRONG};
+
+    for (auto const& strength : strengths) {
+        mVhal->setSensorStrength(strength);
+        ASSERT_TRUE(Fingerprint::cfg().get<int32_t>("sensor_strength") == (int32_t)(strength));
+    }
+}
+
+TEST_F(VirtualHalTest, sensorLocation) {
+    SensorLocation loc = {.sensorLocationX = 1, .sensorLocationY = 2, .sensorRadius = 3};
+    mVhal->setSensorLocation(loc);
+    ASSERT_TRUE(Fingerprint::cfg().get<std::string>("sensor_location") == "1:2:3");
+}
+
+TEST_F(VirtualHalTest, setLatency) {
+    ndk::ScopedAStatus status;
+    std::vector<int32_t> in_lats[] = {{1}, {2, 3}, {5, 4}};
+    for (auto const& in_lat : in_lats) {
+        status = mVhal->setOperationAuthenticateLatency(in_lat);
+        ASSERT_TRUE(status.isOk());
+        OptIntVec out_lat = Fingerprint::cfg().getopt<OptIntVec>("operation_authenticate_latency");
+        ASSERT_TRUE(in_lat.size() == out_lat.size());
+        for (int i = 0; i < in_lat.size(); i++) {
+            ASSERT_TRUE(in_lat[i] == out_lat[i]);
+        }
+    }
+
+    std::vector<int32_t> bad_in_lats[] = {{}, {1, 2, 3}, {1, -3}};
+    for (auto const& in_lat : bad_in_lats) {
+        status = mVhal->setOperationAuthenticateLatency(in_lat);
+        ASSERT_TRUE(!status.isOk());
+        ASSERT_TRUE(status.getServiceSpecificError() == IVirtualHal::STATUS_INVALID_PARAMETER);
+    }
+}
+
+TEST_F(VirtualHalTest, setOperationAuthenticateDuration) {
+    ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
+            "operation_authenticate_duration", &IVirtualHal::setOperationAuthenticateDuration,
+            {0, 33});
+    ASSERT_TRUE(status.isOk());
+}
+
+TEST_F(VirtualHalTest, setOperationDetectInteractionDuration) {
+    ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
+            "operation_detect_interaction_duration",
+            &IVirtualHal::setOperationDetectInteractionDuration, {0, 34});
+    ASSERT_TRUE(status.isOk());
+}
+
+TEST_F(VirtualHalTest, setLockoutTimedDuration) {
+    ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
+            "lockout_timed_duration", &IVirtualHal::setLockoutTimedDuration, {0, 35});
+    ASSERT_TRUE(status.isOk());
+}
+
+TEST_F(VirtualHalTest, setLockoutTimedThreshold) {
+    ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
+            "lockout_timed_threshold", &IVirtualHal::setLockoutTimedThreshold, {0, 36});
+    ASSERT_TRUE(status.isOk());
+}
+
+TEST_F(VirtualHalTest, setLockoutPermanentThreshold) {
+    ndk::ScopedAStatus status = validateNonNegativeInputOfInt32(
+            "lockout_permanent_threshold", &IVirtualHal::setLockoutPermanentThreshold, {0, 37});
+    ASSERT_TRUE(status.isOk());
+}
+
+TEST_F(VirtualHalTest, setOthers) {
+    // Verify that there is no CHECK() failures
+    mVhal->setEnrollments({7, 6, 5});
+    mVhal->setChallenge(111222333444555666);
+    mVhal->setOperationAuthenticateError(4);
+    mVhal->setOperationEnrollError(5);
+    mVhal->setOperationEnrollLatency({4, 5});
+    mVhal->setOperationDetectInteractionError(6);
+    mVhal->setOperationDetectInteractionAcquired({{AcquiredInfo::START}, {AcquiredInfo::GOOD}});
+    mVhal->setLockout(false);
+    mVhal->setLockoutEnable(false);
+    mVhal->setSensorId(5);
+    mVhal->setMaxEnrollmentPerUser(6);
+    mVhal->setNavigationGuesture(false);
+    mVhal->setDetectInteraction(false);
+    mVhal->setDisplayTouch(false);
+    mVhal->setControlIllumination(false);
+}
+
+}  // namespace aidl::android::hardware::biometrics::fingerprint
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_startThreadPool();
+    return RUN_ALL_TESTS();
+}
diff --git a/broadcastradio/aidl/Android.bp b/broadcastradio/aidl/Android.bp
index 187f283..82ee949 100644
--- a/broadcastradio/aidl/Android.bp
+++ b/broadcastradio/aidl/Android.bp
@@ -36,6 +36,9 @@
             sdk_version: "module_current",
             min_sdk_version: "Tiramisu",
         },
+        rust: {
+            enabled: true,
+        },
     },
     versions_with_info: [
         {
@@ -51,3 +54,27 @@
     frozen: true,
 
 }
+
+// Note: This should always be one version ahead of the last frozen version
+latest_android_hardware_broadcastradio = "android.hardware.broadcastradio-V2"
+
+cc_defaults {
+    name: "latest_android_hardware_broadcastradio_ndk_static",
+    static_libs: [
+        latest_android_hardware_broadcastradio + "-ndk",
+    ],
+}
+
+java_defaults {
+    name: "latest_android_hardware_broadcastradio_java_static",
+    static_libs: [
+        latest_android_hardware_broadcastradio + "-java",
+    ],
+}
+
+rust_defaults {
+    name: "latest_android_hardware_broadcastradio_rust",
+    rustlibs: [
+        latest_android_hardware_broadcastradio + "-rust",
+    ],
+}
diff --git a/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl b/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
index 4a95a41..4d29743 100644
--- a/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
+++ b/broadcastradio/aidl/android/hardware/broadcastradio/IdentifierType.aidl
@@ -174,7 +174,7 @@
      * - 13 bit: Fractional bits of longitude
      * - 8 bit: Integer bits of longitude
      * - 1 bit: 0 for east and 1 for west for longitude
-     * - 1 bit: 0, representing latitude
+     * - 1 bit: 0, representing longitude
      * - 5 bit: pad of zeros separating longitude and latitude
      * - 4 bit: Bits 4:7 of altitude
      * - 13 bit: Fractional bits of latitude
diff --git a/broadcastradio/aidl/default/Android.bp b/broadcastradio/aidl/default/Android.bp
index d7bb751..b620a59 100644
--- a/broadcastradio/aidl/default/Android.bp
+++ b/broadcastradio/aidl/default/Android.bp
@@ -20,14 +20,17 @@
     // all of the 'license_kinds' from "hardware_interfaces_license"
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
 cc_defaults {
     name: "BroadcastRadioHalDefaults",
+    defaults: [
+        "latest_android_hardware_broadcastradio_ndk_static",
+    ],
     static_libs: [
-        "android.hardware.broadcastradio-V2-ndk",
-        "android.hardware.broadcastradio@common-utils-aidl-lib-V2",
+        "android.hardware.broadcastradio@common-utils-aidl-lib-latest",
         "android.hardware.broadcastradio@common-utils-lib",
     ],
     shared_libs: [
@@ -79,12 +82,12 @@
     // TODO(b/307611931): avoid fuzzing on vendor until hermiticity issue is fixed
     // vendor: true,
     defaults: [
+        "latest_android_hardware_broadcastradio_ndk_static",
         "BroadcastRadioHalDefaults",
         "service_fuzzer_defaults",
     ],
     static_libs: [
         "DefaultBroadcastRadioHal",
-        "android.hardware.broadcastradio-V2-ndk",
     ],
     srcs: [
         "fuzzer.cpp",
diff --git a/broadcastradio/aidl/rust_impl/Android.bp b/broadcastradio/aidl/rust_impl/Android.bp
new file mode 100644
index 0000000..d6f984e
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/Android.bp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+rust_binary {
+    name: "android.hardware.broadcastradio-rust-service",
+    relative_install_path: "hw",
+    vendor: true,
+    srcs: ["src/*.rs"],
+    crate_root: "src/main.rs",
+    defaults: [
+        "latest_android_hardware_broadcastradio_rust",
+    ],
+    vintf_fragments: ["broadcastradio-rust-service.xml"],
+    init_rc: ["broadcastradio-rust-service.rc"],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+}
diff --git a/broadcastradio/aidl/rust_impl/README.md b/broadcastradio/aidl/rust_impl/README.md
new file mode 100644
index 0000000..17e0c18
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/README.md
@@ -0,0 +1,13 @@
+# Rust Skeleton BroadcastRadio HAL implementation.
+
+WARNING: This is not a reference BroadcastRadio HAL implementation and does
+not contain any actual implementation.
+
+This folder contains a skeleton broadcast radio HAL implementation in Rust to
+demonstrate  how vendor may implement a Rust broadcast radio HAL. To run this
+broadcast radio HAL, include `android.hardware.broadcastradio-rust-service`
+in your image.
+
+This implementation returns `StatusCode::UNKNOWN_ERROR` for all operations
+and does not pass VTS/CTS. Vendor must replace the logic in
+`default_broadcastradio_hal.rs` with the actual implementation
\ No newline at end of file
diff --git a/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.rc b/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.rc
new file mode 100644
index 0000000..4dad616
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.rc
@@ -0,0 +1,5 @@
+service vendor.broadcastradio-default /vendor/bin/hw/android.hardware.broadcastradio-service.default
+    interface aidl android.hardware.broadcastradio.IBroadcastRadio/amfm
+    class hal
+    user audioserver
+    group audio
diff --git a/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.xml b/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.xml
new file mode 100644
index 0000000..ced2d78
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/broadcastradio-rust-service.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.broadcastradio</name>
+        <version>2</version>
+        <fqname>IBroadcastRadio/amfm</fqname>
+    </hal>
+</manifest>
diff --git a/broadcastradio/aidl/rust_impl/src/default_broadcastradio_hal.rs b/broadcastradio/aidl/rust_impl/src/default_broadcastradio_hal.rs
new file mode 100644
index 0000000..ea2f9d3
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/src/default_broadcastradio_hal.rs
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+use android_hardware_broadcastradio::aidl::android::hardware::broadcastradio::{
+    AmFmRegionConfig::AmFmRegionConfig,
+    AnnouncementType::AnnouncementType,
+    ConfigFlag::ConfigFlag,
+    DabTableEntry::DabTableEntry,
+    IAnnouncementListener::IAnnouncementListener,
+    IBroadcastRadio::IBroadcastRadio,
+    ICloseHandle::ICloseHandle,
+    ITunerCallback::ITunerCallback,
+    ProgramFilter::ProgramFilter,
+    ProgramSelector::ProgramSelector,
+    Properties::Properties,
+    VendorKeyValue::VendorKeyValue,
+};
+use binder::{Interface, Result as BinderResult, StatusCode, Strong};
+use std::vec::Vec;
+
+/// This struct is defined to implement IBroadcastRadio AIDL interface.
+pub struct DefaultBroadcastRadioHal;
+
+impl Interface for DefaultBroadcastRadioHal {}
+
+impl IBroadcastRadio for DefaultBroadcastRadioHal {
+    fn getAmFmRegionConfig(&self, _full : bool) -> BinderResult<AmFmRegionConfig> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getDabRegionConfig(&self) -> BinderResult<Vec<DabTableEntry>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getProperties(&self) -> BinderResult<Properties> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getImage(&self, _id : i32) -> BinderResult<Vec<u8>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setTunerCallback(&self, _callback : &Strong<dyn ITunerCallback>) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn unsetTunerCallback(&self) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn tune(&self, _program : &ProgramSelector) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn seek(&self, _direction_up : bool, _skip_sub_channel : bool) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn step(&self, _direction_up : bool) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn cancel(&self) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn startProgramListUpdates(&self, _filter : &ProgramFilter) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn stopProgramListUpdates(&self) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn isConfigFlagSet(&self, _flag : ConfigFlag) -> BinderResult<bool> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setConfigFlag(&self, _flag : ConfigFlag, _value : bool) -> BinderResult<()> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn setParameters(&self, _parameters : &[VendorKeyValue]) -> BinderResult<Vec<VendorKeyValue>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn getParameters(&self, _parameters : &[String]) -> BinderResult<Vec<VendorKeyValue>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+
+    fn registerAnnouncementListener(&self, _listener : &Strong<dyn IAnnouncementListener>,
+            _enabled : &[AnnouncementType]) -> BinderResult<Strong<dyn ICloseHandle>> {
+        Err(StatusCode::UNKNOWN_ERROR.into())
+    }
+}
diff --git a/broadcastradio/aidl/rust_impl/src/main.rs b/broadcastradio/aidl/rust_impl/src/main.rs
new file mode 100644
index 0000000..c0bc055
--- /dev/null
+++ b/broadcastradio/aidl/rust_impl/src/main.rs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ mod default_broadcastradio_hal;
+
+use android_hardware_broadcastradio::aidl::android::hardware::broadcastradio::IBroadcastRadio::BnBroadcastRadio;
+use crate::default_broadcastradio_hal::DefaultBroadcastRadioHal;
+
+fn main() {
+    binder::ProcessState::start_thread_pool();
+    let my_service = DefaultBroadcastRadioHal;
+    let service_name = "android.hardware.broadcastradio.IBroadcastRadio/amfm";
+    let my_service_binder = BnBroadcastRadio::new_binder(
+        my_service,
+        binder::BinderFeatures::default(),
+    );
+    binder::add_service(service_name, my_service_binder.as_binder())
+    		.expect(format!("Failed to register {}?", service_name).as_str());
+    // Does not return.
+    binder::ProcessState::join_thread_pool()
+}
diff --git a/broadcastradio/aidl/vts/Android.bp b/broadcastradio/aidl/vts/Android.bp
index 87e48a9..78c377d 100644
--- a/broadcastradio/aidl/vts/Android.bp
+++ b/broadcastradio/aidl/vts/Android.bp
@@ -18,6 +18,7 @@
     // all of the 'license_kinds' from "hardware_interfaces_license"
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
+    default_team: "trendy_team_aaos_framework",
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
@@ -25,6 +26,7 @@
     name: "VtsHalBroadcastradioAidlTargetTest",
     defaults: [
         "VtsHalTargetTestDefaults",
+        "latest_android_hardware_broadcastradio_ndk_static",
         "use_libaidlvintf_gtest_helper_static",
     ],
     tidy_timeout_srcs: ["src/*.cpp"],
@@ -35,9 +37,7 @@
         "libxml2",
     ],
     static_libs: [
-        "android.hardware.broadcastradio-V2-ndk",
-        "android.hardware.broadcastradio@common-utils-aidl-lib-V2",
-        "android.hardware.broadcastradio@vts-utils-lib",
+        "android.hardware.broadcastradio@common-utils-aidl-lib-latest",
         "libgmock",
     ],
     test_suites: [
diff --git a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
index 9633ebb..ee0c639 100644
--- a/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
+++ b/broadcastradio/aidl/vts/src/VtsHalBroadcastradioAidlTargetTest.cpp
@@ -193,7 +193,7 @@
 
 MATCHER_P(InfoHasId, id,
           std::string(negation ? "does not contain" : "contains") + " " + id.toString()) {
-    vector<int> ids = bcutils::getAllIds(arg.selector, id.type);
+    vector<int64_t> ids = bcutils::getAllIds(arg.selector, id.type);
     return ids.end() != find(ids.begin(), ids.end(), id.value);
 }
 
@@ -697,7 +697,7 @@
     LOG(DEBUG) << "Current program info: " << infoCb.toString();
 
     // it should tune exactly to what was requested
-    vector<int> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::AMFM_FREQUENCY_KHZ);
+    vector<int64_t> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::AMFM_FREQUENCY_KHZ);
     EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq))
             << "FM freq " << freq << " kHz is not sent back by callback.";
 }
@@ -829,7 +829,7 @@
     LOG(DEBUG) << "Current program info: " << infoCb.toString();
 
     // it should tune exactly to what was requested
-    vector<int> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::DAB_FREQUENCY_KHZ);
+    vector<int64_t> freqs = bcutils::getAllIds(infoCb.selector, IdentifierType::DAB_FREQUENCY_KHZ);
     EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq))
             << "DAB freq " << freq << " kHz is not sent back by callback.";
 }
@@ -1152,7 +1152,7 @@
     int expectedResultSize = 0;
     uint64_t expectedFreq = 0;
     for (const auto& program : *completeList) {
-        vector<int> amfmIds =
+        vector<int64_t> amfmIds =
                 bcutils::getAllIds(program.selector, IdentifierType::AMFM_FREQUENCY_KHZ);
         EXPECT_LE(amfmIds.size(), 1u);
         if (amfmIds.size() == 0) {
@@ -1238,7 +1238,8 @@
     }
 
     for (const auto& program : *list) {
-        vector<int> nameIds = bcutils::getAllIds(program.selector, IdentifierType::HD_STATION_NAME);
+        vector<int64_t> nameIds =
+                bcutils::getAllIds(program.selector, IdentifierType::HD_STATION_NAME);
         EXPECT_LE(nameIds.size(), 1u);
         if (nameIds.size() == 0) {
             continue;
diff --git a/broadcastradio/common/utilsaidl/Android.bp b/broadcastradio/common/utilsaidl/Android.bp
index e3bdfdd..d88081f 100644
--- a/broadcastradio/common/utilsaidl/Android.bp
+++ b/broadcastradio/common/utilsaidl/Android.bp
@@ -47,17 +47,28 @@
     ],
 }
 
+cc_library_static {
+    name: "android.hardware.broadcastradio@common-utils-aidl-lib-latest",
+    defaults: [
+        "BroadcastRadioUtilsDefaults",
+        "latest_android_hardware_broadcastradio_ndk_static",
+    ],
+    srcs: [
+        "src/UtilsV2.cpp",
+    ],
+}
+
 cc_test {
     name: "broadcastradio_utils_aidl_test",
     defaults: [
         "BroadcastRadioUtilsDefaults",
+        "latest_android_hardware_broadcastradio_ndk_static",
     ],
     srcs: [
         "test/*.cpp",
     ],
     static_libs: [
-        "android.hardware.broadcastradio@common-utils-aidl-lib-V2",
-        "android.hardware.broadcastradio-V2-ndk",
+        "android.hardware.broadcastradio@common-utils-aidl-lib-latest",
     ],
     test_suites: ["general-tests"],
 }
diff --git a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
index 25c96d0..a34ee10 100644
--- a/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
+++ b/broadcastradio/common/utilsaidl/include/broadcastradio-utils-aidl/Utils.h
@@ -121,7 +121,7 @@
 /**
  * Returns all IDs of a given type.
  */
-std::vector<int> getAllIds(const ProgramSelector& sel, const IdentifierType& type);
+std::vector<int64_t> getAllIds(const ProgramSelector& sel, const IdentifierType& type);
 
 /**
  * Checks, if a given selector is supported by the radio module.
diff --git a/broadcastradio/common/utilsaidl/src/Utils.cpp b/broadcastradio/common/utilsaidl/src/Utils.cpp
index ddc5b8d..3de1866 100644
--- a/broadcastradio/common/utilsaidl/src/Utils.cpp
+++ b/broadcastradio/common/utilsaidl/src/Utils.cpp
@@ -178,8 +178,8 @@
     return getId(sel, type);
 }
 
-vector<int> getAllIds(const ProgramSelector& sel, const IdentifierType& type) {
-    vector<int> ret;
+vector<int64_t> getAllIds(const ProgramSelector& sel, const IdentifierType& type) {
+    vector<int64_t> ret;
 
     // iterate through primaryId and secondaryIds
     for (auto it = begin(sel); it != end(sel); it++) {
@@ -296,7 +296,12 @@
          sel.primaryId.type > IdentifierType::VENDOR_END)) {
         return false;
     }
-    return isValid(sel.primaryId);
+    for (auto it = begin(sel); it != end(sel); it++) {
+        if (!isValid(*it)) {
+            return false;
+        }
+    }
+    return true;
 }
 
 ProgramIdentifier makeIdentifier(IdentifierType type, int64_t value) {
diff --git a/broadcastradio/common/utilsaidl/src/UtilsV2.cpp b/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
index 6c75759..56365c5 100644
--- a/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
+++ b/broadcastradio/common/utilsaidl/src/UtilsV2.cpp
@@ -102,15 +102,16 @@
             expect(val < 1000u, "SXM channel < 1000");
             break;
         case IdentifierType::HD_STATION_LOCATION: {
+            val >>= 26;
             uint64_t latitudeBit = val & 0x1;
-            expect(latitudeBit == 1u, "Latitude comes first");
-            val >>= 27;
+            expect(latitudeBit == 0u, "Longitude comes first");
+            val >>= 1;
             uint64_t latitudePad = val & 0x1Fu;
-            expect(latitudePad == 0u, "Latitude padding");
-            val >>= 5;
+            expect(latitudePad == 0u, "Longitude padding");
+            val >>= 31;
             uint64_t longitudeBit = val & 0x1;
-            expect(longitudeBit == 1u, "Longitude comes next");
-            val >>= 27;
+            expect(longitudeBit == 1u, "Latitude comes next");
+            val >>= 1;
             uint64_t longitudePad = val & 0x1Fu;
             expect(longitudePad == 0u, "Latitude padding");
             break;
@@ -135,7 +136,12 @@
          sel.primaryId.type > IdentifierType::VENDOR_END)) {
         return false;
     }
-    return isValidV2(sel.primaryId);
+    for (auto it = begin(sel); it != end(sel); it++) {
+        if (!isValidV2(*it)) {
+            return false;
+        }
+    }
+    return true;
 }
 
 bool isValidMetadataV2(const Metadata& metadata) {
diff --git a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsCommonTest.cpp b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsCommonTest.cpp
new file mode 100644
index 0000000..b71bf03
--- /dev/null
+++ b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsCommonTest.cpp
@@ -0,0 +1,421 @@
+/*
+ * 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 <broadcastradio-utils-aidl/UtilsV2.h>
+#include <gtest/gtest.h>
+
+namespace aidl::android::hardware::broadcastradio {
+
+namespace {
+constexpr int64_t kFmFrequencyKHz = 97900;
+constexpr uint32_t kDabSid = 0x0000C221u;
+constexpr int kDabEccCode = 0xE1u;
+constexpr int kDabSCIdS = 0x1u;
+constexpr uint64_t kDabSidExt = static_cast<uint64_t>(kDabSid) |
+                                (static_cast<uint64_t>(kDabEccCode) << 32) |
+                                (static_cast<uint64_t>(kDabSCIdS) << 40);
+constexpr uint32_t kDabEnsemble = 0xCE15u;
+constexpr uint64_t kDabFrequencyKhz = 225648u;
+constexpr uint64_t kHdStationId = 0xA0000001u;
+constexpr uint64_t kHdSubChannel = 1u;
+constexpr uint64_t kHdStationLocation = 0x44E647003665CF6u;
+constexpr uint64_t kHdStationLocationInvalid = 0x4E647007665CF6u;
+constexpr uint64_t kHdFrequency = 97700u;
+constexpr int64_t kRdsValue = 0xBEEF;
+
+struct IsValidIdentifierTestCase {
+    std::string name;
+    ProgramIdentifier id;
+    bool valid;
+};
+
+std::vector<IsValidIdentifierTestCase> getIsValidIdentifierTestCases() {
+    return std::vector<IsValidIdentifierTestCase>({
+            IsValidIdentifierTestCase{.name = "invalid_id_type",
+                                      .id = utils::makeIdentifier(IdentifierType::INVALID, 0),
+                                      .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_dab_frequency_high",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 10000000u),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_dab_frequency_low",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 100000u),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "valid_dab_frequency",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 1000000u),
+                    .valid = true},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_am_fm_frequency_high",
+                    .id = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 10000000u),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_am_fm_frequency_low",
+                    .id = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 100u),
+                    .valid = false},
+            IsValidIdentifierTestCase{.name = "valid_am_fm_frequency",
+                                      .id = utils::makeIdentifier(
+                                              IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz),
+                                      .valid = true},
+            IsValidIdentifierTestCase{
+                    .name = "drmo_frequency_high",
+                    .id = utils::makeIdentifier(IdentifierType::DRMO_FREQUENCY_KHZ, 10000000u),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "drmo_frequency_low",
+                    .id = utils::makeIdentifier(IdentifierType::DRMO_FREQUENCY_KHZ, 100u),
+                    .valid = false},
+            IsValidIdentifierTestCase{.name = "valid_drmo_frequency",
+                                      .id = utils::makeIdentifier(
+                                              IdentifierType::DRMO_FREQUENCY_KHZ, kFmFrequencyKHz),
+                                      .valid = true},
+            IsValidIdentifierTestCase{.name = "invalid_rds_low",
+                                      .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x0),
+                                      .valid = false},
+            IsValidIdentifierTestCase{.name = "invalid_rds_high",
+                                      .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x10000),
+                                      .valid = false},
+            IsValidIdentifierTestCase{.name = "valid_rds",
+                                      .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x1000),
+                                      .valid = true},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_hd_id_zero",
+                    .id = utils::makeSelectorHd(/* stationId= */ 0u, kHdSubChannel, kHdFrequency)
+                                  .primaryId,
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_hd_suchannel",
+                    .id = utils::makeSelectorHd(kHdStationId, /* subChannel= */ 8u, kHdFrequency)
+                                  .primaryId,
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_hd_frequency_low",
+                    .id = utils::makeSelectorHd(kHdStationId, kHdSubChannel, /* frequency= */ 100u)
+                                  .primaryId,
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "valid_hd_id",
+                    .id = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency)
+                                  .primaryId,
+                    .valid = true},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_hd_station_name",
+                    .id = utils::makeIdentifier(IdentifierType::HD_STATION_NAME, 0x41422D464D),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "valid_hd_station_name",
+                    .id = utils::makeIdentifier(IdentifierType::HD_STATION_NAME, 0x414231464D),
+                    .valid = true},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_dab_sid",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x0E100000000u),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_dab_ecc_low",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x0F700000221u),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_dab_ecc_high",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x09900000221u),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "valid_dab_sid_ext",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, kDabSidExt),
+                    .valid = true},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_dab_ensemble_zero",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, 0x0),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_dab_ensemble_high",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, 0x10000),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "valid_dab_ensemble",
+                    .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, kDabEnsemble),
+                    .valid = true},
+            IsValidIdentifierTestCase{.name = "invalid_dab_scid_low",
+                                      .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0xF),
+                                      .valid = false},
+            IsValidIdentifierTestCase{.name = "invalid_dab_scid_high",
+                                      .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0x1000),
+                                      .valid = false},
+            IsValidIdentifierTestCase{.name = "valid_dab_scid",
+                                      .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0x100),
+                                      .valid = true},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_drmo_id_zero",
+                    .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x0),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "invalid_drmo_id_high",
+                    .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x1000000),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "valid_drmo_id",
+                    .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x100000),
+                    .valid = true},
+    });
+}
+
+std::vector<IsValidIdentifierTestCase> getIsValidIdentifierV2TestCases() {
+    std::vector<IsValidIdentifierTestCase> testcases = getIsValidIdentifierTestCases();
+    std::vector<IsValidIdentifierTestCase> testcasesNew = std::vector<IsValidIdentifierTestCase>({
+            IsValidIdentifierTestCase{
+                    .name = "invalid_hd_station_location_id",
+                    .id = utils::makeIdentifier(IdentifierType::HD_STATION_LOCATION,
+                                                kHdStationLocationInvalid),
+                    .valid = false},
+            IsValidIdentifierTestCase{
+                    .name = "valid_hd_station_location_id",
+                    .id = utils::makeIdentifier(IdentifierType::HD_STATION_LOCATION,
+                                                kHdStationLocation),
+                    .valid = true},
+    });
+    testcases.insert(testcases.end(), testcasesNew.begin(), testcasesNew.end());
+    return testcases;
+}
+
+struct IsValidSelectorTestCase {
+    std::string name;
+    ProgramSelector sel;
+    bool valid;
+};
+
+std::vector<IsValidSelectorTestCase> getIsValidSelectorTestCases() {
+    return std::vector<IsValidSelectorTestCase>({
+            IsValidSelectorTestCase{.name = "valid_am_fm_selector",
+                                    .sel = utils::makeSelectorAmfm(kFmFrequencyKHz),
+                                    .valid = true},
+            IsValidSelectorTestCase{
+                    .name = "valid_hd_selector",
+                    .sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency),
+                    .valid = true},
+            IsValidSelectorTestCase{
+                    .name = "valid_dab_selector",
+                    .sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz),
+                    .valid = true},
+            IsValidSelectorTestCase{.name = "valid_rds_selector",
+                                    .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
+                                                                   IdentifierType::RDS_PI, 0x1000)},
+                                    .valid = true},
+            IsValidSelectorTestCase{.name = "selector_with_invalid_id",
+                                    .sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel,
+                                                                 /* frequency= */ 100u),
+                                    .valid = false},
+            IsValidSelectorTestCase{
+                    .name = "selector_with_invalid_primary_id_type",
+                    .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
+                                                   IdentifierType::DAB_ENSEMBLE, kDabEnsemble)},
+                    .valid = false},
+            IsValidSelectorTestCase{
+                    .name = "selector_with_invalid_secondary_id",
+                    .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
+                                                   IdentifierType::DAB_SID_EXT, kDabSidExt),
+                                           .secondaryIds = {utils::makeIdentifier(
+                                                   IdentifierType::DAB_ENSEMBLE, 0x0)}},
+                    .valid = false},
+    });
+}
+
+std::vector<IsValidSelectorTestCase> getIsValidSelectorV2TestCases() {
+    ProgramSelector validHdSel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+    validHdSel.secondaryIds = {
+            utils::makeIdentifier(IdentifierType::HD_STATION_LOCATION, kHdStationLocation)};
+    ProgramSelector invalidHdSel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency);
+    invalidHdSel.secondaryIds = {
+            utils::makeIdentifier(IdentifierType::HD_STATION_LOCATION, kHdStationLocationInvalid)};
+    std::vector<IsValidSelectorTestCase> testcasesNew = std::vector<IsValidSelectorTestCase>(
+            {IsValidSelectorTestCase{.name = "hd_selector_with_valid_station_location",
+                                     .sel = validHdSel,
+                                     .valid = true},
+             IsValidSelectorTestCase{.name = "hd_selector_with_invalid_station_location",
+                                     .sel = invalidHdSel,
+                                     .valid = false}});
+    std::vector<IsValidSelectorTestCase> testcases = getIsValidSelectorTestCases();
+    testcases.insert(testcases.end(), testcasesNew.begin(), testcasesNew.end());
+    return testcases;
+}
+
+struct IsValidMetadataTestCase {
+    std::string name;
+    Metadata metadata;
+    bool valid;
+};
+
+std::vector<IsValidMetadataTestCase> getIsValidMetadataTestCases() {
+    return std::vector<IsValidMetadataTestCase>({
+            IsValidMetadataTestCase{.name = "valid_rds_pty",
+                                    .metadata = Metadata::make<Metadata::rdsPty>(1),
+                                    .valid = true},
+            IsValidMetadataTestCase{.name = "negative_rds_pty",
+                                    .metadata = Metadata::make<Metadata::rdsPty>(-1),
+                                    .valid = false},
+            IsValidMetadataTestCase{.name = "large_rds_pty",
+                                    .metadata = Metadata::make<Metadata::rdsPty>(256),
+                                    .valid = false},
+            IsValidMetadataTestCase{.name = "valid_rbds_pty",
+                                    .metadata = Metadata::make<Metadata::rbdsPty>(1),
+                                    .valid = true},
+            IsValidMetadataTestCase{.name = "negative_rbds_pty",
+                                    .metadata = Metadata::make<Metadata::rbdsPty>(-1),
+                                    .valid = false},
+            IsValidMetadataTestCase{.name = "large_rbds_pty",
+                                    .metadata = Metadata::make<Metadata::rbdsPty>(256),
+                                    .valid = false},
+            IsValidMetadataTestCase{
+                    .name = "valid_dab_ensemble_name_short",
+                    .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name"),
+                    .valid = true},
+            IsValidMetadataTestCase{
+                    .name = "too_long_dab_ensemble_name_short",
+                    .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name_long"),
+                    .valid = false},
+            IsValidMetadataTestCase{
+                    .name = "valid_dab_service_name_short",
+                    .metadata = Metadata::make<Metadata::dabServiceNameShort>("name"),
+                    .valid = true},
+            IsValidMetadataTestCase{
+                    .name = "too_long_dab_service_name_short",
+                    .metadata = Metadata::make<Metadata::dabServiceNameShort>("name_long"),
+                    .valid = false},
+            IsValidMetadataTestCase{
+                    .name = "valid_dab_component_name_short",
+                    .metadata = Metadata::make<Metadata::dabComponentNameShort>("name"),
+                    .valid = true},
+            IsValidMetadataTestCase{
+                    .name = "too_long_dab_component_name_short",
+                    .metadata = Metadata::make<Metadata::dabComponentNameShort>("name_long"),
+                    .valid = false},
+    });
+}
+
+std::vector<IsValidMetadataTestCase> getIsValidMetadataV2TestCases() {
+    std::vector<IsValidMetadataTestCase> testcases = getIsValidMetadataTestCases();
+    std::vector<IsValidMetadataTestCase> testcasesNew = std::vector<IsValidMetadataTestCase>({
+            IsValidMetadataTestCase{
+                    .name = "valid_hd_station_name_short",
+                    .metadata = Metadata::make<Metadata::hdStationNameShort>("name_short"),
+                    .valid = true},
+            IsValidMetadataTestCase{
+                    .name = "too_long_hd_station_name_short",
+                    .metadata = Metadata::make<Metadata::hdStationNameShort>("name_too_long"),
+                    .valid = false},
+            IsValidMetadataTestCase{.name = "valid_hd_subchannel_available",
+                                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(1),
+                                    .valid = true},
+            IsValidMetadataTestCase{
+                    .name = "negative_subchannel_available",
+                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(-1),
+                    .valid = false},
+            IsValidMetadataTestCase{
+                    .name = "large_subchannel_available",
+                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(256),
+                    .valid = false},
+    });
+    testcases.insert(testcases.end(), testcasesNew.begin(), testcasesNew.end());
+    return testcases;
+}
+}  // namespace
+
+class IsValidIdentifierTest : public testing::TestWithParam<IsValidIdentifierTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidIdentifierTests, IsValidIdentifierTest,
+                         testing::ValuesIn(getIsValidIdentifierTestCases()),
+                         [](const testing::TestParamInfo<IsValidIdentifierTest::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(IsValidIdentifierTest, IsValid) {
+    IsValidIdentifierTestCase testcase = GetParam();
+
+    ASSERT_EQ(utils::isValid(testcase.id), testcase.valid);
+}
+
+class IsValidIdentifierV2Test : public testing::TestWithParam<IsValidIdentifierTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(
+        IsValidIdentifierV2Tests, IsValidIdentifierV2Test,
+        testing::ValuesIn(getIsValidIdentifierV2TestCases()),
+        [](const testing::TestParamInfo<IsValidIdentifierV2Test::ParamType>& info) {
+            return info.param.name;
+        });
+
+TEST_P(IsValidIdentifierV2Test, IsValidV2) {
+    IsValidIdentifierTestCase testcase = GetParam();
+
+    ASSERT_EQ(utils::isValidV2(testcase.id), testcase.valid);
+}
+
+class IsValidSelectorTest : public testing::TestWithParam<IsValidSelectorTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidSelectorTests, IsValidSelectorTest,
+                         testing::ValuesIn(getIsValidSelectorTestCases()),
+                         [](const testing::TestParamInfo<IsValidSelectorTest::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(IsValidSelectorTest, IsValid) {
+    IsValidSelectorTestCase testcase = GetParam();
+
+    ASSERT_EQ(utils::isValid(testcase.sel), testcase.valid);
+}
+
+class IsValidSelectorV2Test : public testing::TestWithParam<IsValidSelectorTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidSelectorV2Tests, IsValidSelectorV2Test,
+                         testing::ValuesIn(getIsValidSelectorV2TestCases()),
+                         [](const testing::TestParamInfo<IsValidSelectorV2Test::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(IsValidSelectorV2Test, IsValidV2) {
+    IsValidSelectorTestCase testcase = GetParam();
+
+    ASSERT_EQ(utils::isValidV2(testcase.sel), testcase.valid);
+}
+
+class IsValidMetadataTest : public testing::TestWithParam<IsValidMetadataTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidMetadataTests, IsValidMetadataTest,
+                         testing::ValuesIn(getIsValidMetadataTestCases()),
+                         [](const testing::TestParamInfo<IsValidMetadataTest::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(IsValidMetadataTest, IsValidMetadata) {
+    IsValidMetadataTestCase testParam = GetParam();
+
+    ASSERT_EQ(utils::isValidMetadata(testParam.metadata), testParam.valid);
+}
+
+class IsValidMetadataV2Test : public testing::TestWithParam<IsValidMetadataTestCase> {};
+
+INSTANTIATE_TEST_SUITE_P(IsValidMetadataV2Tests, IsValidMetadataV2Test,
+                         testing::ValuesIn(getIsValidMetadataV2TestCases()),
+                         [](const testing::TestParamInfo<IsValidMetadataV2Test::ParamType>& info) {
+                             return info.param.name;
+                         });
+
+TEST_P(IsValidMetadataV2Test, IsValidMetadataV2) {
+    IsValidMetadataTestCase testParam = GetParam();
+
+    ASSERT_EQ(utils::isValidMetadataV2(testParam.metadata), testParam.valid);
+}
+
+}  // namespace aidl::android::hardware::broadcastradio
diff --git a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
index a5c9073..81f9470 100644
--- a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
+++ b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsTest.cpp
@@ -66,230 +66,6 @@
                              .frequency = 110000,
                              .bandResult = utils::FrequencyBand::UNKNOWN}});
 }
-
-struct IsValidIdentifierTestCase {
-    std::string name;
-    ProgramIdentifier id;
-    bool valid;
-};
-
-std::vector<IsValidIdentifierTestCase> getIsValidIdentifierTestCases() {
-    return std::vector<IsValidIdentifierTestCase>({
-            IsValidIdentifierTestCase{.name = "invalid_id_type",
-                                      .id = utils::makeIdentifier(IdentifierType::INVALID, 0),
-                                      .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_dab_frequency_high",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 10000000u),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_dab_frequency_low",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 100000u),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "valid_dab_frequency",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_FREQUENCY_KHZ, 1000000u),
-                    .valid = true},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_am_fm_frequency_high",
-                    .id = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 10000000u),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_am_fm_frequency_low",
-                    .id = utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, 100u),
-                    .valid = false},
-            IsValidIdentifierTestCase{.name = "valid_am_fm_frequency",
-                                      .id = utils::makeIdentifier(
-                                              IdentifierType::AMFM_FREQUENCY_KHZ, kFmFrequencyKHz),
-                                      .valid = true},
-            IsValidIdentifierTestCase{
-                    .name = "drmo_frequency_high",
-                    .id = utils::makeIdentifier(IdentifierType::DRMO_FREQUENCY_KHZ, 10000000u),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "drmo_frequency_low",
-                    .id = utils::makeIdentifier(IdentifierType::DRMO_FREQUENCY_KHZ, 100u),
-                    .valid = false},
-            IsValidIdentifierTestCase{.name = "valid_drmo_frequency",
-                                      .id = utils::makeIdentifier(
-                                              IdentifierType::DRMO_FREQUENCY_KHZ, kFmFrequencyKHz),
-                                      .valid = true},
-            IsValidIdentifierTestCase{.name = "invalid_rds_low",
-                                      .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x0),
-                                      .valid = false},
-            IsValidIdentifierTestCase{.name = "invalid_rds_high",
-                                      .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x10000),
-                                      .valid = false},
-            IsValidIdentifierTestCase{.name = "valid_rds",
-                                      .id = utils::makeIdentifier(IdentifierType::RDS_PI, 0x1000),
-                                      .valid = true},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_hd_id_zero",
-                    .id = utils::makeSelectorHd(/* stationId= */ 0u, kHdSubChannel, kHdFrequency)
-                                  .primaryId,
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_hd_suchannel",
-                    .id = utils::makeSelectorHd(kHdStationId, /* subChannel= */ 8u, kHdFrequency)
-                                  .primaryId,
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_hd_frequency_low",
-                    .id = utils::makeSelectorHd(kHdStationId, kHdSubChannel, /* frequency= */ 100u)
-                                  .primaryId,
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "valid_hd_id",
-                    .id = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency)
-                                  .primaryId,
-                    .valid = true},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_hd_station_name",
-                    .id = utils::makeIdentifier(IdentifierType::HD_STATION_NAME, 0x41422D464D),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "valid_hd_station_name",
-                    .id = utils::makeIdentifier(IdentifierType::HD_STATION_NAME, 0x414231464D),
-                    .valid = true},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_dab_sid",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x0E100000000u),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_dab_ecc_low",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x0F700000221u),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_dab_ecc_high",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, 0x09900000221u),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "valid_dab_sid_ext",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_SID_EXT, kDabSidExt),
-                    .valid = true},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_dab_ensemble_zero",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, 0x0),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_dab_ensemble_high",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, 0x10000),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "valid_dab_ensemble",
-                    .id = utils::makeIdentifier(IdentifierType::DAB_ENSEMBLE, kDabEnsemble),
-                    .valid = true},
-            IsValidIdentifierTestCase{.name = "invalid_dab_scid_low",
-                                      .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0xF),
-                                      .valid = false},
-            IsValidIdentifierTestCase{.name = "invalid_dab_scid_high",
-                                      .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0x1000),
-                                      .valid = false},
-            IsValidIdentifierTestCase{.name = "valid_dab_scid",
-                                      .id = utils::makeIdentifier(IdentifierType::DAB_SCID, 0x100),
-                                      .valid = true},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_drmo_id_zero",
-                    .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x0),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "invalid_drmo_id_high",
-                    .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x1000000),
-                    .valid = false},
-            IsValidIdentifierTestCase{
-                    .name = "valid_drmo_id",
-                    .id = utils::makeIdentifier(IdentifierType::DRMO_SERVICE_ID, 0x100000),
-                    .valid = true},
-    });
-}
-
-struct IsValidSelectorTestCase {
-    std::string name;
-    ProgramSelector sel;
-    bool valid;
-};
-
-std::vector<IsValidSelectorTestCase> getIsValidSelectorTestCases() {
-    return std::vector<IsValidSelectorTestCase>({
-            IsValidSelectorTestCase{.name = "valid_am_fm_selector",
-                                    .sel = utils::makeSelectorAmfm(kFmFrequencyKHz),
-                                    .valid = true},
-            IsValidSelectorTestCase{
-                    .name = "valid_hd_selector",
-                    .sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel, kHdFrequency),
-                    .valid = true},
-            IsValidSelectorTestCase{
-                    .name = "valid_dab_selector",
-                    .sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz),
-                    .valid = true},
-            IsValidSelectorTestCase{.name = "valid_rds_selector",
-                                    .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
-                                                                   IdentifierType::RDS_PI, 0x1000)},
-                                    .valid = true},
-            IsValidSelectorTestCase{.name = "selector_with_invalid_id",
-                                    .sel = utils::makeSelectorHd(kHdStationId, kHdSubChannel,
-                                                                 /* frequency= */ 100u),
-                                    .valid = false},
-            IsValidSelectorTestCase{
-                    .name = "selector_with_invalid_primary_id_type",
-                    .sel = ProgramSelector{.primaryId = utils::makeIdentifier(
-                                                   IdentifierType::DAB_ENSEMBLE, kDabEnsemble)},
-                    .valid = false},
-    });
-}
-
-struct IsValidMetadataTestCase {
-    std::string name;
-    Metadata metadata;
-    bool valid;
-};
-
-std::vector<IsValidMetadataTestCase> getIsValidMetadataTestCases() {
-    return std::vector<IsValidMetadataTestCase>({
-            IsValidMetadataTestCase{.name = "valid_rds_pty",
-                                    .metadata = Metadata::make<Metadata::rdsPty>(1),
-                                    .valid = true},
-            IsValidMetadataTestCase{.name = "negative_rds_pty",
-                                    .metadata = Metadata::make<Metadata::rdsPty>(-1),
-                                    .valid = false},
-            IsValidMetadataTestCase{.name = "large_rds_pty",
-                                    .metadata = Metadata::make<Metadata::rdsPty>(256),
-                                    .valid = false},
-            IsValidMetadataTestCase{.name = "valid_rbds_pty",
-                                    .metadata = Metadata::make<Metadata::rbdsPty>(1),
-                                    .valid = true},
-            IsValidMetadataTestCase{.name = "negative_rbds_pty",
-                                    .metadata = Metadata::make<Metadata::rbdsPty>(-1),
-                                    .valid = false},
-            IsValidMetadataTestCase{.name = "large_rbds_pty",
-                                    .metadata = Metadata::make<Metadata::rbdsPty>(256),
-                                    .valid = false},
-            IsValidMetadataTestCase{
-                    .name = "valid_dab_ensemble_name_short",
-                    .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name"),
-                    .valid = true},
-            IsValidMetadataTestCase{
-                    .name = "too_long_dab_ensemble_name_short",
-                    .metadata = Metadata::make<Metadata::dabEnsembleNameShort>("name_long"),
-                    .valid = false},
-            IsValidMetadataTestCase{
-                    .name = "valid_dab_service_name_short",
-                    .metadata = Metadata::make<Metadata::dabServiceNameShort>("name"),
-                    .valid = true},
-            IsValidMetadataTestCase{
-                    .name = "too_long_dab_service_name_short",
-                    .metadata = Metadata::make<Metadata::dabServiceNameShort>("name_long"),
-                    .valid = false},
-            IsValidMetadataTestCase{
-                    .name = "valid_dab_component_name_short",
-                    .metadata = Metadata::make<Metadata::dabComponentNameShort>("name"),
-                    .valid = true},
-            IsValidMetadataTestCase{
-                    .name = "too_long_dab_component_name_short",
-                    .metadata = Metadata::make<Metadata::dabComponentNameShort>("name_long"),
-                    .valid = false},
-    });
-}
 }  // namespace
 
 class GetBandTest : public testing::TestWithParam<GetBandTestCase> {};
@@ -305,48 +81,6 @@
     ASSERT_EQ(utils::getBand(testcase.frequency), testcase.bandResult);
 }
 
-class IsValidMetadataTest : public testing::TestWithParam<IsValidMetadataTestCase> {};
-
-INSTANTIATE_TEST_SUITE_P(IsValidMetadataTests, IsValidMetadataTest,
-                         testing::ValuesIn(getIsValidMetadataTestCases()),
-                         [](const testing::TestParamInfo<IsValidMetadataTest::ParamType>& info) {
-                             return info.param.name;
-                         });
-
-TEST_P(IsValidMetadataTest, IsValidMetadata) {
-    IsValidMetadataTestCase testParam = GetParam();
-
-    ASSERT_EQ(utils::isValidMetadata(testParam.metadata), testParam.valid);
-}
-
-class IsValidIdentifierTest : public testing::TestWithParam<IsValidIdentifierTestCase> {};
-
-INSTANTIATE_TEST_SUITE_P(IsValidIdentifierTests, IsValidIdentifierTest,
-                         testing::ValuesIn(getIsValidIdentifierTestCases()),
-                         [](const testing::TestParamInfo<IsValidIdentifierTest::ParamType>& info) {
-                             return info.param.name;
-                         });
-
-TEST_P(IsValidIdentifierTest, IsValid) {
-    IsValidIdentifierTestCase testcase = GetParam();
-
-    ASSERT_EQ(utils::isValid(testcase.id), testcase.valid);
-}
-
-class IsValidSelectorTest : public testing::TestWithParam<IsValidSelectorTestCase> {};
-
-INSTANTIATE_TEST_SUITE_P(IsValidSelectorTests, IsValidSelectorTest,
-                         testing::ValuesIn(getIsValidSelectorTestCases()),
-                         [](const testing::TestParamInfo<IsValidSelectorTest::ParamType>& info) {
-                             return info.param.name;
-                         });
-
-TEST_P(IsValidSelectorTest, IsValid) {
-    IsValidSelectorTestCase testcase = GetParam();
-
-    ASSERT_EQ(utils::isValid(testcase.sel), testcase.valid);
-}
-
 TEST(BroadcastRadioUtilsTest, IdentifierIteratorBegin) {
     ProgramSelector sel = {
             .primaryId = utils::makeIdentifier(IdentifierType::RDS_PI, kRdsValue),
@@ -503,13 +237,22 @@
     sel.secondaryIds.push_back(
             utils::makeIdentifier(IdentifierType::AMFM_FREQUENCY_KHZ, secondaryFrequencyKHz));
 
-    std::vector<int> allIds = utils::getAllIds(sel, IdentifierType::AMFM_FREQUENCY_KHZ);
+    std::vector<int64_t> allIds = utils::getAllIds(sel, IdentifierType::AMFM_FREQUENCY_KHZ);
 
     ASSERT_EQ(allIds.size(), 2u);
     EXPECT_NE(std::find(allIds.begin(), allIds.end(), kFmFrequencyKHz), allIds.end());
     EXPECT_NE(std::find(allIds.begin(), allIds.end(), secondaryFrequencyKHz), allIds.end());
 }
 
+TEST(BroadcastRadioUtilsTest, GetAllIdsWithIdLongerThan32Bit) {
+    ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
+
+    std::vector<int64_t> allIds = utils::getAllIds(sel, IdentifierType::DAB_SID_EXT);
+
+    ASSERT_EQ(allIds.size(), 1u);
+    EXPECT_NE(std::find(allIds.begin(), allIds.end(), kDabSidExt), allIds.end());
+}
+
 TEST(BroadcastRadioUtilsTest, GetAllIdsWithIdNotFound) {
     ProgramSelector sel = utils::makeSelectorDab(kDabSidExt, kDabEnsemble, kDabFrequencyKhz);
 
diff --git a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp b/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp
deleted file mode 100644
index cf9f9e9..0000000
--- a/broadcastradio/common/utilsaidl/test/BroadcastRadioUtilsV2Test.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <broadcastradio-utils-aidl/UtilsV2.h>
-#include <gtest/gtest.h>
-
-namespace aidl::android::hardware::broadcastradio {
-
-namespace {
-struct IsValidMetadataV2TestCase {
-    std::string name;
-    Metadata metadata;
-    bool valid;
-};
-
-std::vector<IsValidMetadataV2TestCase> getIsValidMetadataV2TestCases() {
-    return std::vector<IsValidMetadataV2TestCase>({
-            IsValidMetadataV2TestCase{.name = "valid_rds_pty",
-                                      .metadata = Metadata::make<Metadata::rdsPty>(1),
-                                      .valid = true},
-            IsValidMetadataV2TestCase{.name = "negative_rds_pty",
-                                      .metadata = Metadata::make<Metadata::rdsPty>(-1),
-                                      .valid = false},
-            IsValidMetadataV2TestCase{
-                    .name = "valid_hd_station_name_short",
-                    .metadata = Metadata::make<Metadata::hdStationNameShort>("name_short"),
-                    .valid = true},
-            IsValidMetadataV2TestCase{
-                    .name = "too_long_hd_station_name_short",
-                    .metadata = Metadata::make<Metadata::hdStationNameShort>("name_too_long"),
-                    .valid = false},
-            IsValidMetadataV2TestCase{
-                    .name = "valid_hd_subchannel_available",
-                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(1),
-                    .valid = true},
-            IsValidMetadataV2TestCase{
-                    .name = "negative_subchannel_available",
-                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(-1),
-                    .valid = false},
-            IsValidMetadataV2TestCase{
-                    .name = "large_subchannel_available",
-                    .metadata = Metadata::make<Metadata::hdSubChannelsAvailable>(256),
-                    .valid = false},
-    });
-}
-}  // namespace
-
-class IsValidMetadataV2Test : public testing::TestWithParam<IsValidMetadataV2TestCase> {};
-
-INSTANTIATE_TEST_SUITE_P(IsValidMetadataV2Tests, IsValidMetadataV2Test,
-                         testing::ValuesIn(getIsValidMetadataV2TestCases()),
-                         [](const testing::TestParamInfo<IsValidMetadataV2Test::ParamType>& info) {
-                             return info.param.name;
-                         });
-
-TEST_P(IsValidMetadataV2Test, IsValidMetadataV2) {
-    IsValidMetadataV2TestCase testParam = GetParam();
-
-    ASSERT_EQ(utils::isValidMetadataV2(testParam.metadata), testParam.valid);
-}
-
-}  // namespace aidl::android::hardware::broadcastradio
diff --git a/camera/device/3.4/default/ExternalCameraUtils.cpp b/camera/device/3.4/default/ExternalCameraUtils.cpp
index 8f4626c..d9610c2 100644
--- a/camera/device/3.4/default/ExternalCameraUtils.cpp
+++ b/camera/device/3.4/default/ExternalCameraUtils.cpp
@@ -108,9 +108,38 @@
         return -EINVAL;
     }
 
-    uint32_t dataSize = mWidth * mHeight * 3 / 2; // YUV420
-    if (mData.size() != dataSize) {
-        mData.resize(dataSize);
+    // This frame might be sent to jpeglib to be encoded. Since AllocatedFrame only contains YUV420,
+    // jpeglib expects height and width of Y component to be an integral multiple of 2*DCTSIZE,
+    // and heights and widths of Cb and Cr components to be an integral multiple of DCTSIZE. If the
+    // image size does not meet this requirement, libjpeg expects its input to be padded to meet the
+    // constraints. This padding is removed from the final encoded image so the content in the
+    // padding doesn't matter. What matters is that the memory is accessible to jpeglib at the time
+    // of encoding.
+    // For example, if the image size is 1500x844 and DCTSIZE is 8, jpeglib expects a YUV 420
+    // frame with components of following sizes:
+    //   Y:      1504x848 because 1504 and 848 are the next smallest multiples of 2*8
+    //   Cb/Cr:  752x424 which are the next smallest multiples of 8
+
+    // jpeglib takes an array of row pointers which makes vertical padding trivial when setting up
+    // the pointers. Padding horizontally is a bit more complicated. AllocatedFrame holds the data
+    // in a flattened buffer, which means memory accesses past a row will flow into the next logical
+    // row. For any row of a component, we can consider the first few bytes of the next row as
+    // padding for the current one. This is true for Y and Cb components and all but last row of the
+    // Cr component. Reading past the last row of Cr component will lead to undefined behavior as
+    // libjpeg attempts to read memory past the allocated buffer. To prevent undefined behavior,
+    // the buffer allocated here is padded such that libjpeg never accesses unallocated memory when
+    // reading the last row. Effectively, we only need to ensure that the last row of Cr component
+    // has width that is an integral multiple of DCTSIZE.
+
+    size_t dataSize = mWidth * mHeight * 3 / 2;  // YUV420
+
+    size_t cbWidth = mWidth / 2;
+    size_t requiredCbWidth = DCTSIZE * ((cbWidth + DCTSIZE - 1) / DCTSIZE);
+    size_t padding = requiredCbWidth - cbWidth;
+    size_t finalSize = dataSize + padding;
+
+    if (mData.size() != finalSize) {
+        mData.resize(finalSize);
     }
 
     if (out != nullptr) {
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index 440c2b3..5da515b 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -372,66 +372,13 @@
      * the particular StreamConfiguration is supported, the camera HAL must take all
      * the keys in sessionParameters into consideration.
      *
-     * 2. For version 3 of this interface, the camera compliance test will verify that
+     * 2. For version 3 of this interface, the camera compliance tests will verify that
      * isStreamCombinationWithSettingsSupported behaves properly for all combinations of
-     * below features. This function must return true for all supported combinations,
-     * and return false for non-supported feature combinations. The list of features
-     * required may grow in future versions. The additional metadata entries in
-     * StreamConfiguration::sessionParameters are {CONTROL_AE_TARGET_FPS_RANGE,
-     * CONTROL_VIDEO_STABILIZATION_MODE}.
-     *
-     * - Stream Combinations (a subset of LEGACY device mandatory stream combinations):
-     *   {
-     *     //                    4:3                16:9
-     *     // S1440P:         1920 x 1440         2560 x 1440
-     *     // S1080P:         1440 x 1080         1920 x 1080
-     *     // S720P:           960 x 720          1280 x 720
-     *
-     *     // Simple preview, GPU video processing, or no-preview video recording
-     *     {PRIV, MAXIMUM},
-     *     {PRIV, PREVIEW},
-     *     {PRIV, S1440P},
-     *     {PRIV, S1080P},
-     *     {PRIV, S720P},
-     *     // In-application video/image processing
-     *     {YUV, MAXIMUM},
-     *     {YUV, PREVIEW},
-     *     {YUV, S1440P},
-     *     {YUV, S1080P},
-     *     {YUV, S720P},
-     *     // Standard still imaging.
-     *     {PRIV, PREVIEW, JPEG, MAXIMUM},
-     *     {PRIV, S1440P,  JPEG, MAXIMUM},
-     *     {PRIV, S1080P,  JPEG, MAXIMUM},
-     *     {PRIV, S720P,   JPEG, MAXIMUM},
-     *     {PRIV, S1440P,  JPEG, S1440P},
-     *     {PRIV, S1080P,  JPEG, S1080P},
-     *     {PRIV, S720P,   JPEG, S1080P},
-     *     // In-app processing plus still capture.
-     *     {YUV,  PREVIEW, JPEG, MAXIMUM},
-     *     {YUV,  S1440P,  JPEG, MAXIMUM},
-     *     {YUV,  S1080P,  JPEG, MAXIMUM},
-     *     {YUV,  S720P,   JPEG, MAXIMUM},
-     *     // Standard recording.
-     *     {PRIV, PREVIEW, PRIV, PREVIEW},
-     *     {PRIV, S1440P,  PRIV, S1440P},
-     *     {PRIV, S1080P,  PRIV, S1080P},
-     *     {PRIV, S720P,   PRIV, S720P},
-     *     // Preview plus in-app processing.
-     *     {PRIV, PREVIEW, YUV,  PREVIEW},
-     *     {PRIV, S1440P,  YUV,  S1440P},
-     *     {PRIV, S1080P,  YUV,  S1080P},
-     *     {PRIV, S720P,   YUV,  S720P},
-     *   }
-     * - VIDEO_STABILIZATION_MODES: {OFF, PREVIEW}
-     * - AE_TARGET_FPS_RANGE: {{*, 30}, {*, 60}}
-     * - DYNAMIC_RANGE_PROFILE: {STANDARD, HLG10}
-     *
-     * Note: If a combination contains a S1440P, S1080P, or S720P stream,
-     * both 4:3 and 16:9 aspect ratio will be considered. For example, for the
-     * stream combination of {PRIV, S1440P, JPEG, MAXIMUM}, and if MAXIMUM ==
-     * 4032 x 3024, the camera compliance test will verify both
-     * {PRIV, 1920 x 1440, JPEG, 4032 x 3024} and {PRIV, 2560 x 1440, JPEG, 4032 x 2268}.
+     * features described in the android.info.sessionConfigurationQueryVersion section of
+     * /system/media/camera/docs/docs.html. This function must
+     * return true for all supported combinations, and return false for non-supported
+     * feature combinations. The list of feature combinations required may grow in future
+     * HAL versions.
      *
      * @param streams The StreamConfiguration to be tested, with optional CaptureRequest parameters.
      *
diff --git a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
index f133372..236bcaf 100644
--- a/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
+++ b/camera/metadata/aidl/android/hardware/camera/metadata/CameraMetadataTag.aidl
@@ -580,25 +580,25 @@
     /**
      * android.flash.singleStrengthMaxLevel [static, int32, public]
      *
-     * <p>Maximum flash brightness level for manual flash control in SINGLE mode.</p>
+     * <p>Maximum flash brightness level for manual flash control in <code>SINGLE</code> mode.</p>
      */
     ANDROID_FLASH_SINGLE_STRENGTH_MAX_LEVEL,
     /**
      * android.flash.singleStrengthDefaultLevel [static, int32, public]
      *
-     * <p>Default flash brightness level for manual flash control in SINGLE mode.</p>
+     * <p>Default flash brightness level for manual flash control in <code>SINGLE</code> mode.</p>
      */
     ANDROID_FLASH_SINGLE_STRENGTH_DEFAULT_LEVEL,
     /**
      * android.flash.torchStrengthMaxLevel [static, int32, public]
      *
-     * <p>Maximum flash brightness level for manual flash control in TORCH mode</p>
+     * <p>Maximum flash brightness level for manual flash control in <code>TORCH</code> mode</p>
      */
     ANDROID_FLASH_TORCH_STRENGTH_MAX_LEVEL,
     /**
      * android.flash.torchStrengthDefaultLevel [static, int32, public]
      *
-     * <p>Default flash brightness level for manual flash control in TORCH mode</p>
+     * <p>Default flash brightness level for manual flash control in <code>TORCH</code> mode</p>
      */
     ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL,
     /**
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index c8e683c..82666ae 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -8140,7 +8140,7 @@
             ANDROID_LENS_POSE_REFERENCE, &entry);
     if (0 == retcode && entry.count > 0) {
         uint8_t poseReference = entry.data.u8[0];
-        ASSERT_TRUE(poseReference <= ANDROID_LENS_POSE_REFERENCE_UNDEFINED &&
+        ASSERT_TRUE(poseReference <= ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE &&
                 poseReference >= ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA);
     }
 
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index 90ec32c..ad8d4c8 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -178,6 +178,9 @@
             const camera_metadata_t* staticMeta =
                     reinterpret_cast<const camera_metadata_t*>(meta.metadata.data());
             verifyManualFlashStrengthControlCharacteristics(staticMeta);
+            ret = mSession->close();
+            mSession = nullptr;
+            ASSERT_TRUE(ret.isOk());
         }
     } else {
         ALOGI("validateManualFlashStrengthControlKeys: Test skipped.\n");
@@ -297,6 +300,15 @@
             ASSERT_TRUE(ret.isOk());
             ASSERT_NE(device, nullptr);
 
+            int32_t interfaceVersion = -1;
+            ret = device->getInterfaceVersion(&interfaceVersion);
+            ASSERT_TRUE(ret.isOk());
+            bool supportSessionCharacteristics =
+                    (interfaceVersion >= CAMERA_DEVICE_API_MINOR_VERSION_3);
+            if (!supportSessionCharacteristics) {
+                continue;
+            }
+
             CameraMetadata meta;
             openEmptyDeviceSession(name, mProvider, &mSession /*out*/, &meta /*out*/,
                                    &device /*out*/);
@@ -339,6 +351,10 @@
             ret = device->getSessionCharacteristics(config, &session_chars);
             ASSERT_TRUE(ret.isOk());
             verifySessionCharacteristics(session_chars, camera_chars);
+
+            ret = mSession->close();
+            mSession = nullptr;
+            ASSERT_TRUE(ret.isOk());
         }
     } else {
         ALOGI("getSessionCharacteristics: Test skipped.\n");
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index 1673ab0..1ad5af9 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -695,8 +695,8 @@
     retcode = find_camera_metadata_ro_entry(metadata, ANDROID_LENS_POSE_REFERENCE, &entry);
     if (0 == retcode && entry.count > 0) {
         uint8_t poseReference = entry.data.u8[0];
-        ASSERT_TRUE(poseReference <= ANDROID_LENS_POSE_REFERENCE_UNDEFINED &&
-                    poseReference >= ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA);
+        ASSERT_TRUE(poseReference <= ANDROID_LENS_POSE_REFERENCE_AUTOMOTIVE &&
+                poseReference >= ANDROID_LENS_POSE_REFERENCE_PRIMARY_CAMERA);
     }
 
     retcode =
@@ -1205,18 +1205,21 @@
     int torchDefRetCode = find_camera_metadata_ro_entry(staticMeta,
             ANDROID_FLASH_TORCH_STRENGTH_DEFAULT_LEVEL, &torchDefEntry);
     if (torch_supported) {
+        int expectedEntryCount;
         if(singleMaxRetCode == 0 && singleDefRetCode == 0 && torchMaxRetCode == 0 &&
                 torchDefRetCode == 0) {
             singleMaxLevel = *singleMaxEntry.data.i32;
             singleDefLevel = *singleDefEntry.data.i32;
             torchMaxLevel = *torchMaxEntry.data.i32;
             torchDefLevel = *torchDefEntry.data.i32;
-            ASSERT_TRUE((singleMaxEntry.count == singleDefEntry.count == torchMaxEntry.count
-                    == torchDefEntry.count == 1));
+            expectedEntryCount = 1;
         } else {
-            ASSERT_TRUE((singleMaxEntry.count == singleDefEntry.count == torchMaxEntry.count
-                    == torchDefEntry.count == 0));
+            expectedEntryCount = 0;
         }
+        ASSERT_EQ(singleMaxEntry.count, expectedEntryCount);
+        ASSERT_EQ(singleDefEntry.count, expectedEntryCount);
+        ASSERT_EQ(torchMaxEntry.count, expectedEntryCount);
+        ASSERT_EQ(torchDefEntry.count, expectedEntryCount);
         // if the device supports this feature default levels should be greater than 0
         if (singleMaxLevel > 1) {
             ASSERT_GT(torchMaxLevel, 1);
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 3fd762a..ee62163 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -84,7 +84,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.automotive.vehicle</name>
-        <version>1-3</version>
+        <version>1-4</version>
         <interface>
             <name>IVehicle</name>
             <instance>default</instance>
@@ -116,7 +116,7 @@
     </hal>
     <hal format="aidl" updatable-via-apex="true">
         <name>android.hardware.biometrics.fingerprint</name>
-        <version>3-4</version>
+        <version>3-5</version>
         <interface>
             <name>IFingerprint</name>
             <instance>default</instance>
@@ -529,6 +529,7 @@
             <name>ISharedSecret</name>
             <instance>default</instance>
             <instance>strongbox</instance>
+            <regex-instance>.*</regex-instance>
         </interface>
     </hal>
     <hal format="aidl">
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index c31f991..94d4d00 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -162,12 +162,13 @@
     return ScopedAStatus::ok();
 }
 
-void Gnss::reportLocation(const GnssLocation& location) const {
+void Gnss::reportLocation(const GnssLocation& location) {
     std::unique_lock<std::mutex> lock(mMutex);
     if (sGnssCallback == nullptr) {
         ALOGE("%s: GnssCallback is null.", __func__);
         return;
     }
+    mLastLocation = std::make_shared<GnssLocation>(location);
     auto status = sGnssCallback->gnssLocationCb(location);
     if (!status.isOk()) {
         ALOGE("%s: Unable to invoke gnssLocationCb", __func__);
@@ -359,7 +360,6 @@
 
 ndk::ScopedAStatus Gnss::getExtensionGnssDebug(std::shared_ptr<IGnssDebug>* iGnssDebug) {
     ALOGD("Gnss::getExtensionGnssDebug");
-
     *iGnssDebug = SharedRefBase::make<GnssDebug>();
     return ndk::ScopedAStatus::ok();
 }
@@ -398,4 +398,8 @@
     mGnssMeasurementIntervalMs = intervalMs;
 }
 
+std::shared_ptr<GnssLocation> Gnss::getLastLocation() const {
+    return mLastLocation;
+}
+
 }  // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 245d607..73085ef 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -87,18 +87,19 @@
     void reportSvStatus() const;
     void setGnssMeasurementEnabled(const bool enabled);
     void setGnssMeasurementInterval(const long intervalMs);
+    std::shared_ptr<GnssLocation> getLastLocation() const;
     std::shared_ptr<GnssConfiguration> mGnssConfiguration;
     std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
     std::shared_ptr<GnssMeasurementInterface> mGnssMeasurementInterface;
 
   private:
-    void reportLocation(const GnssLocation&) const;
+    void reportLocation(const GnssLocation&);
     void reportSvStatus(const std::vector<IGnssCallback::GnssSvInfo>& svInfoList) const;
+    void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const;
+    void reportNmea() const;
     std::vector<IGnssCallback::GnssSvInfo> filterBlocklistedSatellites(
             std::vector<IGnssCallback::GnssSvInfo> gnssSvInfoList) const;
-    void reportGnssStatusValue(const IGnssCallback::GnssStatusValue gnssStatusValue) const;
     std::unique_ptr<GnssLocation> getLocationFromHW();
-    void reportNmea() const;
 
     static std::shared_ptr<IGnssCallback> sGnssCallback;
 
@@ -109,6 +110,7 @@
     std::atomic<bool> mIsNmeaActive;
     std::atomic<bool> mFirstFixReceived;
     std::atomic<bool> mGnssMeasurementEnabled;
+    std::shared_ptr<GnssLocation> mLastLocation;
     std::thread mThread;
     ::android::hardware::gnss::common::ThreadBlocker mThreadBlocker;
 
diff --git a/gnss/aidl/default/GnssDebug.cpp b/gnss/aidl/default/GnssDebug.cpp
index f40c0bc..5ae6edd 100644
--- a/gnss/aidl/default/GnssDebug.cpp
+++ b/gnss/aidl/default/GnssDebug.cpp
@@ -18,10 +18,15 @@
 
 #include "GnssDebug.h"
 #include <log/log.h>
+#include <utils/SystemClock.h>
+#include "Constants.h"
+#include "Gnss.h"
 #include "MockLocation.h"
 
 namespace aidl::android::hardware::gnss {
 
+using ::android::hardware::gnss::common::kMockTimestamp;
+
 ndk::ScopedAStatus GnssDebug::getDebugData(DebugData* debugData) {
     ALOGD("GnssDebug::getDebugData");
 
@@ -36,10 +41,94 @@
                                    .speedAccuracyMetersPerSecond = 1,
                                    .bearingAccuracyDegrees = 90,
                                    .ageSeconds = 0.99};
-    TimeDebug timeDebug = {.timeEstimateMs = 1519930775453L,
+    TimeDebug timeDebug = {.timeEstimateMs = static_cast<int64_t>(
+                                   kMockTimestamp + ::android::elapsedRealtimeNano() / 1e6),
                            .timeUncertaintyNs = 1000,
-                           .frequencyUncertaintyNsPerSec = 5.0e4};
-    std::vector<SatelliteData> satelliteDataArrayDebug = {};
+                           .frequencyUncertaintyNsPerSec = 800};
+    SatelliteData satelliteData1 = {
+            .svid = 3,
+            .constellation = GnssConstellationType::GPS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData2 = {
+            .svid = 5,
+            .constellation = GnssConstellationType::GPS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData3 = {
+            .svid = 17,
+            .constellation = GnssConstellationType::GPS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData4 = {
+            .svid = 26,
+            .constellation = GnssConstellationType::GPS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData5 = {
+            .svid = 5,
+            .constellation = GnssConstellationType::GLONASS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData6 = {
+            .svid = 17,
+            .constellation = GnssConstellationType::GLONASS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData7 = {
+            .svid = 18,
+            .constellation = GnssConstellationType::GLONASS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData8 = {
+            .svid = 10,
+            .constellation = GnssConstellationType::GLONASS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    SatelliteData satelliteData9 = {
+            .svid = 3,
+            .constellation = GnssConstellationType::IRNSS,
+            .ephemerisType = SatelliteEphemerisType::EPHEMERIS,
+            .ephemerisSource = SatellitePvt::SatelliteEphemerisSource::SERVER_LONG_TERM,
+            .ephemerisHealth = SatelliteEphemerisHealth::GOOD,
+            .ephemerisAgeSeconds = 12,
+            .serverPredictionIsAvailable = true,
+            .serverPredictionAgeSeconds = 30};
+    std::vector<SatelliteData> satelliteDataArrayDebug = {
+            satelliteData1, satelliteData2, satelliteData3, satelliteData4, satelliteData5,
+            satelliteData6, satelliteData7, satelliteData8, satelliteData9};
     debugData->position = positionDebug;
     debugData->time = timeDebug;
     debugData->satelliteDataArray = satelliteDataArrayDebug;
diff --git a/gnss/aidl/default/GnssDebug.h b/gnss/aidl/default/GnssDebug.h
index 001d47c..b6844b3 100644
--- a/gnss/aidl/default/GnssDebug.h
+++ b/gnss/aidl/default/GnssDebug.h
@@ -20,6 +20,8 @@
 
 namespace aidl::android::hardware::gnss {
 
+class Gnss;
+
 struct GnssDebug : public BnGnssDebug {
   public:
     ndk::ScopedAStatus getDebugData(DebugData* debugData) override;
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp
index f324213..db1b8c6 100644
--- a/gnss/aidl/default/GnssMeasurementInterface.cpp
+++ b/gnss/aidl/default/GnssMeasurementInterface.cpp
@@ -146,15 +146,18 @@
     mIsActive = false;
     mGnss->setGnssMeasurementEnabled(false);
     mThreadBlocker.notify();
-    for (auto iter = mThreads.begin(); iter != mThreads.end(); ++iter) {
+    for (auto iter = mThreads.begin(); iter != mThreads.end();) {
         if (iter->joinable()) {
-            mFutures.push_back(std::async(std::launch::async, [this, iter] {
-                iter->join();
-                mThreads.erase(iter);
-            }));
-        } else {
-            mThreads.erase(iter);
+            // Store the thread object by value
+            std::thread threadToMove = std::move(*iter);
+
+            mFutures.push_back(std::async(std::launch::async,
+                                          [threadToMove = std::move(threadToMove)]() mutable {
+                                              ALOGD("joining thread");
+                                              threadToMove.join();
+                                          }));
         }
+        iter = mThreads.erase(iter);
     }
 }
 
diff --git a/gnss/aidl/default/GnssNavigationMessageInterface.cpp b/gnss/aidl/default/GnssNavigationMessageInterface.cpp
index c262dc6..eb1d655 100644
--- a/gnss/aidl/default/GnssNavigationMessageInterface.cpp
+++ b/gnss/aidl/default/GnssNavigationMessageInterface.cpp
@@ -90,15 +90,18 @@
     ALOGD("stop");
     mIsActive = false;
     mThreadBlocker.notify();
-    for (auto iter = mThreads.begin(); iter != mThreads.end(); ++iter) {
+    for (auto iter = mThreads.begin(); iter != mThreads.end();) {
         if (iter->joinable()) {
-            mFutures.push_back(std::async(std::launch::async, [this, iter] {
-                iter->join();
-                mThreads.erase(iter);
-            }));
-        } else {
-            mThreads.erase(iter);
+            // Store the thread object by value
+            std::thread threadToMove = std::move(*iter);
+
+            mFutures.push_back(std::async(std::launch::async,
+                                          [threadToMove = std::move(threadToMove)]() mutable {
+                                              ALOGD("joining thread");
+                                              threadToMove.join();
+                                          }));
         }
+        iter = mThreads.erase(iter);
     }
 }
 
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 9381a0a..f7408d8 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -1149,40 +1149,139 @@
     sp<IGnssDebug> iGnssDebug;
     auto status = aidl_gnss_hal_->getExtensionGnssDebug(&iGnssDebug);
     ASSERT_TRUE(status.isOk());
-
-    if (!IsAutomotiveDevice()) {
-        ASSERT_TRUE(iGnssDebug != nullptr);
-
-        IGnssDebug::DebugData data;
-        auto status = iGnssDebug->getDebugData(&data);
-        ASSERT_TRUE(status.isOk());
-
-        if (data.position.valid) {
-            ASSERT_TRUE(data.position.latitudeDegrees >= -90 &&
-                        data.position.latitudeDegrees <= 90);
-            ASSERT_TRUE(data.position.longitudeDegrees >= -180 &&
-                        data.position.longitudeDegrees <= 180);
-            ASSERT_TRUE(data.position.altitudeMeters >= -1000 &&  // Dead Sea: -414m
-                        data.position.altitudeMeters <= 20000);   // Mount Everest: 8850m
-            ASSERT_TRUE(data.position.speedMetersPerSec >= 0 &&
-                        data.position.speedMetersPerSec <= 600);
-            ASSERT_TRUE(data.position.bearingDegrees >= -360 &&
-                        data.position.bearingDegrees <= 360);
-            ASSERT_TRUE(data.position.horizontalAccuracyMeters > 0 &&
-                        data.position.horizontalAccuracyMeters <= 20000000);
-            ASSERT_TRUE(data.position.verticalAccuracyMeters > 0 &&
-                        data.position.verticalAccuracyMeters <= 20000);
-            ASSERT_TRUE(data.position.speedAccuracyMetersPerSecond > 0 &&
-                        data.position.speedAccuracyMetersPerSecond <= 500);
-            ASSERT_TRUE(data.position.bearingAccuracyDegrees > 0 &&
-                        data.position.bearingAccuracyDegrees <= 180);
-            ASSERT_TRUE(data.position.ageSeconds >= 0);
-        }
-        ASSERT_TRUE(data.time.timeEstimateMs >= 1483228800000);  // Jan 01 2017 00:00:00 GMT.
-        ASSERT_TRUE(data.time.timeUncertaintyNs > 0);
-        ASSERT_TRUE(data.time.frequencyUncertaintyNsPerSec > 0 &&
-                    data.time.frequencyUncertaintyNsPerSec <= 2.0e5);  // 200 ppm
+    if (IsAutomotiveDevice()) {
+        return;
     }
+    ASSERT_TRUE(iGnssDebug != nullptr);
+
+    IGnssDebug::DebugData data;
+    status = iGnssDebug->getDebugData(&data);
+    ASSERT_TRUE(status.isOk());
+    Utils::checkPositionDebug(data);
+
+    // Additional GnssDebug tests for AIDL version >= 4 (launched in Android 15(V)+)
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 3) {
+        return;
+    }
+
+    // Start location and check the consistency between SvStatus and DebugData
+    aidl_gnss_cb_->location_cbq_.reset();
+    aidl_gnss_cb_->sv_info_list_cbq_.reset();
+    StartAndCheckLocations(/* count= */ 2);
+    int location_called_count = aidl_gnss_cb_->location_cbq_.calledCount();
+    ALOGD("Observed %d GnssSvStatus, while awaiting 2 locations (%d received)",
+          aidl_gnss_cb_->sv_info_list_cbq_.size(), location_called_count);
+
+    // Wait for up to kNumSvInfoLists events for kTimeoutSeconds for each event.
+    int kTimeoutSeconds = 2;
+    int kNumSvInfoLists = 4;
+    std::list<std::vector<IGnssCallback::GnssSvInfo>> sv_info_lists;
+    std::vector<IGnssCallback::GnssSvInfo> last_sv_info_list;
+
+    do {
+        EXPECT_GT(aidl_gnss_cb_->sv_info_list_cbq_.retrieve(sv_info_lists, kNumSvInfoLists,
+                                                            kTimeoutSeconds),
+                  0);
+        if (!sv_info_lists.empty()) {
+            last_sv_info_list = sv_info_lists.back();
+            ALOGD("last_sv_info size = %d", (int)last_sv_info_list.size());
+        }
+    } while (!sv_info_lists.empty() && last_sv_info_list.size() == 0);
+
+    StopAndClearLocations();
+
+    status = iGnssDebug->getDebugData(&data);
+    Utils::checkPositionDebug(data);
+
+    // Validate SatelliteEphemerisType, SatelliteEphemerisSource, SatelliteEphemerisHealth
+    for (auto sv_info : last_sv_info_list) {
+        if ((sv_info.svFlag & static_cast<int>(IGnssCallback::GnssSvFlags::USED_IN_FIX)) == 0) {
+            continue;
+        }
+        ALOGD("Found usedInFix const: %d, svid: %d", static_cast<int>(sv_info.constellation),
+              sv_info.svid);
+        bool foundDebugData = false;
+        for (auto satelliteData : data.satelliteDataArray) {
+            if (satelliteData.constellation == sv_info.constellation &&
+                satelliteData.svid == sv_info.svid) {
+                foundDebugData = true;
+                ALOGD("Found GnssDebug data for this sv.");
+                EXPECT_TRUE(satelliteData.serverPredictionIsAvailable ||
+                            satelliteData.ephemerisType ==
+                                    IGnssDebug::SatelliteEphemerisType::EPHEMERIS);
+                // for satellites with ephType=0, they need ephHealth=0 if used-in-fix
+                if (satelliteData.ephemerisType == IGnssDebug::SatelliteEphemerisType::EPHEMERIS) {
+                    EXPECT_TRUE(satelliteData.ephemerisHealth ==
+                                IGnssDebug::SatelliteEphemerisHealth::GOOD);
+                }
+                break;
+            }
+        }
+        // Every Satellite where GnssStatus says it is used-in-fix has a valid ephemeris - i.e. it's
+        // it shows either a serverPredAvail: 1, or a ephType=0
+        EXPECT_TRUE(foundDebugData);
+    }
+
+    bool hasServerPredictionAvailable = false;
+    bool hasNoneZeroServerPredictionAgeSeconds = false;
+    bool hasNoneDemodEphSource = false;
+    for (auto satelliteData : data.satelliteDataArray) {
+        // for satellites with serverPredAvail: 1, the serverPredAgeSec: is not 0 for all
+        // satellites (at least not on 2 fixes in a row - it could get lucky once)
+        if (satelliteData.serverPredictionIsAvailable) {
+            hasServerPredictionAvailable = true;
+            if (satelliteData.serverPredictionAgeSeconds != 0) {
+                hasNoneZeroServerPredictionAgeSeconds = true;
+            }
+        }
+        // for satellites with ephType=0, they need ephSource 0-3
+        if (satelliteData.ephemerisType == IGnssDebug::SatelliteEphemerisType::EPHEMERIS) {
+            EXPECT_TRUE(satelliteData.ephemerisSource >=
+                                SatellitePvt::SatelliteEphemerisSource::DEMODULATED &&
+                        satelliteData.ephemerisSource <=
+                                SatellitePvt::SatelliteEphemerisSource::OTHER);
+            if (satelliteData.ephemerisSource !=
+                SatellitePvt::SatelliteEphemerisSource::DEMODULATED) {
+                hasNoneDemodEphSource = true;
+            }
+        }
+    }
+    if (hasNoneDemodEphSource && hasServerPredictionAvailable) {
+        EXPECT_TRUE(hasNoneZeroServerPredictionAgeSeconds);
+    }
+
+    /**
+    - Gnss Location Data:: should show some valid information, ideally reasonably close (+/-1km) to
+        the Location output - at least after the 2nd valid location output (maybe in general, wait
+        for 2 good Location outputs before checking this, in case they don't update the assistance
+        until after they output the Location)
+    */
+    double distanceM =
+            Utils::distanceMeters(data.position.latitudeDegrees, data.position.longitudeDegrees,
+                                  aidl_gnss_cb_->last_location_.latitudeDegrees,
+                                  aidl_gnss_cb_->last_location_.longitudeDegrees);
+    ALOGD("distance between debug position and last position: %.2lf", distanceM);
+    EXPECT_LT(distanceM, 1000.0);  // 1km
+
+    /**
+    - Gnss Time Data:: timeEstimate should be reasonably close to the current GPS time.
+    - Gnss Time Data:: timeUncertaintyNs should always be > 0 and < 5e9 (could be large due
+        to solve-for-time type solutions)
+    - Gnss Time Data:: frequencyUncertaintyNsPerSec: should always be > 0 and < 1000 (1000 ns/s
+        corresponds to roughly a 300 m/s speed error, which should be pretty rare)
+    */
+    ALOGD("debug time: %" PRId64 ", position time: %" PRId64, data.time.timeEstimateMs,
+          aidl_gnss_cb_->last_location_.timestampMillis);
+    // Allowing 5s between the last location time and the current GPS time
+    EXPECT_LT(abs(data.time.timeEstimateMs - aidl_gnss_cb_->last_location_.timestampMillis), 5000);
+
+    ALOGD("debug time uncertainty: %f ns", data.time.timeUncertaintyNs);
+    EXPECT_GT(data.time.timeUncertaintyNs, 0);
+    EXPECT_LT(data.time.timeUncertaintyNs, 5e9);
+
+    ALOGD("debug freq uncertainty: %f ns/s", data.time.frequencyUncertaintyNsPerSec);
+    EXPECT_GT(data.time.frequencyUncertaintyNsPerSec, 0);
+    EXPECT_LT(data.time.frequencyUncertaintyNsPerSec, 1000);
 }
 
 /*
@@ -1714,7 +1813,8 @@
  * 2. verify the SvStatus are received at expected interval
  */
 TEST_P(GnssHalTest, TestSvStatusIntervals) {
-    if (aidl_gnss_hal_->getInterfaceVersion() <= 2) {
+    // Only runs on devices launched in Android 15+
+    if (aidl_gnss_hal_->getInterfaceVersion() <= 3) {
         return;
     }
     ALOGD("TestSvStatusIntervals");
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index 69e2b34..e3ff0f3 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -20,6 +20,7 @@
 #include "gtest/gtest.h"
 
 #include <cutils/properties.h>
+#include <math.h>
 #include <utils/SystemClock.h>
 
 namespace android {
@@ -58,6 +59,31 @@
     checkElapsedRealtime(location.elapsedRealtime);
 }
 
+void Utils::checkPositionDebug(android::hardware::gnss::IGnssDebug::DebugData data) {
+    if (data.position.valid) {
+        ASSERT_TRUE(data.position.latitudeDegrees >= -90 && data.position.latitudeDegrees <= 90);
+        ASSERT_TRUE(data.position.longitudeDegrees >= -180 &&
+                    data.position.longitudeDegrees <= 180);
+        ASSERT_TRUE(data.position.altitudeMeters >= -1000 &&  // Dead Sea: -414m
+                    data.position.altitudeMeters <= 20000);   // Mount Everest: 8850m
+        ASSERT_TRUE(data.position.speedMetersPerSec >= 0 && data.position.speedMetersPerSec <= 600);
+        ASSERT_TRUE(data.position.bearingDegrees >= -360 && data.position.bearingDegrees <= 360);
+        ASSERT_TRUE(data.position.horizontalAccuracyMeters > 0 &&
+                    data.position.horizontalAccuracyMeters <= 20000000);
+        ASSERT_TRUE(data.position.verticalAccuracyMeters > 0 &&
+                    data.position.verticalAccuracyMeters <= 20000);
+        ASSERT_TRUE(data.position.speedAccuracyMetersPerSecond > 0 &&
+                    data.position.speedAccuracyMetersPerSecond <= 500);
+        ASSERT_TRUE(data.position.bearingAccuracyDegrees > 0 &&
+                    data.position.bearingAccuracyDegrees <= 180);
+        ASSERT_TRUE(data.position.ageSeconds >= 0);
+    }
+    ASSERT_TRUE(data.time.timeEstimateMs >= 1483228800000);  // Jan 01 2017 00:00:00 GMT.
+    ASSERT_TRUE(data.time.timeUncertaintyNs > 0);
+    ASSERT_TRUE(data.time.frequencyUncertaintyNsPerSec > 0 &&
+                data.time.frequencyUncertaintyNsPerSec <= 2.0e5);  // 200 ppm
+}
+
 void Utils::checkElapsedRealtime(const ElapsedRealtime& elapsedRealtime) {
     ASSERT_TRUE(elapsedRealtime.flags >= 0 &&
                 elapsedRealtime.flags <= (ElapsedRealtime::HAS_TIMESTAMP_NS |
@@ -282,6 +308,17 @@
     return strncmp(buffer, "automotive", PROPERTY_VALUE_MAX) == 0;
 }
 
+double Utils::distanceMeters(double lat1, double lon1, double lat2, double lon2) {
+    double R = 6378.137;  // Radius of earth in KM
+    double dLat = lat2 * M_PI / 180 - lat1 * M_PI / 180;
+    double dLon = lon2 * M_PI / 180 - lon1 * M_PI / 180;
+    double a = sin(dLat / 2) * sin(dLat / 2) +
+               cos(lat1 * M_PI / 180) * cos(lat2 * M_PI / 180) * sin(dLon / 2) * sin(dLon / 2);
+    double c = 2 * atan2(sqrt(a), sqrt(1 - a));
+    double d = R * c;
+    return d * 1000;  // meters
+}
+
 }  // namespace common
 }  // namespace gnss
 }  // namespace hardware
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index 7b89078..62d409a 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -43,6 +43,7 @@
 
     static void checkElapsedRealtime(
             const android::hardware::gnss::ElapsedRealtime& elapsedRealtime);
+    static void checkPositionDebug(android::hardware::gnss::IGnssDebug::DebugData data);
 
     static const android::hardware::gnss::GnssLocation getMockLocation(
             double latitudeDegrees, double longitudeDegrees, double horizontalAccuracyMeters);
@@ -57,6 +58,7 @@
             V2_0::GnssConstellationType constellation);
 
     static bool isAutomotiveDevice();
+    static double distanceMeters(double lat1, double lon1, double lat2, double lon2);
 
   private:
     template <class T>
diff --git a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
index 2985212..1117504 100644
--- a/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
+++ b/graphics/common/aidl/android/hardware/graphics/common/PixelFormat.aidl
@@ -161,8 +161,7 @@
      *
      * The allocator should examine the usage bits passed in when allocating a
      * buffer with this format, and it should derive the pixel format from
-     * those usage flags. This format must never be used with any of the
-     * BufferUsage::CPU_* usage flags.
+     * those usage flags.
      *
      * Even when the internally chosen format has an alpha component, the
      * clients must assume the alpha vlaue to be 1.0.
diff --git a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
index 336d15d..6a45987 100644
--- a/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
+++ b/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h
@@ -33,6 +33,7 @@
 #include <string.h>
 
 #include <android/hardware/graphics/composer/2.1/IComposer.h>
+#include <android/hardware/graphics/composer/2.1/IComposerClient.h>
 #include <fmq/MessageQueue.h>
 #include <log/log.h>
 #include <sync/sync.h>
@@ -649,7 +650,8 @@
         *outLength = static_cast<uint16_t>(val & length_mask);
 
         if (mDataRead + *outLength > mDataSize) {
-            ALOGE("command 0x%x has invalid command length %" PRIu16, *outCommand, *outLength);
+            ALOGE("command %s has invalid command length %" PRIu16,
+                  toString(*outCommand).c_str(), *outLength);
             // undo the read() above
             mDataRead--;
             return false;
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl
index 106fd87..99c91aa 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/CommandResultPayload.aidl
@@ -28,6 +28,10 @@
 union CommandResultPayload {
     /**
      * Indicates an error generated by a command.
+     *
+     * If there is an error from a command, the composer should only respond
+     * with the CommandError, and not with other results
+     * (e.g. ChangedCompositionTypes).
      */
     CommandError error;
 
diff --git a/graphics/composer/aidl/vts/VtsComposerClient.h b/graphics/composer/aidl/vts/VtsComposerClient.h
index fabc82a..da6116f 100644
--- a/graphics/composer/aidl/vts/VtsComposerClient.h
+++ b/graphics/composer/aidl/vts/VtsComposerClient.h
@@ -258,13 +258,13 @@
 
     struct DisplayConfig {
         DisplayConfig(int32_t vsyncPeriod_, int32_t configGroup_,
-                      std::optional<VrrConfig> vrrConfig_ = {})
+                      std::optional<VrrConfig> vrrConfigOpt_ = {})
             : vsyncPeriod(vsyncPeriod_),
               configGroup(configGroup_),
-              vrrConfig(std::move(vrrConfig_)) {}
+              vrrConfigOpt(std::move(vrrConfigOpt_)) {}
         int32_t vsyncPeriod;
         int32_t configGroup;
-        std::optional<VrrConfig> vrrConfig;
+        std::optional<VrrConfig> vrrConfigOpt;
     };
 
     void addDisplayConfig(int32_t config, DisplayConfig displayConfig) {
@@ -273,6 +273,35 @@
 
     DisplayConfig getDisplayConfig(int32_t config) { return mDisplayConfigs.find(config)->second; }
 
+    bool isRateSameBetweenConfigs(int config1, int config2) {
+        const auto displayConfig1 = getDisplayConfig(config1);
+        const auto displayConfig2 = getDisplayConfig(config2);
+        const auto vrrConfigOpt1 = displayConfig1.vrrConfigOpt;
+        const auto vrrConfigOpt2 = displayConfig2.vrrConfigOpt;
+
+        if (vrrConfigOpt1 && vrrConfigOpt2 &&
+            vrrConfigOpt1->minFrameIntervalNs == vrrConfigOpt2->minFrameIntervalNs) {
+            return true;
+        } else if (displayConfig1.vsyncPeriod == displayConfig2.vsyncPeriod) {
+            return true;
+        }
+        return false;
+    }
+
+    std::string printConfig(int config) {
+        const auto displayConfig = getDisplayConfig(config);
+        const auto vrrConfigOpt = displayConfig.vrrConfigOpt;
+        std::stringstream ss;
+        if (displayConfig.vrrConfigOpt) {
+            ss << "{Config " << config << ": vsyncPeriod " << displayConfig.vsyncPeriod
+                << ", minFrameIntervalNs " << vrrConfigOpt->minFrameIntervalNs << "}";
+        }
+        else {
+            ss << "{Config " << config << ": vsyncPeriod " << displayConfig.vsyncPeriod << "}";
+        }
+        return ss.str();
+    }
+
     std::unordered_map<int32_t, DisplayConfig> getDisplayConfigs() { return mDisplayConfigs; }
 
   private:
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index d4ce3ba..3d9253f 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -59,10 +59,12 @@
 
         EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
 
+        const auto format = getHasReadbackBuffer() ? mPixelFormat : common::PixelFormat::RGBA_8888;
+
         ASSERT_NO_FATAL_FAILURE(
                 mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine(
                         ::android::renderengine::RenderEngineCreationArgs::Builder()
-                                .setPixelFormat(static_cast<int>(common::PixelFormat::RGBA_8888))
+                                .setPixelFormat(static_cast<int>(format))
                                 .setImageCacheSize(TestRenderEngine::sMaxFrameBufferAcquireBuffers)
                                 .setEnableProtectedContext(false)
                                 .setPrecacheToneMapperShaderOnly(false)
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
index f72cf55..ba15421 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -1603,18 +1603,24 @@
                 EXPECT_TRUE(mComposerClient->setActiveConfig(&display, config1).isOk());
                 sendRefreshFrame(display, nullptr);
 
-                const auto displayConfigGroup1 = display.getDisplayConfig(config1);
-                int32_t vsyncPeriod1 = displayConfigGroup1.vsyncPeriod;
-                int32_t configGroup1 = displayConfigGroup1.configGroup;
+                const auto displayConfig1 = display.getDisplayConfig(config1);
+                int32_t vsyncPeriod1 = displayConfig1.vsyncPeriod;
+                int32_t configGroup1 = displayConfig1.configGroup;
 
-                const auto displayConfigGroup2 = display.getDisplayConfig(config2);
-                int32_t vsyncPeriod2 = displayConfigGroup2.vsyncPeriod;
-                int32_t configGroup2 = displayConfigGroup2.configGroup;
+                const auto displayConfig2 = display.getDisplayConfig(config2);
+                int32_t vsyncPeriod2 = displayConfig2.vsyncPeriod;
+                int32_t configGroup2 = displayConfig2.configGroup;
 
                 if (vsyncPeriod1 == vsyncPeriod2) {
                     return;  // continue
                 }
 
+                if ((!displayConfig1.vrrConfigOpt && displayConfig2.vrrConfigOpt) ||
+                    (displayConfig1.vrrConfigOpt && !displayConfig2.vrrConfigOpt)) {
+                    // switching between vrr to non-vrr modes
+                    return;  // continue
+                }
+
                 // We don't allow delayed change when changing config groups
                 if (params.delayForChange > 0 && configGroup1 != configGroup2) {
                     return;  // continue
@@ -2197,13 +2203,13 @@
 
 TEST_P(GraphicsComposerAidlCommandTest, DisplayDecoration) {
     for (VtsDisplay& display : mDisplays) {
-        auto& writer = getWriter(display.getDisplayId());
+        const auto displayId = display.getDisplayId();
+        auto& writer = getWriter(displayId);
         const auto [layerStatus, layer] =
-                mComposerClient->createLayer(display.getDisplayId(), kBufferSlotCount, &writer);
-        EXPECT_TRUE(layerStatus.isOk());
+                mComposerClient->createLayer(displayId, kBufferSlotCount, &writer);
+        ASSERT_TRUE(layerStatus.isOk());
 
-        const auto [error, support] =
-                mComposerClient->getDisplayDecorationSupport(display.getDisplayId());
+        const auto [error, support] = mComposerClient->getDisplayDecorationSupport(displayId);
 
         const auto format = (error.isOk() && support) ? support->format
                         : aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888;
@@ -2223,9 +2229,9 @@
 
         configureLayer(display, layer, Composition::DISPLAY_DECORATION, display.getFrameRect(),
                        display.getCrop());
-        writer.setLayerBuffer(display.getDisplayId(), layer, /*slot*/ 0, decorBuffer->handle,
+        writer.setLayerBuffer(displayId, layer, /*slot*/ 0, decorBuffer->handle,
                               /*acquireFence*/ -1);
-        writer.validateDisplay(display.getDisplayId(), ComposerClientWriter::kNoTimestamp,
+        writer.validateDisplay(displayId, ComposerClientWriter::kNoTimestamp,
                                VtsComposerClient::kNoFrameIntervalNs);
         execute();
         if (support) {
@@ -2235,6 +2241,7 @@
             ASSERT_EQ(1, errors.size());
             EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errors[0].errorCode);
         }
+        EXPECT_TRUE(mComposerClient->destroyLayer(displayId, layer, &writer).isOk());
     }
 }
 
@@ -2738,7 +2745,7 @@
         const auto displayFilter = [&](auto refreshRateChangedDebugData) {
             bool nonVrrRateMatching = true;
             if (std::optional<VrrConfig> vrrConfigOpt =
-                        display.getDisplayConfig(configId).vrrConfig;
+                        display.getDisplayConfig(configId).vrrConfigOpt;
                 getInterfaceVersion() >= 3 && !vrrConfigOpt) {
                 nonVrrRateMatching = refreshRateChangedDebugData.refreshPeriodNanos ==
                                      refreshRateChangedDebugData.vsyncPeriodNanos;
@@ -2836,10 +2843,7 @@
                             .isOk());
 
         forEachTwoConfigs(displayId, [&](int32_t config1, int32_t config2) {
-            const int32_t vsyncPeriod1 = display.getDisplayConfig(config1).vsyncPeriod;
-            const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
-
-            if (vsyncPeriod1 == vsyncPeriod2) {
+            if (display.isRateSameBetweenConfigs(config1, config2)) {
                 return;  // continue
             }
 
@@ -2854,6 +2858,7 @@
                 sendRefreshFrame(display, &timeline);
             }
 
+            const int32_t vsyncPeriod2 = display.getDisplayConfig(config2).vsyncPeriod;
             const auto callbackFilter = [displayId,
                                          vsyncPeriod2](auto refreshRateChangedDebugData) {
                 constexpr int kVsyncThreshold = 1000;
@@ -2872,8 +2877,9 @@
             } while (--retryCount > 0);
 
             if (retryCount == 0) {
-                GTEST_FAIL() << "failed to get a callback for the display " << displayId
-                             << " with config " << config2;
+                GTEST_FAIL() << "Failed to get a callback for Display " << displayId
+                             << " switching from " << display.printConfig(config1)
+                             << " to " << display.printConfig(config2);
             }
         });
 
@@ -3002,14 +3008,10 @@
         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);
+    const auto& [status, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(status.isOk());
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
 }
@@ -3019,15 +3021,13 @@
         GTEST_SKIP() << "LAYER_LIFECYCLE_BATCH_COMMAND not supported by the implementation";
         return;
     }
-
-    auto& writer = getWriter(getPrimaryDisplayId());
+    auto& writer = getWriter(getInvalidDisplayId());
     int64_t layer = 5;
     writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
                                              LayerLifecycleBatchCommandType::CREATE);
-    writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
-    writer.validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
-                           VtsComposerClient::kNoFrameIntervalNs);
+    writer.setNewBufferSlotCount(getInvalidDisplayId(), layer, 1);
     execute();
+
     const auto errors = mReader.takeErrors();
     ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
 }
@@ -3037,26 +3037,15 @@
         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);
+    const auto& [status, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
+    EXPECT_TRUE(status.isOk());
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
-    writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
-                                             LayerLifecycleBatchCommandType::DESTROY);
-    layer++;
-    writer.setLayerLifecycleBatchCommandType(getPrimaryDisplayId(), layer,
-                                             LayerLifecycleBatchCommandType::CREATE);
-    writer.setNewBufferSlotCount(getPrimaryDisplayId(), layer, 1);
-
+    EXPECT_TRUE(mComposerClient->destroyLayer(getPrimaryDisplayId(), layer, &writer).isOk());
     execute();
-    const auto errors = mReader.takeErrors();
-    ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
+    ASSERT_TRUE(mReader.takeErrors().empty());
 }
 
 TEST_P(GraphicsComposerAidlCommandV3Test, DestroyBatchedCommand_BadDisplay) {
@@ -3064,25 +3053,20 @@
         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);
+    const auto& [status, layer] =
+            mComposerClient->createLayer(getPrimaryDisplayId(), kBufferSlotCount, &writer);
 
+    EXPECT_TRUE(status.isOk());
     execute();
     ASSERT_TRUE(mReader.takeErrors().empty());
+
+    auto& invalid_writer = getWriter(getInvalidDisplayId());
+    invalid_writer.setLayerLifecycleBatchCommandType(getInvalidDisplayId(), layer,
+                                                     LayerLifecycleBatchCommandType::DESTROY);
+    execute();
+    const auto errors = mReader.takeErrors();
+    ASSERT_TRUE(errors.size() == 1 && errors[0].errorCode == IComposerClient::EX_BAD_DISPLAY);
 }
 
 TEST_P(GraphicsComposerAidlCommandV3Test, NoCreateDestroyBatchedCommandIncorrectLayer) {
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h
index 92ed1cd..9a7fe5e 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h
@@ -56,6 +56,8 @@
 // Thread safe class
 class DeathMonitor final {
   public:
+    explicit DeathMonitor(uintptr_t cookieKey) : kCookieKey(cookieKey) {}
+
     static void serviceDied(void* cookie);
     void serviceDied();
     // Precondition: `killable` must be non-null.
@@ -63,9 +65,18 @@
     // Precondition: `killable` must be non-null.
     void remove(IProtectedCallback* killable) const;
 
+    uintptr_t getCookieKey() const { return kCookieKey; }
+
+    ~DeathMonitor();
+    DeathMonitor(const DeathMonitor&) = delete;
+    DeathMonitor(DeathMonitor&&) noexcept = delete;
+    DeathMonitor& operator=(const DeathMonitor&) = delete;
+    DeathMonitor& operator=(DeathMonitor&&) noexcept = delete;
+
   private:
     mutable std::mutex mMutex;
     mutable std::vector<IProtectedCallback*> mObjects GUARDED_BY(mMutex);
+    const uintptr_t kCookieKey;
 };
 
 class DeathHandler final {
diff --git a/neuralnetworks/aidl/utils/src/ProtectCallback.cpp b/neuralnetworks/aidl/utils/src/ProtectCallback.cpp
index 54a673c..4a7ac08 100644
--- a/neuralnetworks/aidl/utils/src/ProtectCallback.cpp
+++ b/neuralnetworks/aidl/utils/src/ProtectCallback.cpp
@@ -25,6 +25,7 @@
 
 #include <algorithm>
 #include <functional>
+#include <map>
 #include <memory>
 #include <mutex>
 #include <vector>
@@ -33,6 +34,16 @@
 
 namespace aidl::android::hardware::neuralnetworks::utils {
 
+namespace {
+
+// Only dereference the cookie if it's valid (if it's in this set)
+// Only used with ndk
+std::mutex sCookiesMutex;
+uintptr_t sCookieKeyCounter GUARDED_BY(sCookiesMutex) = 0;
+std::map<uintptr_t, std::weak_ptr<DeathMonitor>> sCookies GUARDED_BY(sCookiesMutex);
+
+}  // namespace
+
 void DeathMonitor::serviceDied() {
     std::lock_guard guard(mMutex);
     std::for_each(mObjects.begin(), mObjects.end(),
@@ -40,8 +51,24 @@
 }
 
 void DeathMonitor::serviceDied(void* cookie) {
-    auto deathMonitor = static_cast<DeathMonitor*>(cookie);
-    deathMonitor->serviceDied();
+    std::shared_ptr<DeathMonitor> monitor;
+    {
+        std::lock_guard<std::mutex> guard(sCookiesMutex);
+        if (auto it = sCookies.find(reinterpret_cast<uintptr_t>(cookie)); it != sCookies.end()) {
+            monitor = it->second.lock();
+            sCookies.erase(it);
+        } else {
+            LOG(INFO)
+                    << "Service died, but cookie is no longer valid so there is nothing to notify.";
+            return;
+        }
+    }
+    if (monitor) {
+        LOG(INFO) << "Notifying DeathMonitor from serviceDied.";
+        monitor->serviceDied();
+    } else {
+        LOG(INFO) << "Tried to notify DeathMonitor from serviceDied but could not promote.";
+    }
 }
 
 void DeathMonitor::add(IProtectedCallback* killable) const {
@@ -57,12 +84,25 @@
     mObjects.erase(removedIter);
 }
 
+DeathMonitor::~DeathMonitor() {
+    // lock must be taken so object is not used in OnBinderDied"
+    std::lock_guard<std::mutex> guard(sCookiesMutex);
+    sCookies.erase(kCookieKey);
+}
+
 nn::GeneralResult<DeathHandler> DeathHandler::create(std::shared_ptr<ndk::ICInterface> object) {
     if (object == nullptr) {
         return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT)
                << "utils::DeathHandler::create must have non-null object";
     }
-    auto deathMonitor = std::make_shared<DeathMonitor>();
+
+    std::shared_ptr<DeathMonitor> deathMonitor;
+    {
+        std::lock_guard<std::mutex> guard(sCookiesMutex);
+        deathMonitor = std::make_shared<DeathMonitor>(sCookieKeyCounter++);
+        sCookies[deathMonitor->getCookieKey()] = deathMonitor;
+    }
+
     auto deathRecipient = ndk::ScopedAIBinder_DeathRecipient(
             AIBinder_DeathRecipient_new(DeathMonitor::serviceDied));
 
@@ -70,8 +110,9 @@
     // STATUS_INVALID_OPERATION. We ignore this case because we only use local binders in tests
     // where this is not an error.
     if (object->isRemote()) {
-        const auto ret = ndk::ScopedAStatus::fromStatus(AIBinder_linkToDeath(
-                object->asBinder().get(), deathRecipient.get(), deathMonitor.get()));
+        const auto ret = ndk::ScopedAStatus::fromStatus(
+                AIBinder_linkToDeath(object->asBinder().get(), deathRecipient.get(),
+                                     reinterpret_cast<void*>(deathMonitor->getCookieKey())));
         HANDLE_ASTATUS(ret) << "AIBinder_linkToDeath failed";
     }
 
@@ -91,8 +132,9 @@
 
 DeathHandler::~DeathHandler() {
     if (kObject != nullptr && kDeathRecipient.get() != nullptr && kDeathMonitor != nullptr) {
-        const auto ret = ndk::ScopedAStatus::fromStatus(AIBinder_unlinkToDeath(
-                kObject->asBinder().get(), kDeathRecipient.get(), kDeathMonitor.get()));
+        const auto ret = ndk::ScopedAStatus::fromStatus(
+                AIBinder_unlinkToDeath(kObject->asBinder().get(), kDeathRecipient.get(),
+                                       reinterpret_cast<void*>(kDeathMonitor->getCookieKey())));
         const auto maybeSuccess = handleTransportError(ret);
         if (!maybeSuccess.ok()) {
             LOG(ERROR) << maybeSuccess.error().message;
diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
index 73727b3..ffd3b8e 100644
--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
@@ -697,7 +697,8 @@
     const auto mockDevice = createMockDevice();
     const auto device = Device::create(kName, mockDevice, kVersion).value();
     const auto ret = [&device]() {
-        DeathMonitor::serviceDied(device->getDeathMonitor());
+        DeathMonitor::serviceDied(
+                reinterpret_cast<void*>(device->getDeathMonitor()->getCookieKey()));
         return ndk::ScopedAStatus::ok();
     };
     EXPECT_CALL(*mockDevice, prepareModel(_, _, _, _, _, _, _, _))
@@ -846,7 +847,8 @@
     const auto mockDevice = createMockDevice();
     const auto device = Device::create(kName, mockDevice, kVersion).value();
     const auto ret = [&device]() {
-        DeathMonitor::serviceDied(device->getDeathMonitor());
+        DeathMonitor::serviceDied(
+                reinterpret_cast<void*>(device->getDeathMonitor()->getCookieKey()));
         return ndk::ScopedAStatus::ok();
     };
     EXPECT_CALL(*mockDevice, prepareModelWithConfig(_, _, _))
@@ -970,7 +972,8 @@
     const auto mockDevice = createMockDevice();
     const auto device = Device::create(kName, mockDevice, kVersion).value();
     const auto ret = [&device]() {
-        DeathMonitor::serviceDied(device->getDeathMonitor());
+        DeathMonitor::serviceDied(
+                reinterpret_cast<void*>(device->getDeathMonitor()->getCookieKey()));
         return ndk::ScopedAStatus::ok();
     };
     EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _, _))
diff --git a/nfc/aidl/vts/functional/Android.bp b/nfc/aidl/vts/functional/Android.bp
index 0dab2d8..d0b684b 100644
--- a/nfc/aidl/vts/functional/Android.bp
+++ b/nfc/aidl/vts/functional/Android.bp
@@ -45,3 +45,48 @@
         "vts",
     ],
 }
+
+cc_test {
+    name: "VtsNfcBehaviorChangesTest",
+    defaults: [
+        "VtsHalTargetTestDefaults",
+        "use_libaidlvintf_gtest_helper_static",
+    ],
+    srcs: [
+        "VtsNfcBehaviorChangesTest.cpp",
+        "CondVar.cpp",
+    ],
+    include_dirs: [
+        "system/nfc/src/gki/common",
+        "system/nfc/src/gki/ulinux",
+        "system/nfc/src/include",
+        "system/nfc/src/nfa/include",
+        "system/nfc/src/nfc/include",
+        "system/nfc/utils/include",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbinder_ndk",
+        "libnativehelper",
+        "libstatssocket",
+    ],
+    static_libs: [
+        "android.hardware.nfc-V1-ndk",
+        "android.hardware.nfc@1.0",
+        "android.hardware.nfc@1.1",
+        "android.hardware.nfc@1.2",
+        "android_nfc_flags_aconfig_c_lib",
+        "libnfc-nci",
+        "libnfc-nci_flags",
+        "libnfcutils",
+        "libstatslog_nfc",
+        "server_configurable_flags",
+    ],
+    require_root: true,
+    test_options: {
+        vsr_min_shipping_api_level: 202404, // 2024Q2
+    },
+    test_suites: [
+        "vts",
+    ],
+}
diff --git a/nfc/aidl/vts/functional/CondVar.cpp b/nfc/aidl/vts/functional/CondVar.cpp
new file mode 100644
index 0000000..59e5b51
--- /dev/null
+++ b/nfc/aidl/vts/functional/CondVar.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *  Encapsulate a condition variable for thread synchronization.
+ */
+
+#include "CondVar.h"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <errno.h>
+#include <string.h>
+
+using android::base::StringPrintf;
+
+/*******************************************************************************
+**
+** Function:        CondVar
+**
+** Description:     Initialize member variables.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+CondVar::CondVar() {
+    pthread_condattr_t attr;
+    pthread_condattr_init(&attr);
+    pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+    memset(&mCondition, 0, sizeof(mCondition));
+    int const res = pthread_cond_init(&mCondition, &attr);
+    if (res) {
+        LOG(ERROR) << StringPrintf("CondVar::CondVar: fail init; error=0x%X", res);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:        ~CondVar
+**
+** Description:     Cleanup all resources.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+CondVar::~CondVar() {
+    int const res = pthread_cond_destroy(&mCondition);
+    if (res) {
+        LOG(ERROR) << StringPrintf("CondVar::~CondVar: fail destroy; error=0x%X", res);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:        wait
+**
+** Description:     Block the caller and wait for a condition.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void CondVar::wait(std::mutex& mutex) {
+    int const res = pthread_cond_wait(&mCondition, mutex.native_handle());
+    if (res) {
+        LOG(ERROR) << StringPrintf("CondVar::wait: fail wait; error=0x%X", res);
+    }
+}
+
+/*******************************************************************************
+**
+** Function:        wait
+**
+** Description:     Block the caller and wait for a condition.
+**                  millisec: Timeout in milliseconds.
+**
+** Returns:         True if wait is successful; false if timeout occurs.
+**
+*******************************************************************************/
+bool CondVar::wait(std::mutex& mutex, long millisec) {
+    bool retVal = false;
+    struct timespec absoluteTime;
+
+    if (clock_gettime(CLOCK_MONOTONIC, &absoluteTime) == -1) {
+        LOG(ERROR) << StringPrintf("CondVar::wait: fail get time; errno=0x%X", errno);
+    } else {
+        absoluteTime.tv_sec += millisec / 1000;
+        long ns = absoluteTime.tv_nsec + ((millisec % 1000) * 1000000);
+        if (ns > 1000000000) {
+            absoluteTime.tv_sec++;
+            absoluteTime.tv_nsec = ns - 1000000000;
+        } else
+            absoluteTime.tv_nsec = ns;
+    }
+
+    int waitResult = pthread_cond_timedwait(&mCondition, mutex.native_handle(), &absoluteTime);
+    if ((waitResult != 0) && (waitResult != ETIMEDOUT))
+        LOG(ERROR) << StringPrintf("CondVar::wait: fail timed wait; error=0x%X", waitResult);
+    retVal = (waitResult == 0);  // waited successfully
+    return retVal;
+}
+
+/*******************************************************************************
+**
+** Function:        notifyOne
+**
+** Description:     Unblock the waiting thread.
+**
+** Returns:         None.
+**
+*******************************************************************************/
+void CondVar::notifyOne() {
+    int const res = pthread_cond_signal(&mCondition);
+    if (res) {
+        LOG(ERROR) << StringPrintf("CondVar::notifyOne: fail signal; error=0x%X", res);
+    }
+}
diff --git a/nfc/aidl/vts/functional/CondVar.h b/nfc/aidl/vts/functional/CondVar.h
new file mode 100644
index 0000000..5e0dcf7
--- /dev/null
+++ b/nfc/aidl/vts/functional/CondVar.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *  Encapsulate a condition variable for thread synchronization.
+ */
+
+#pragma once
+#include <pthread.h>
+
+#include <mutex>
+
+class CondVar {
+  public:
+    /*******************************************************************************
+    **
+    ** Function:        CondVar
+    **
+    ** Description:     Initialize member variables.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    CondVar();
+
+    /*******************************************************************************
+    **
+    ** Function:        ~CondVar
+    **
+    ** Description:     Cleanup all resources.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~CondVar();
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the caller and wait for a condition.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void wait(std::mutex& mutex);
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the caller and wait for a condition.
+    **                  millisec: Timeout in milliseconds.
+    **
+    ** Returns:         True if wait is successful; false if timeout occurs.
+    **
+    *******************************************************************************/
+    bool wait(std::mutex& mutex, long millisec);
+
+    /*******************************************************************************
+    **
+    ** Function:        notifyOne
+    **
+    ** Description:     Unblock the waiting thread.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void notifyOne();
+
+  private:
+    pthread_cond_t mCondition;
+};
diff --git a/nfc/aidl/vts/functional/SyncEvent.h b/nfc/aidl/vts/functional/SyncEvent.h
new file mode 100644
index 0000000..352a549
--- /dev/null
+++ b/nfc/aidl/vts/functional/SyncEvent.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ *  Synchronize two or more threads using a condition variable and a mutex.
+ */
+#pragma once
+#include <mutex>
+
+#include "CondVar.h"
+
+class SyncEvent {
+  public:
+    /*******************************************************************************
+    **
+    ** Function:        ~SyncEvent
+    **
+    ** Description:     Cleanup all resources.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~SyncEvent() {}
+
+    /*******************************************************************************
+    **
+    ** Function:        start
+    **
+    ** Description:     Start a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void start() { mMutex.lock(); }
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the thread and wait for the event to occur.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void wait() { mCondVar.wait(mMutex); }
+
+    /*******************************************************************************
+    **
+    ** Function:        wait
+    **
+    ** Description:     Block the thread and wait for the event to occur.
+    **                  millisec: Timeout in milliseconds.
+    **
+    ** Returns:         True if wait is successful; false if timeout occurs.
+    **
+    *******************************************************************************/
+    bool wait(long millisec) {
+        bool retVal = mCondVar.wait(mMutex, millisec);
+        return retVal;
+    }
+
+    /*******************************************************************************
+    **
+    ** Function:        notifyOne
+    **
+    ** Description:     Notify a blocked thread that the event has occurred.
+    *Unblocks it.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void notifyOne() { mCondVar.notifyOne(); }
+
+    /*******************************************************************************
+    **
+    ** Function:        end
+    **
+    ** Description:     End a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    void end() { mMutex.unlock(); }
+
+  private:
+    CondVar mCondVar;
+    std::mutex mMutex;
+};
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+/*****************************************************************************
+**
+**  Name:           SyncEventGuard
+**
+**  Description:    Automatically start and end a synchronization event.
+**
+*****************************************************************************/
+class SyncEventGuard {
+  public:
+    /*******************************************************************************
+    **
+    ** Function:        SyncEventGuard
+    **
+    ** Description:     Start a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    SyncEventGuard(SyncEvent& event) : mEvent(event) {
+        event.start();  // automatically start operation
+    };
+
+    /*******************************************************************************
+    **
+    ** Function:        ~SyncEventGuard
+    **
+    ** Description:     End a synchronization operation.
+    **
+    ** Returns:         None.
+    **
+    *******************************************************************************/
+    ~SyncEventGuard() {
+        mEvent.end();  // automatically end operation
+    };
+
+  private:
+    SyncEvent& mEvent;
+};
diff --git a/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
new file mode 100644
index 0000000..0b73cc9
--- /dev/null
+++ b/nfc/aidl/vts/functional/VtsNfcBehaviorChangesTest.cpp
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "nfc_behavior_changes_test"
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android/binder_process.h>
+#include <gtest/gtest.h>
+
+#include <chrono>
+#include <future>
+
+#include "NfcAdaptation.h"
+#include "SyncEvent.h"
+#include "nci_defs.h"
+#include "nfa_api.h"
+#include "nfa_ee_api.h"
+
+using android::base::StringPrintf;
+
+static SyncEvent sNfaEnableEvent;  // event for NFA_Enable()
+static SyncEvent sNfaVsCommand;    // event for VS commands
+static SyncEvent sNfaEnableDisablePollingEvent;
+static SyncEvent sNfaPowerChangeEvent;
+static bool sIsNfaEnabled;
+static tNFA_STATUS sVSCmdStatus;
+
+static void nfaDeviceManagementCallback(uint8_t dmEvent, tNFA_DM_CBACK_DATA* eventData) {
+    LOG(DEBUG) << StringPrintf("%s: enter; event=0x%X", __func__, dmEvent);
+
+    switch (dmEvent) {
+        case NFA_DM_ENABLE_EVT: /* Result of NFA_Enable */
+        {
+            SyncEventGuard guard(sNfaEnableEvent);
+            LOG(DEBUG) << StringPrintf("%s: NFA_DM_ENABLE_EVT; status=0x%X", __func__,
+                                       eventData->status);
+            sIsNfaEnabled = eventData->status == NFA_STATUS_OK;
+            sNfaEnableEvent.notifyOne();
+        } break;
+
+        case NFA_DM_DISABLE_EVT: /* Result of NFA_Disable */
+        {
+            SyncEventGuard guard(sNfaEnableEvent);
+            LOG(DEBUG) << StringPrintf("%s: NFA_DM_DISABLE_EVT; status=0x%X", __func__,
+                                       eventData->status);
+            sIsNfaEnabled = eventData->status == NFA_STATUS_OK;
+            sNfaEnableEvent.notifyOne();
+        } break;
+
+        case NFA_DM_PWR_MODE_CHANGE_EVT: {
+            SyncEventGuard guard(sNfaPowerChangeEvent);
+            LOG(DEBUG) << StringPrintf(
+                    "%s: NFA_DM_PWR_MODE_CHANGE_EVT: status=0x%X, power_mode=0x%X", __func__,
+                    eventData->status, eventData->power_mode.power_mode);
+
+            sNfaPowerChangeEvent.notifyOne();
+
+        } break;
+    }
+}
+
+static void nfaConnectionCallback(uint8_t connEvent, tNFA_CONN_EVT_DATA* eventData) {
+    LOG(DEBUG) << StringPrintf("%s: event= %u", __func__, connEvent);
+
+    switch (connEvent) {
+        case NFA_LISTEN_DISABLED_EVT: {
+            SyncEventGuard guard(sNfaEnableDisablePollingEvent);
+            sNfaEnableDisablePollingEvent.notifyOne();
+        } break;
+
+        case NFA_LISTEN_ENABLED_EVT: {
+            SyncEventGuard guard(sNfaEnableDisablePollingEvent);
+            sNfaEnableDisablePollingEvent.notifyOne();
+        } break;
+
+        case NFA_RF_DISCOVERY_STARTED_EVT:  // RF Discovery started
+        {
+            LOG(DEBUG) << StringPrintf("%s: NFA_RF_DISCOVERY_STARTED_EVT: status = %u", __func__,
+                                       eventData->status);
+
+            SyncEventGuard guard(sNfaEnableDisablePollingEvent);
+            sNfaEnableDisablePollingEvent.notifyOne();
+        } break;
+
+        case NFA_RF_DISCOVERY_STOPPED_EVT:  // RF Discovery stopped event
+        {
+            LOG(DEBUG) << StringPrintf("%s: NFA_RF_DISCOVERY_STOPPED_EVT: status = %u", __func__,
+                                       eventData->status);
+
+            SyncEventGuard guard(sNfaEnableDisablePollingEvent);
+            sNfaEnableDisablePollingEvent.notifyOne();
+        } break;
+    }
+}
+
+void static nfaVSCallback(uint8_t event, uint16_t /* param_len */, uint8_t* p_param) {
+    switch (event & NCI_OID_MASK) {
+        case NCI_MSG_PROP_ANDROID: {
+            uint8_t android_sub_opcode = p_param[3];
+            switch (android_sub_opcode) {
+                case NCI_ANDROID_PASSIVE_OBSERVE: {
+                    sVSCmdStatus = p_param[4];
+                    LOG(INFO) << StringPrintf("Observe mode RSP: status: %x", sVSCmdStatus);
+                    SyncEventGuard guard(sNfaVsCommand);
+                    sNfaVsCommand.notifyOne();
+                } break;
+                case NCI_ANDROID_POLLING_FRAME_NTF: {
+                    // TODO
+                } break;
+                default:
+                    LOG(WARNING) << StringPrintf("Unknown Android sub opcode %x",
+                                                 android_sub_opcode);
+            }
+        } break;
+        default:
+            break;
+    }
+}
+
+/*
+ * Enable passive observe mode.
+ */
+tNFA_STATUS static nfaObserveModeEnable(bool enable) {
+    tNFA_STATUS status = NFA_STATUS_FAILED;
+
+    status = NFA_StopRfDiscovery();
+    if (status == NFA_STATUS_OK) {
+        if (!sNfaEnableDisablePollingEvent.wait(1000)) {
+            LOG(WARNING) << "Timeout waiting to disable NFC RF discovery";
+            return NFA_STATUS_TIMEOUT;
+        }
+    }
+
+    uint8_t cmd[] = {(NCI_MT_CMD << NCI_MT_SHIFT) | NCI_GID_PROP, NCI_MSG_PROP_ANDROID,
+                     NCI_ANDROID_PASSIVE_OBSERVE_PARAM_SIZE, NCI_ANDROID_PASSIVE_OBSERVE,
+                     static_cast<uint8_t>(enable ? NCI_ANDROID_PASSIVE_OBSERVE_PARAM_ENABLE
+                                                 : NCI_ANDROID_PASSIVE_OBSERVE_PARAM_DISABLE)};
+
+    status = NFA_SendRawVsCommand(sizeof(cmd), cmd, nfaVSCallback);
+
+    if (status == NFA_STATUS_OK) {
+        if (!sNfaVsCommand.wait(1000)) {
+            LOG(WARNING) << "Timeout waiting for NFA VS command response";
+            return NFA_STATUS_TIMEOUT;
+        }
+    }
+
+    return status;
+}
+
+class NfcBehaviorChanges : public testing::Test {
+  protected:
+    void SetUp() override {
+        tNFA_STATUS status = NFA_STATUS_OK;
+
+        sIsNfaEnabled = false;
+        sVSCmdStatus = NFA_STATUS_OK;
+
+        NfcAdaptation& theInstance = NfcAdaptation::GetInstance();
+        theInstance.Initialize();  // start GKI, NCI task, NFC task
+
+        {
+            SyncEventGuard guard(sNfaEnableEvent);
+            tHAL_NFC_ENTRY* halFuncEntries = theInstance.GetHalEntryFuncs();
+
+            NFA_Init(halFuncEntries);
+
+            status = NFA_Enable(nfaDeviceManagementCallback, nfaConnectionCallback);
+            ASSERT_EQ(status, NFA_STATUS_OK);
+
+            // wait for NFA command to finish
+            ASSERT_TRUE(sNfaEnableEvent.wait(1000))
+                    << "Timeout waiting for NFA command on NFA_Enable";
+        }
+
+        ASSERT_TRUE(sIsNfaEnabled) << "Could not initialize NFC controller";
+
+        status = NFA_StartRfDiscovery();
+        ASSERT_EQ(status, NFA_STATUS_OK);
+        ASSERT_TRUE(sNfaEnableDisablePollingEvent.wait(1000)) << "Timeout starting RF discovery";
+    }
+};
+
+/*
+ * ObserveModeEnable:
+ * Attempts to enable observe mode. Does not test Observe Mode functionality,
+ * but simply verifies that the enable command responds successfully.
+ *
+ * @VsrTest = GMS-VSR-3.2.8-001
+ */
+TEST_F(NfcBehaviorChanges, ObserveModeEnableDisable) {
+    tNFA_STATUS status = nfaObserveModeEnable(true);
+    ASSERT_EQ(status, NFA_STATUS_OK);
+
+    status = nfaObserveModeEnable(false);
+    ASSERT_EQ(status, NFA_STATUS_OK);
+}
+
+int main(int argc, char** argv) {
+    testing::InitGoogleTest(&argc, argv);
+    ABinderProcess_startThreadPool();
+    std::system("/system/bin/svc nfc disable"); /* Turn off NFC service */
+    sleep(5);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    std::system("/system/bin/svc nfc enable"); /* Turn on NFC service */
+    sleep(5);
+    return status;
+}
diff --git a/power/aidl/android/hardware/power/SessionConfig.aidl b/power/aidl/android/hardware/power/SessionConfig.aidl
index 93dc9a2..ca89183 100644
--- a/power/aidl/android/hardware/power/SessionConfig.aidl
+++ b/power/aidl/android/hardware/power/SessionConfig.aidl
@@ -25,6 +25,9 @@
     /**
      * The session's unique ID, used to identify the session for debugging and
      * for multiplexing on the per-process FMQ channel.
+     *
+     * Values that fit in the 32-bit int range value must be provided when using
+     * the FMQ API, as the FMQ messages can only accept 32-bit Session IDs.
      */
     long id;
 }
diff --git a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
index 01f7327..451eaa9 100644
--- a/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
+++ b/radio/aidl/android/hardware/radio/network/SecurityAlgorithm.aidl
@@ -62,7 +62,7 @@
     // IMS and SIP layer security (See 3GPP TS 33.203)
     // No IPsec config
     SIP_NO_IPSEC_CONFIG = 66,
-    IMS_NULL = 67,
+    IMS_NULL = 67, // Deprecated. Use SIP_NO_IPSEC_CONFIG and SIP_NULL instead.
 
     // Has IPsec config
     SIP_NULL = 68,
diff --git a/radio/aidl/vts/radio_config_test.cpp b/radio/aidl/vts/radio_config_test.cpp
index 6f18d18..e7214e5 100644
--- a/radio/aidl/vts/radio_config_test.cpp
+++ b/radio/aidl/vts/radio_config_test.cpp
@@ -278,7 +278,14 @@
                     EXPECT_LT(logicalSlotId, slotPortMappingList.size());
                     if (logicalSlotId >= 0 && logicalSlotId < slotPortMappingList.size()) {
                         slotPortMappingList[logicalSlotId].physicalSlotId = i;
-                        slotPortMappingList[logicalSlotId].portId = j;
+                        if (radioRsp_config->simSlotStatus[i].supportedMepMode ==
+                                    MultipleEnabledProfilesMode::MEP_A1 ||
+                            radioRsp_config->simSlotStatus[i].supportedMepMode ==
+                                    MultipleEnabledProfilesMode::MEP_A2) {
+                            slotPortMappingList[logicalSlotId].portId = j + 1;
+                        } else {
+                            slotPortMappingList[logicalSlotId].portId = j;
+                        }
                     }
                 }
             }
diff --git a/sensors/aidl/default/include/sensors-impl/Sensors.h b/sensors/aidl/default/include/sensors-impl/Sensors.h
index e270d96..2adbc9d 100644
--- a/sensors/aidl/default/include/sensors-impl/Sensors.h
+++ b/sensors/aidl/default/include/sensors-impl/Sensors.h
@@ -119,6 +119,8 @@
 
     // Utility function to delete the Event Flag
     void deleteEventFlag() {
+        // Hold the lock to ensure we don't delete the flag while it's being used in postEvents()
+        std::lock_guard<std::mutex> lock(mWriteLock);
         if (mEventQueueFlag != nullptr) {
             status_t status = EventFlag::deleteEventFlag(&mEventQueueFlag);
             if (status != OK) {
diff --git a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
index 4208d09..7f33e2d 100644
--- a/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
+++ b/thermal/aidl/vts/VtsHalThermalTargetTest.cpp
@@ -25,6 +25,7 @@
 
 #define LOG_TAG "thermal_aidl_hal_test"
 
+#include <VtsCoreUtil.h>
 #include <aidl/Gtest.h>
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/thermal/BnCoolingDeviceChangedCallback.h>
@@ -70,6 +71,16 @@
         .timeWindowMs = 7000,
 };
 
+static const std::string FEATURE_WATCH = "android.hardware.type.watch";
+static const std::string FEATURE_TELEVISION = "android.hardware.type.television";
+static const std::string FEATURE_LEANBACK = "android.software.leanback";
+static const std::string FEATURE_AUTOMOTIVE = "android.hardware.type.automotive";
+static const std::string FEATURE_PC = "android.hardware.type.pc";
+static const std::string FEATURE_EMBEDDED = "android.hardware.type.embedded";
+static const std::string kNonHandheldFeatures[] = {FEATURE_AUTOMOTIVE, FEATURE_LEANBACK,
+                                                   FEATURE_PC,         FEATURE_TELEVISION,
+                                                   FEATURE_WATCH,      FEATURE_EMBEDDED};
+
 // Callback class for receiving thermal event notifications from main class
 class ThermalCallback : public BnThermalChangedCallback {
   public:
@@ -341,8 +352,13 @@
 // @VsrTest = VSR-3.2.5-002
 TEST_P(ThermalAidlTest, SkinTemperatureThresholdsTest) {
     auto apiLevel = ::android::base::GetIntProperty<int32_t>("ro.vendor.api_level", 0);
-    if (apiLevel < 35) {
-        GTEST_SKIP() << "Skipping test as the vendor level is below 35: " << apiLevel;
+    if (apiLevel < 202404) {
+        GTEST_SKIP() << "Skipping test as the vendor level is below 202404: " << apiLevel;
+    }
+    for (const auto& feature : kNonHandheldFeatures) {
+        if (::testing::deviceSupportsFeature(feature.c_str())) {
+            GTEST_SKIP() << "Skipping test as the device has feature: " << feature;
+        }
     }
     std::vector<Temperature> temperatures;
     ::ndk::ScopedAStatus status =
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 6c6846f..db474d6 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -41,6 +41,8 @@
 using android::hardware::vibrator::PrimitivePwle;
 using std::chrono::high_resolution_clock;
 
+using namespace ::std::chrono_literals;
+
 const std::vector<Effect> kEffects{android::enum_range<Effect>().begin(),
                                    android::enum_range<Effect>().end()};
 const std::vector<EffectStrength> kEffectStrengths{android::enum_range<EffectStrength>().begin(),
@@ -71,6 +73,9 @@
     static_cast<CompositePrimitive>(static_cast<int32_t>(kCompositePrimitives.back()) + 1),
 };
 
+// Timeout to wait for vibration callback completion.
+static constexpr auto VIBRATION_CALLBACK_TIMEOUT = 100ms;
+
 class CompletionCallback : public BnVibratorCallback {
   public:
     CompletionCallback(const std::function<void()> &callback) : mCallback(callback) {}
@@ -221,7 +226,7 @@
     sp<CompletionCallback> callback =
         new CompletionCallback([&completionPromise] { completionPromise.set_value(); });
     uint32_t durationMs = 250;
-    std::chrono::milliseconds timeout{durationMs * 2};
+    auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
     EXPECT_TRUE(vibrator->on(durationMs, callback).isOk());
     EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
     EXPECT_TRUE(vibrator->off().isOk());
@@ -288,10 +293,10 @@
             if (!status.isOk())
                 continue;
 
-            //TODO(b/187207798): revert back to conservative timeout values once
-            //latencies have been fixed
-            std::chrono::milliseconds timeout{lengthMs * 8};
+            auto timeout = std::chrono::milliseconds(lengthMs) + VIBRATION_CALLBACK_TIMEOUT;
             EXPECT_EQ(completionFuture.wait_for(timeout), std::future_status::ready);
+
+            EXPECT_TRUE(vibrator->off().isOk());
         }
     }
 }
@@ -619,9 +624,7 @@
         EXPECT_EQ(Status::EX_NONE, vibrator->compose(composite, callback).exceptionCode())
                 << toString(primitive);
 
-        // TODO(b/261130361): Investigate why latency from driver and hardware will cause test
-        // to fail when wait duration is ~40ms or less.
-        EXPECT_EQ(completionFuture.wait_for(duration + std::chrono::milliseconds(50)),
+        EXPECT_EQ(completionFuture.wait_for(duration + VIBRATION_CALLBACK_TIMEOUT),
                   std::future_status::ready)
                 << toString(primitive);
         end = high_resolution_clock::now();
@@ -782,9 +785,7 @@
     int32_t segmentDurationMaxMs;
     vibrator->getPwlePrimitiveDurationMax(&segmentDurationMaxMs);
     uint32_t durationMs = segmentDurationMaxMs * 2 + 100;  // Sum of 2 active and 1 braking below
-    //TODO(b/187207798): revert back to conservative timeout values once
-    //latencies have been fixed
-    std::chrono::milliseconds timeout{durationMs * 4};
+    auto timeout = std::chrono::milliseconds(durationMs) + VIBRATION_CALLBACK_TIMEOUT;
 
     ActivePwle active = composeValidActivePwle(vibrator, capabilities);
 
diff --git a/vibrator/bench/benchmark.cpp b/vibrator/bench/benchmark.cpp
index b96e06d..deaa6f2 100644
--- a/vibrator/bench/benchmark.cpp
+++ b/vibrator/bench/benchmark.cpp
@@ -20,6 +20,8 @@
 #include <android/hardware/vibrator/BnVibratorCallback.h>
 #include <android/hardware/vibrator/IVibrator.h>
 #include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <future>
 
 using ::android::enum_range;
 using ::android::sp;
@@ -31,9 +33,8 @@
 using ::benchmark::kMicrosecond;
 using ::benchmark::State;
 using ::benchmark::internal::Benchmark;
-using ::std::chrono::duration;
-using ::std::chrono::duration_cast;
-using ::std::chrono::high_resolution_clock;
+
+using namespace ::std::chrono_literals;
 
 namespace Aidl = ::android::hardware::vibrator;
 namespace V1_0 = ::android::hardware::vibrator::V1_0;
@@ -41,14 +42,28 @@
 namespace V1_2 = ::android::hardware::vibrator::V1_2;
 namespace V1_3 = ::android::hardware::vibrator::V1_3;
 
+// Fixed number of iterations for benchmarks that trigger a vibration on the loop.
+// They require slow cleanup to ensure a stable state on each run and less noisy metrics.
+static constexpr auto VIBRATION_ITERATIONS = 500;
+
+// Timeout to wait for vibration callback completion.
+static constexpr auto VIBRATION_CALLBACK_TIMEOUT = 100ms;
+
+// Max duration the vibrator can be turned on, in milliseconds.
+static constexpr uint32_t MAX_ON_DURATION_MS = UINT16_MAX;
+
 template <typename I>
 class BaseBench : public Fixture {
   public:
+    void SetUp(State& /*state*/) override {
+        android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+        android::ProcessState::self()->startThreadPool();
+    }
+
     void TearDown(State& /*state*/) override {
-        if (!mVibrator) {
-            return;
+        if (mVibrator) {
+            mVibrator->off();
         }
-        mVibrator->off();
     }
 
     static void DefaultConfig(Benchmark* b) { b->Unit(kMicrosecond); }
@@ -66,7 +81,19 @@
 template <typename I>
 class VibratorBench : public BaseBench<I> {
   public:
-    void SetUp(State& /*state*/) override { this->mVibrator = I::getService(); }
+    void SetUp(State& state) override {
+        BaseBench<I>::SetUp(state);
+        this->mVibrator = I::getService();
+    }
+
+  protected:
+    bool shouldSkipWithError(State& state, const android::hardware::Return<V1_0::Status>&& ret) {
+        if (!ret.isOk()) {
+            state.SkipWithError(ret.description());
+            return true;
+        }
+        return false;
+    }
 };
 
 enum class EmptyEnum : uint32_t;
@@ -118,16 +145,25 @@
         });
 
         if (!supported) {
-            state->SkipWithMessage("performApi returned UNSUPPORTED_OPERATION");
+            state->SkipWithMessage("effect unsupported");
             return;
         }
 
         for (auto _ : *state) {
-            state->ResumeTiming();
-            (*this->mVibrator.*performApi)(effect, strength,
-                                           [](Status /*status*/, uint32_t /*lengthMs*/) {});
+            // Test
+            auto ret = (*this->mVibrator.*performApi)(
+                    effect, strength, [](Status /*status*/, uint32_t /*lengthMs*/) {});
+
+            // Cleanup
             state->PauseTiming();
-            this->mVibrator->off();
+            if (!ret.isOk()) {
+                state->SkipWithError(ret.description());
+                return;
+            }
+            if (this->shouldSkipWithError(*state, this->mVibrator->off())) {
+                return;
+            }
+            state->ResumeTiming();
         }
     }
 
@@ -157,24 +193,38 @@
 using VibratorBench_V1_0 = VibratorBench<V1_0::IVibrator>;
 
 BENCHMARK_WRAPPER(VibratorBench_V1_0, on, {
-    uint32_t ms = UINT32_MAX;
+    auto ms = MAX_ON_DURATION_MS;
 
     for (auto _ : state) {
-        state.ResumeTiming();
-        mVibrator->on(ms);
+        // Test
+        if (shouldSkipWithError(state, mVibrator->on(ms))) {
+            return;
+        }
+
+        // Cleanup
         state.PauseTiming();
-        mVibrator->off();
+        if (shouldSkipWithError(state, mVibrator->off())) {
+            return;
+        }
+        state.ResumeTiming();
     }
 });
 
 BENCHMARK_WRAPPER(VibratorBench_V1_0, off, {
-    uint32_t ms = UINT32_MAX;
+    auto ms = MAX_ON_DURATION_MS;
 
     for (auto _ : state) {
+        // Setup
         state.PauseTiming();
-        mVibrator->on(ms);
+        if (shouldSkipWithError(state, mVibrator->on(ms))) {
+            return;
+        }
         state.ResumeTiming();
-        mVibrator->off();
+
+        // Test
+        if (shouldSkipWithError(state, mVibrator->off())) {
+            return;
+        }
     }
 });
 
@@ -185,20 +235,23 @@
 });
 
 BENCHMARK_WRAPPER(VibratorBench_V1_0, setAmplitude, {
+    auto ms = MAX_ON_DURATION_MS;
     uint8_t amplitude = UINT8_MAX;
 
     if (!mVibrator->supportsAmplitudeControl()) {
-        state.SkipWithMessage("Amplitude control unavailable");
+        state.SkipWithMessage("amplitude control unavailable");
         return;
     }
 
-    mVibrator->on(UINT32_MAX);
-
-    for (auto _ : state) {
-        mVibrator->setAmplitude(amplitude);
+    if (shouldSkipWithError(state, mVibrator->on(ms))) {
+        return;
     }
 
-    mVibrator->off();
+    for (auto _ : state) {
+        if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
+            return;
+        }
+    }
 });
 
 using VibratorEffectsBench_V1_0 = VibratorEffectsBench<V1_0::IVibrator, V1_0::Effect>;
@@ -218,7 +271,15 @@
 BENCHMARK_WRAPPER(VibratorEffectsBench_V1_2, perform_1_2,
                   { performBench(&state, &V1_2::IVibrator::perform_1_2); });
 
-using VibratorBench_V1_3 = VibratorBench<V1_3::IVibrator>;
+class VibratorBench_V1_3 : public VibratorBench<V1_3::IVibrator> {
+  public:
+    void TearDown(State& state) override {
+        VibratorBench::TearDown(state);
+        if (mVibrator) {
+            mVibrator->setExternalControl(false);
+        }
+    }
+};
 
 BENCHMARK_WRAPPER(VibratorBench_V1_3, supportsExternalControl, {
     for (auto _ : state) {
@@ -227,18 +288,23 @@
 });
 
 BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalControl, {
-    bool enable = true;
-
     if (!mVibrator->supportsExternalControl()) {
         state.SkipWithMessage("external control unavailable");
         return;
     }
 
     for (auto _ : state) {
-        state.ResumeTiming();
-        mVibrator->setExternalControl(enable);
+        // Test
+        if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
+            return;
+        }
+
+        // Cleanup
         state.PauseTiming();
-        mVibrator->setExternalControl(false);
+        if (shouldSkipWithError(state, mVibrator->setExternalControl(false))) {
+            return;
+        }
+        state.ResumeTiming();
     }
 });
 
@@ -248,13 +314,13 @@
         return;
     }
 
-    mVibrator->setExternalControl(true);
+    if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
+        return;
+    }
 
     for (auto _ : state) {
         mVibrator->supportsAmplitudeControl();
     }
-
-    mVibrator->setExternalControl(false);
 });
 
 BENCHMARK_WRAPPER(VibratorBench_V1_3, setExternalAmplitude, {
@@ -265,7 +331,9 @@
         return;
     }
 
-    mVibrator->setExternalControl(true);
+    if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
+        return;
+    }
 
     if (!mVibrator->supportsAmplitudeControl()) {
         state.SkipWithMessage("amplitude control unavailable");
@@ -273,10 +341,10 @@
     }
 
     for (auto _ : state) {
-        mVibrator->setAmplitude(amplitude);
+        if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
+            return;
+        }
     }
-
-    mVibrator->setExternalControl(false);
 });
 
 using VibratorEffectsBench_V1_3 = VibratorEffectsBench<V1_3::IVibrator, V1_3::Effect, V1_2::Effect>;
@@ -286,9 +354,42 @@
 
 class VibratorBench_Aidl : public BaseBench<Aidl::IVibrator> {
   public:
-    void SetUp(State& /*state*/) override {
+    void SetUp(State& state) override {
+        BaseBench::SetUp(state);
         this->mVibrator = android::waitForVintfService<Aidl::IVibrator>();
     }
+
+    void TearDown(State& state) override {
+        BaseBench::TearDown(state);
+        if (mVibrator) {
+            mVibrator->setExternalControl(false);
+        }
+    }
+
+  protected:
+    int32_t hasCapabilities(int32_t capabilities) {
+        int32_t deviceCapabilities = 0;
+        this->mVibrator->getCapabilities(&deviceCapabilities);
+        return (deviceCapabilities & capabilities) == capabilities;
+    }
+
+    bool shouldSkipWithError(State& state, const android::binder::Status&& status) {
+        if (!status.isOk()) {
+            state.SkipWithError(status.toString8().c_str());
+            return true;
+        }
+        return false;
+    }
+
+    static void SlowBenchConfig(Benchmark* b) { b->Iterations(VIBRATION_ITERATIONS); }
+};
+
+class SlowVibratorBench_Aidl : public VibratorBench_Aidl {
+  public:
+    static void DefaultConfig(Benchmark* b) {
+        VibratorBench_Aidl::DefaultConfig(b);
+        SlowBenchConfig(b);
+    }
 };
 
 class HalCallback : public Aidl::BnVibratorCallback {
@@ -296,30 +397,70 @@
     HalCallback() = default;
     ~HalCallback() = default;
 
-    android::binder::Status onComplete() override { return android::binder::Status::ok(); }
+    android::binder::Status onComplete() override {
+        mPromise.set_value();
+        return android::binder::Status::ok();
+    }
+
+    void waitForComplete() {
+        // Wait until the HAL has finished processing previous vibration before starting a new one,
+        // so the HAL state is consistent on each run and metrics are less noisy. Some of the newest
+        // HAL implementations are waiting on previous vibration cleanup and might be significantly
+        // slower, so make sure we measure vibrations on a clean slate.
+        mPromise.get_future().wait_for(VIBRATION_CALLBACK_TIMEOUT);
+    }
+
+  private:
+    std::promise<void> mPromise;
 };
 
-BENCHMARK_WRAPPER(VibratorBench_Aidl, on, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-
-    int32_t ms = INT32_MAX;
-    auto cb = (capabilities & Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
+BENCHMARK_WRAPPER(SlowVibratorBench_Aidl, on, {
+    auto ms = MAX_ON_DURATION_MS;
 
     for (auto _ : state) {
-        state.ResumeTiming();
-        mVibrator->on(ms, cb);
+        auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
+
+        // Test
+        if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
+            return;
+        }
+
+        // Cleanup
         state.PauseTiming();
-        mVibrator->off();
+        if (shouldSkipWithError(state, mVibrator->off())) {
+            return;
+        }
+        if (cb) {
+            cb->waitForComplete();
+        }
+        state.ResumeTiming();
     }
 });
 
-BENCHMARK_WRAPPER(VibratorBench_Aidl, off, {
+BENCHMARK_WRAPPER(SlowVibratorBench_Aidl, off, {
+    auto ms = MAX_ON_DURATION_MS;
+
     for (auto _ : state) {
+        auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
+
+        // Setup
         state.PauseTiming();
-        mVibrator->on(INT32_MAX, nullptr);
+        if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
+            return;
+        }
         state.ResumeTiming();
-        mVibrator->off();
+
+        // Test
+        if (shouldSkipWithError(state, mVibrator->off())) {
+            return;
+        }
+
+        // Cleanup
+        state.PauseTiming();
+        if (cb) {
+            cb->waitForComplete();
+        }
+        state.ResumeTiming();
     }
 });
 
@@ -327,76 +468,97 @@
     int32_t capabilities = 0;
 
     for (auto _ : state) {
-        mVibrator->getCapabilities(&capabilities);
+        if (shouldSkipWithError(state, mVibrator->getCapabilities(&capabilities))) {
+            return;
+        }
     }
 });
 
 BENCHMARK_WRAPPER(VibratorBench_Aidl, setAmplitude, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-    if ((capabilities & Aidl::IVibrator::CAP_AMPLITUDE_CONTROL) == 0) {
+    auto ms = MAX_ON_DURATION_MS;
+    float amplitude = 1.0f;
+
+    if (!hasCapabilities(Aidl::IVibrator::CAP_AMPLITUDE_CONTROL)) {
         state.SkipWithMessage("amplitude control unavailable");
         return;
     }
 
-    float amplitude = 1.0f;
-    mVibrator->on(INT32_MAX, nullptr);
-
-    for (auto _ : state) {
-        mVibrator->setAmplitude(amplitude);
+    auto cb = hasCapabilities(Aidl::IVibrator::CAP_ON_CALLBACK) ? new HalCallback() : nullptr;
+    if (shouldSkipWithError(state, mVibrator->on(ms, cb))) {
+        return;
     }
 
-    mVibrator->off();
+    for (auto _ : state) {
+        if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
+            return;
+        }
+    }
 });
 
 BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalControl, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-    if ((capabilities & Aidl::IVibrator::CAP_EXTERNAL_CONTROL) == 0) {
+    if (!hasCapabilities(Aidl::IVibrator::CAP_EXTERNAL_CONTROL)) {
         state.SkipWithMessage("external control unavailable");
         return;
     }
 
     for (auto _ : state) {
-        state.ResumeTiming();
-        mVibrator->setExternalControl(true);
+        // Test
+        if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
+            return;
+        }
+
+        // Cleanup
         state.PauseTiming();
-        mVibrator->setExternalControl(false);
+        if (shouldSkipWithError(state, mVibrator->setExternalControl(false))) {
+            return;
+        }
+        state.ResumeTiming();
     }
 });
 
 BENCHMARK_WRAPPER(VibratorBench_Aidl, setExternalAmplitude, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-    if ((capabilities & Aidl::IVibrator::CAP_EXTERNAL_CONTROL) == 0 ||
-        (capabilities & Aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL) == 0) {
+    auto externalControl = static_cast<int32_t>(Aidl::IVibrator::CAP_EXTERNAL_CONTROL);
+    auto externalAmplitudeControl =
+            static_cast<int32_t>(Aidl::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL);
+    if (!hasCapabilities(externalControl | externalAmplitudeControl)) {
         state.SkipWithMessage("external amplitude control unavailable");
         return;
     }
 
-    float amplitude = 1.0f;
-    mVibrator->setExternalControl(true);
-
-    for (auto _ : state) {
-        mVibrator->setAmplitude(amplitude);
+    if (shouldSkipWithError(state, mVibrator->setExternalControl(true))) {
+        return;
     }
 
-    mVibrator->setExternalControl(false);
+    float amplitude = 1.0f;
+    for (auto _ : state) {
+        if (shouldSkipWithError(state, mVibrator->setAmplitude(amplitude))) {
+            return;
+        }
+    }
 });
 
 BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedEffects, {
     std::vector<Aidl::Effect> supportedEffects;
 
     for (auto _ : state) {
-        mVibrator->getSupportedEffects(&supportedEffects);
+        if (shouldSkipWithError(state, mVibrator->getSupportedEffects(&supportedEffects))) {
+            return;
+        }
     }
 });
 
 BENCHMARK_WRAPPER(VibratorBench_Aidl, getSupportedAlwaysOnEffects, {
+    if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
+        state.SkipWithMessage("always on control unavailable");
+        return;
+    }
+
     std::vector<Aidl::Effect> supportedEffects;
 
     for (auto _ : state) {
-        mVibrator->getSupportedAlwaysOnEffects(&supportedEffects);
+        if (shouldSkipWithError(state, mVibrator->getSupportedAlwaysOnEffects(&supportedEffects))) {
+            return;
+        }
     }
 });
 
@@ -404,7 +566,9 @@
     std::vector<Aidl::CompositePrimitive> supportedPrimitives;
 
     for (auto _ : state) {
-        mVibrator->getSupportedPrimitives(&supportedPrimitives);
+        if (shouldSkipWithError(state, mVibrator->getSupportedPrimitives(&supportedPrimitives))) {
+            return;
+        }
     }
 });
 
@@ -427,12 +591,30 @@
     auto getStrength(const State& state) const {
         return static_cast<Aidl::EffectStrength>(this->getOtherArg(state, 1));
     }
+
+    bool isEffectSupported(const Aidl::Effect& effect) {
+        std::vector<Aidl::Effect> supported;
+        mVibrator->getSupportedEffects(&supported);
+        return std::find(supported.begin(), supported.end(), effect) != supported.end();
+    }
+
+    bool isAlwaysOnEffectSupported(const Aidl::Effect& effect) {
+        std::vector<Aidl::Effect> supported;
+        mVibrator->getSupportedAlwaysOnEffects(&supported);
+        return std::find(supported.begin(), supported.end(), effect) != supported.end();
+    }
+};
+
+class SlowVibratorEffectsBench_Aidl : public VibratorEffectsBench_Aidl {
+  public:
+    static void DefaultConfig(Benchmark* b) {
+        VibratorEffectsBench_Aidl::DefaultConfig(b);
+        SlowBenchConfig(b);
+    }
 };
 
 BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnEnable, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-    if ((capabilities & Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL) == 0) {
+    if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
         state.SkipWithMessage("always on control unavailable");
         return;
     }
@@ -441,25 +623,28 @@
     auto effect = getEffect(state);
     auto strength = getStrength(state);
 
-    std::vector<Aidl::Effect> supported;
-    mVibrator->getSupportedAlwaysOnEffects(&supported);
-    if (std::find(supported.begin(), supported.end(), effect) == supported.end()) {
-        state.SkipWithMessage("always on effects unavailable");
+    if (!isAlwaysOnEffectSupported(effect)) {
+        state.SkipWithMessage("always on effect unsupported");
         return;
     }
 
     for (auto _ : state) {
-        state.ResumeTiming();
-        mVibrator->alwaysOnEnable(id, effect, strength);
+        // Test
+        if (shouldSkipWithError(state, mVibrator->alwaysOnEnable(id, effect, strength))) {
+            return;
+        }
+
+        // Cleanup
         state.PauseTiming();
-        mVibrator->alwaysOnDisable(id);
+        if (shouldSkipWithError(state, mVibrator->alwaysOnDisable(id))) {
+            return;
+        }
+        state.ResumeTiming();
     }
 });
 
 BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, alwaysOnDisable, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-    if ((capabilities & Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL) == 0) {
+    if (!hasCapabilities(Aidl::IVibrator::CAP_ALWAYS_ON_CONTROL)) {
         state.SkipWithMessage("always on control unavailable");
         return;
     }
@@ -468,42 +653,55 @@
     auto effect = getEffect(state);
     auto strength = getStrength(state);
 
-    std::vector<Aidl::Effect> supported;
-    mVibrator->getSupportedAlwaysOnEffects(&supported);
-    if (std::find(supported.begin(), supported.end(), effect) == supported.end()) {
-        state.SkipWithMessage("always on effects unavailable");
+    if (!isAlwaysOnEffectSupported(effect)) {
+        state.SkipWithMessage("always on effect unsupported");
         return;
     }
 
     for (auto _ : state) {
+        // Setup
         state.PauseTiming();
-        mVibrator->alwaysOnEnable(id, effect, strength);
+        if (shouldSkipWithError(state, mVibrator->alwaysOnEnable(id, effect, strength))) {
+            return;
+        }
         state.ResumeTiming();
-        mVibrator->alwaysOnDisable(id);
+
+        // Test
+        if (shouldSkipWithError(state, mVibrator->alwaysOnDisable(id))) {
+            return;
+        }
     }
 });
 
-BENCHMARK_WRAPPER(VibratorEffectsBench_Aidl, perform, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-
+BENCHMARK_WRAPPER(SlowVibratorEffectsBench_Aidl, perform, {
     auto effect = getEffect(state);
     auto strength = getStrength(state);
-    auto cb = (capabilities & Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback() : nullptr;
-    int32_t lengthMs = 0;
 
-    std::vector<Aidl::Effect> supported;
-    mVibrator->getSupportedEffects(&supported);
-    if (std::find(supported.begin(), supported.end(), effect) == supported.end()) {
-        state.SkipWithMessage("effects unavailable");
+    if (!isEffectSupported(effect)) {
+        state.SkipWithMessage("effect unsupported");
         return;
     }
 
+    int32_t lengthMs = 0;
+
     for (auto _ : state) {
-        state.ResumeTiming();
-        mVibrator->perform(effect, strength, cb, &lengthMs);
+        auto cb = hasCapabilities(Aidl::IVibrator::CAP_PERFORM_CALLBACK) ? new HalCallback()
+                                                                         : nullptr;
+
+        // Test
+        if (shouldSkipWithError(state, mVibrator->perform(effect, strength, cb, &lengthMs))) {
+            return;
+        }
+
+        // Cleanup
         state.PauseTiming();
-        mVibrator->off();
+        if (shouldSkipWithError(state, mVibrator->off())) {
+            return;
+        }
+        if (cb) {
+            cb->waitForComplete();
+        }
+        state.ResumeTiming();
     }
 });
 
@@ -520,13 +718,29 @@
     auto getPrimitive(const State& state) const {
         return static_cast<Aidl::CompositePrimitive>(this->getOtherArg(state, 0));
     }
+
+    bool isPrimitiveSupported(const Aidl::CompositePrimitive& primitive) {
+        std::vector<Aidl::CompositePrimitive> supported;
+        mVibrator->getSupportedPrimitives(&supported);
+        return std::find(supported.begin(), supported.end(), primitive) != supported.end();
+    }
+};
+
+class SlowVibratorPrimitivesBench_Aidl : public VibratorPrimitivesBench_Aidl {
+  public:
+    static void DefaultConfig(Benchmark* b) {
+        VibratorPrimitivesBench_Aidl::DefaultConfig(b);
+        SlowBenchConfig(b);
+    }
 };
 
 BENCHMARK_WRAPPER(VibratorBench_Aidl, getCompositionDelayMax, {
     int32_t ms = 0;
 
     for (auto _ : state) {
-        mVibrator->getCompositionDelayMax(&ms);
+        if (shouldSkipWithError(state, mVibrator->getCompositionDelayMax(&ms))) {
+            return;
+        }
     }
 });
 
@@ -534,14 +748,14 @@
     int32_t size = 0;
 
     for (auto _ : state) {
-        mVibrator->getCompositionSizeMax(&size);
+        if (shouldSkipWithError(state, mVibrator->getCompositionSizeMax(&size))) {
+            return;
+        }
     }
 });
 
 BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, getPrimitiveDuration, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-    if ((capabilities & Aidl::IVibrator::CAP_COMPOSE_EFFECTS) == 0) {
+    if (!hasCapabilities(Aidl::IVibrator::CAP_COMPOSE_EFFECTS)) {
         state.SkipWithMessage("compose effects unavailable");
         return;
     }
@@ -549,22 +763,20 @@
     auto primitive = getPrimitive(state);
     int32_t ms = 0;
 
-    std::vector<Aidl::CompositePrimitive> supported;
-    mVibrator->getSupportedPrimitives(&supported);
-    if (std::find(supported.begin(), supported.end(), primitive) == supported.end()) {
-        state.SkipWithMessage("supported primitives unavailable");
+    if (!isPrimitiveSupported(primitive)) {
+        state.SkipWithMessage("primitive unsupported");
         return;
     }
 
     for (auto _ : state) {
-        mVibrator->getPrimitiveDuration(primitive, &ms);
+        if (shouldSkipWithError(state, mVibrator->getPrimitiveDuration(primitive, &ms))) {
+            return;
+        }
     }
 });
 
-BENCHMARK_WRAPPER(VibratorPrimitivesBench_Aidl, compose, {
-    int32_t capabilities = 0;
-    mVibrator->getCapabilities(&capabilities);
-    if ((capabilities & Aidl::IVibrator::CAP_COMPOSE_EFFECTS) == 0) {
+BENCHMARK_WRAPPER(SlowVibratorPrimitivesBench_Aidl, compose, {
+    if (!hasCapabilities(Aidl::IVibrator::CAP_COMPOSE_EFFECTS)) {
         state.SkipWithMessage("compose effects unavailable");
         return;
     }
@@ -574,22 +786,33 @@
     effect.scale = 1.0f;
     effect.delayMs = 0;
 
-    std::vector<Aidl::CompositePrimitive> supported;
-    mVibrator->getSupportedPrimitives(&supported);
-    if (std::find(supported.begin(), supported.end(), effect.primitive) == supported.end()) {
-        state.SkipWithMessage("supported primitives unavailable");
+    if (effect.primitive == Aidl::CompositePrimitive::NOOP) {
+        state.SkipWithMessage("skipping primitive NOOP");
+        return;
+    }
+    if (!isPrimitiveSupported(effect.primitive)) {
+        state.SkipWithMessage("primitive unsupported");
         return;
     }
 
-    auto cb = new HalCallback();
     std::vector<Aidl::CompositeEffect> effects;
     effects.push_back(effect);
 
     for (auto _ : state) {
-        state.ResumeTiming();
-        mVibrator->compose(effects, cb);
+        auto cb = new HalCallback();
+
+        // Test
+        if (shouldSkipWithError(state, mVibrator->compose(effects, cb))) {
+            return;
+        }
+
+        // Cleanup
         state.PauseTiming();
-        mVibrator->off();
+        if (shouldSkipWithError(state, mVibrator->off())) {
+            return;
+        }
+        cb->waitForComplete();
+        state.ResumeTiming();
     }
 });
 
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index d9e023c..d82450e 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -525,6 +525,7 @@
     return true;
 }
 
+// Only use to prepare parameters for Gscan.
 legacy_hal::wifi_band convertAidlWifiBandToLegacy(WifiBand band) {
     switch (band) {
         case WifiBand::BAND_UNSPECIFIED:
@@ -541,6 +542,15 @@
             return legacy_hal::WIFI_BAND_ABG;
         case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
             return legacy_hal::WIFI_BAND_ABG_WITH_DFS;
+        case WifiBand::BAND_6GHZ:
+        case WifiBand::BAND_60GHZ:
+        case WifiBand::BAND_5GHZ_6GHZ:
+        case WifiBand::BAND_24GHZ_5GHZ_6GHZ:
+        case WifiBand::BAND_24GHZ_5GHZ_6GHZ_60GHZ:
+        case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ:
+        case WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ:
+            LOG(INFO) << "WifiBand mapping may be incorrect, since 6GHz is not supported by legacy";
+            return legacy_hal::WIFI_BAND_UNSPECIFIED;
         default:
             CHECK(false);
             return {};
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index cf86120..bd92a20 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -2012,7 +2012,7 @@
 }
 
 wifi_error WifiLegacyHal::setScanMode(const std::string& iface_name, bool enable) {
-    return global_func_table_.wifi_set_scan_mode(iface_name.c_str(), enable);
+    return global_func_table_.wifi_set_scan_mode(getIfaceHandle(iface_name), enable);
 }
 
 wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) {
diff --git a/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h b/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
index e770777..9baa2c7 100644
--- a/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
+++ b/wifi/legacy_headers/include/hardware_legacy/wifi_hal.h
@@ -715,7 +715,7 @@
 
 /* Wi-Fi coex channel avoidance support */
 
-#define WIFI_COEX_NO_POWER_CAP (int32_t)0x7FFFFFF
+#define WIFI_COEX_NO_POWER_CAP (int32_t)0x7FFFFFFF
 
 typedef enum {
     WIFI_AWARE = 1 << 0,
@@ -1386,7 +1386,7 @@
      * @param enable true if current is scan only mode
      * @return Synchronous wifi_error
      */
-    wifi_error (*wifi_set_scan_mode)(const char * ifname, bool enable);
+    wifi_error (*wifi_set_scan_mode)(wifi_interface_handle iface, bool enable);
 
     wifi_error (*wifi_nan_pairing_end)(transaction_id id,
                                     wifi_interface_handle iface,