Split rkp from keymint am: 3a810627e0

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

Change-Id: I5e8f26453df36b92beac2915230822ad33174a8f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/audio/README.md b/audio/README.md
index 3f40d72..1938ad4 100644
--- a/audio/README.md
+++ b/audio/README.md
@@ -2,29 +2,10 @@
 
 Directory structure of the audio HAL related code.
 
-## Directory Structure for AIDL audio HAL
+Run `common/all-versions/copyHAL.sh` to create a new version of the audio HAL
+based on an existing one.
 
-The AIDL version is located inside `aidl` directory. The tree below explains
-the role of each subdirectory:
-
-* `aidl_api` — snapshots of the API created each Android release. Every
-  release, the current version of the API becomes "frozen" and gets assigned
-  the next version number. If the API needs further modifications, they are
-  made on the "current" version. After making modifications, run
-  `m <package name>-update-api` to update the snapshot of the "current"
-  version.
-* `android/hardware/audio/common` — data structures and interfaces shared
-  between various HALs: BT HAL, core and effects audio HALs.
-* `android/hardware/audio/core` — data structures and interfaces of the
-  core audio HAL.
-* `default` — the default, reference implementation of the audio HAL service.
-* `vts` — VTS tests for the AIDL HAL.
-
-## Directory Structure for HIDL audio HAL
-
-Run `common/all-versions/copyHAL.sh` to create a new version of the HIDL audio
-HAL based on an existing one. Note that this isn't possible since Android T
-release. Android U and above uses AIDL audio HAL.
+## Directory Structure
 
 * `2.0` — version 2.0 of the core HIDL API. Note that `.hal` files
   can not be moved into the `core` directory because that would change
diff --git a/audio/effect/all-versions/default/Effect.cpp b/audio/effect/all-versions/default/Effect.cpp
index 3baafc9..b57dc63 100644
--- a/audio/effect/all-versions/default/Effect.cpp
+++ b/audio/effect/all-versions/default/Effect.cpp
@@ -238,12 +238,27 @@
 }
 
 // static
-std::vector<uint8_t> Effect::parameterToHal(uint32_t paramSize, const void* paramData,
-                                            uint32_t valueSize, const void** valueData) {
+bool Effect::parameterToHal(uint32_t paramSize, const void* paramData, uint32_t valueSize,
+                            const void** valueData, std::vector<uint8_t>* halParamBuffer) {
+    constexpr size_t kMaxSize = EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t);
+    if (paramSize > kMaxSize) {
+        ALOGE("%s: Parameter size is too big: %" PRIu32, __func__, paramSize);
+        return false;
+    }
     size_t valueOffsetFromData = alignedSizeIn<uint32_t>(paramSize) * sizeof(uint32_t);
+    if (valueOffsetFromData > kMaxSize) {
+        ALOGE("%s: Aligned parameter size is too big: %zu", __func__, valueOffsetFromData);
+        return false;
+    }
+    if (valueSize > kMaxSize - valueOffsetFromData) {
+        ALOGE("%s: Value size is too big: %" PRIu32 ", max size is %zu", __func__, valueSize,
+              kMaxSize - valueOffsetFromData);
+        android_errorWriteLog(0x534e4554, "237291425");
+        return false;
+    }
     size_t halParamBufferSize = sizeof(effect_param_t) + valueOffsetFromData + valueSize;
-    std::vector<uint8_t> halParamBuffer(halParamBufferSize, 0);
-    effect_param_t* halParam = reinterpret_cast<effect_param_t*>(&halParamBuffer[0]);
+    halParamBuffer->resize(halParamBufferSize, 0);
+    effect_param_t* halParam = reinterpret_cast<effect_param_t*>(halParamBuffer->data());
     halParam->psize = paramSize;
     halParam->vsize = valueSize;
     memcpy(halParam->data, paramData, paramSize);
@@ -256,7 +271,7 @@
             *valueData = halParam->data + valueOffsetFromData;
         }
     }
-    return halParamBuffer;
+    return true;
 }
 
 Result Effect::analyzeCommandStatus(const char* commandName, const char* context, status_t status) {
@@ -301,6 +316,11 @@
 
 Result Effect::getCurrentConfigImpl(uint32_t featureId, uint32_t configSize,
                                     GetCurrentConfigSuccessCallback onSuccess) {
+    if (configSize > kMaxDataSize - sizeof(uint32_t)) {
+        ALOGE("%s: Config size is too big: %" PRIu32, __func__, configSize);
+        android_errorWriteLog(0x534e4554, "240266798");
+        return Result::INVALID_ARGUMENTS;
+    }
     uint32_t halCmd = featureId;
     std::vector<uint32_t> halResult(alignedSizeIn<uint32_t>(sizeof(uint32_t) + configSize), 0);
     uint32_t halResultSize = 0;
@@ -314,11 +334,15 @@
                                 GetParameterSuccessCallback onSuccess) {
     // As it is unknown what method HAL uses for copying the provided parameter data,
     // it is safer to make sure that input and output buffers do not overlap.
-    std::vector<uint8_t> halCmdBuffer =
-        parameterToHal(paramSize, paramData, requestValueSize, nullptr);
+    std::vector<uint8_t> halCmdBuffer;
+    if (!parameterToHal(paramSize, paramData, requestValueSize, nullptr, &halCmdBuffer)) {
+        return Result::INVALID_ARGUMENTS;
+    }
     const void* valueData = nullptr;
-    std::vector<uint8_t> halParamBuffer =
-        parameterToHal(paramSize, paramData, replyValueSize, &valueData);
+    std::vector<uint8_t> halParamBuffer;
+    if (!parameterToHal(paramSize, paramData, replyValueSize, &valueData, &halParamBuffer)) {
+        return Result::INVALID_ARGUMENTS;
+    }
     uint32_t halParamBufferSize = halParamBuffer.size();
 
     return sendCommandReturningStatusAndData(
@@ -331,8 +355,12 @@
 
 Result Effect::getSupportedConfigsImpl(uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
                                        GetSupportedConfigsSuccessCallback onSuccess) {
+    if (maxConfigs != 0 && configSize > (kMaxDataSize - 2 * sizeof(uint32_t)) / maxConfigs) {
+        ALOGE("%s: Config size is too big: %" PRIu32, __func__, configSize);
+        return Result::INVALID_ARGUMENTS;
+    }
     uint32_t halCmd[2] = {featureId, maxConfigs};
-    uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * sizeof(configSize);
+    uint32_t halResultSize = 2 * sizeof(uint32_t) + maxConfigs * configSize;
     std::vector<uint8_t> halResult(static_cast<size_t>(halResultSize), 0);
     return sendCommandReturningStatusAndData(
         EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS, "GET_FEATURE_SUPPORTED_CONFIGS", sizeof(halCmd),
@@ -472,8 +500,10 @@
 
 Result Effect::setParameterImpl(uint32_t paramSize, const void* paramData, uint32_t valueSize,
                                 const void* valueData) {
-    std::vector<uint8_t> halParamBuffer =
-        parameterToHal(paramSize, paramData, valueSize, &valueData);
+    std::vector<uint8_t> halParamBuffer;
+    if (!parameterToHal(paramSize, paramData, valueSize, &valueData, &halParamBuffer)) {
+        return Result::INVALID_ARGUMENTS;
+    }
     return sendCommandReturningStatus(EFFECT_CMD_SET_PARAM, "SET_PARAM", halParamBuffer.size(),
                                       &halParamBuffer[0]);
 }
diff --git a/audio/effect/all-versions/default/Effect.h b/audio/effect/all-versions/default/Effect.h
index 011544d..5d8dccc 100644
--- a/audio/effect/all-versions/default/Effect.h
+++ b/audio/effect/all-versions/default/Effect.h
@@ -184,6 +184,9 @@
     using GetSupportedConfigsSuccessCallback =
         std::function<void(uint32_t supportedConfigs, void* configsData)>;
 
+    // Sets the limit on the maximum size of vendor-provided data structures.
+    static constexpr size_t kMaxDataSize = 1 << 20;
+
     static const char* sContextResultOfCommand;
     static const char* sContextCallToCommand;
     static const char* sContextCallFunction;
@@ -211,8 +214,8 @@
                                              channel_config_t* halConfig);
     static void effectOffloadParamToHal(const EffectOffloadParameter& offload,
                                         effect_offload_param_t* halOffload);
-    static std::vector<uint8_t> parameterToHal(uint32_t paramSize, const void* paramData,
-                                               uint32_t valueSize, const void** valueData);
+    static bool parameterToHal(uint32_t paramSize, const void* paramData, uint32_t valueSize,
+                               const void** valueData, std::vector<uint8_t>* halParamBuffer);
 
     Result analyzeCommandStatus(const char* commandName, const char* context, status_t status);
     void getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb);
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index e59423f..d95bb06 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -35,6 +35,7 @@
 
 #include <common/all-versions/VersionUtils.h>
 
+#include <cutils/properties.h>
 #include <gtest/gtest.h>
 #include <hidl/GtestPrinter.h>
 #include <hidl/ServiceManagement.h>
@@ -623,6 +624,27 @@
     EXPECT_TRUE(ret.isOk());
 }
 
+TEST_P(AudioEffectHidlTest, GetParameterInvalidMaxReplySize) {
+    description("Verify that GetParameter caps the maximum reply size");
+    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+    if (!isNewDeviceLaunchingOnTPlus) {
+        GTEST_SKIP() << "The test only applies to devices launching on T or later";
+    }
+    // Use a non-empty parameter to avoid being rejected by any earlier checks.
+    hidl_vec<uint8_t> parameter;
+    parameter.resize(16);
+    // Use very large size to ensure that the service does not crash. Since parameters
+    // are specific to each effect, and some effects may not have parameters at all,
+    // simply checking the return value would not reveal an issue of using an uncapped value.
+    const uint32_t veryLargeReplySize = std::numeric_limits<uint32_t>::max() - 100;
+    Result retval = Result::OK;
+    Return<void> ret =
+            effect->getParameter(parameter, veryLargeReplySize,
+                                 [&](Result r, const hidl_vec<uint8_t>&) { retval = r; });
+    EXPECT_TRUE(ret.isOk());
+    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
 TEST_P(AudioEffectHidlTest, GetSupportedConfigsForFeature) {
     description("Verify that GetSupportedConfigsForFeature does not crash");
     Return<void> ret = effect->getSupportedConfigsForFeature(
@@ -643,6 +665,37 @@
     EXPECT_TRUE(ret.isOk());
 }
 
+TEST_P(AudioEffectHidlTest, GetSupportedConfigsForFeatureInvalidConfigSize) {
+    description("Verify that GetSupportedConfigsForFeature caps the maximum config size");
+    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+    if (!isNewDeviceLaunchingOnTPlus) {
+        GTEST_SKIP() << "The test only applies to devices launching on T or later";
+    }
+    // Use very large size to ensure that the service does not crash.
+    const uint32_t veryLargeConfigSize = std::numeric_limits<uint32_t>::max() - 100;
+    Result retval = Result::OK;
+    Return<void> ret = effect->getSupportedConfigsForFeature(
+            0, 1, veryLargeConfigSize,
+            [&](Result r, uint32_t, const hidl_vec<uint8_t>&) { retval = r; });
+    EXPECT_TRUE(ret.isOk());
+    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
+TEST_P(AudioEffectHidlTest, GetCurrentConfigForFeatureInvalidConfigSize) {
+    description("Verify that GetCurrentConfigForFeature caps the maximum config size");
+    const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+    if (!isNewDeviceLaunchingOnTPlus) {
+        GTEST_SKIP() << "The test only applies to devices launching on T or later";
+    }
+    // Use very large size to ensure that the service does not crash.
+    const uint32_t veryLargeConfigSize = std::numeric_limits<uint32_t>::max() - 100;
+    Result retval = Result::OK;
+    Return<void> ret = effect->getCurrentConfigForFeature(
+            0, veryLargeConfigSize, [&](Result r, const hidl_vec<uint8_t>&) { retval = r; });
+    EXPECT_TRUE(ret.isOk());
+    EXPECT_EQ(Result::INVALID_ARGUMENTS, retval);
+}
+
 // The main test class for Equalizer Audio Effect HIDL HAL.
 class EqualizerAudioEffectHidlTest : public AudioEffectHidlTest {
   public:
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
index ebff98f..3abdb54 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
@@ -33,7 +33,9 @@
     @utf8InCpp
     String deviceId;
     /**
-     * Possible additional vendor information that is opaque to the EvsManager
+     * Possible additional vendor information that is opaque to the EvsManager.
+     * The size of the payload must not exceed 16-byte if the HIDL recipients are
+     * expected to exist.
      */
     int[] payload;
 }
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
index 2c2b44c..c599d58 100644
--- a/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
+++ b/automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl
@@ -47,7 +47,10 @@
     /**
      * Receives calls from the HAL each time an event happens.
      *
-     * @param in event EVS event with possible event information.
+     * @param in event EVS event with possible event information.  If ths HIDL
+     *                 recipients are expected to exist, the size of the event
+     *                 payload must not exceed 16 bytes; otherwise, a notification
+     *                 will not reach them.
      */
     void notify(in EvsEventDesc event);
 }
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 0d3253b..33e211c 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -84,7 +84,10 @@
     name: "android.hardware.automotive.vehicle@2.0-default-impl-lib",
     vendor: true,
     defaults: ["vhal_v2_0_target_defaults"],
-    cflags: ["-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING"],
+    cflags: [
+        "-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING",
+        "-DENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS",
+    ],
     srcs: [
         "impl/vhal_v2_0/DefaultVehicleHal.cpp",
         "impl/vhal_v2_0/VehicleHalClient.cpp",
@@ -225,6 +228,25 @@
     test_suites: ["general-tests"],
 }
 
+cc_test {
+    name: "android.hardware.automotive.vehicle@2.0-default-config-test",
+    vendor: true,
+    defaults: ["vhal_v2_0_target_defaults"],
+    srcs: [
+        "impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp",
+    ],
+    cflags: [
+        "-DENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING",
+        "-DENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS",
+    ],
+    static_libs: [
+        "android.hardware.automotive.vehicle@2.0-default-impl-lib",
+        "libgtest",
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+}
+
 cc_binary {
     name: "android.hardware.automotive.vehicle@2.0-default-service",
     defaults: ["vhal_v2_0_target_defaults"],
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 cfbbbd3..55a7720 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
@@ -1109,6 +1109,19 @@
                         },
                 .initialValue = {.stringValue = {"Test"}},
         },
+        // This property is later defined in the AIDL VHAL interface. However, HIDL VHAL might
+        // require support for this property to meet EU regulation.
+        {
+                .config =
+                        {
+                                // GENERAL_SAFETY_REGULATION_COMPLIANCE_REQUIREMENT
+                                .prop = 0x11400F47,
+                                .access = VehiclePropertyAccess::READ,
+                                .changeMode = VehiclePropertyChangeMode::STATIC,
+                        },
+                // GsrComplianceRequirementType::GSR_COMPLIANCE_REQUIRED_V1
+                .initialValue = {.int32Values = {1}},
+        },
 #ifdef ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
         // Vendor propetry for E2E ClusterHomeService testing.
         {
@@ -1157,6 +1170,46 @@
                         },
         },
 #endif  // ENABLE_VENDOR_CLUSTER_PROPERTY_FOR_TESTING
+#ifdef ENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS
+        {
+                .config =
+                        {
+                                // VHAL_SUPPORTED_PROPERTY_IDS
+                                .prop = 289476424,
+                                .access = VehiclePropertyAccess::READ,
+                                .changeMode = VehiclePropertyChangeMode::STATIC,
+                                // Fetch 100 configs in one request. This number is just arbitrarily
+                                // chosen here. But some HAL impl with bigger config data may need a
+                                // smaller number.
+                                .configArray = {100},
+                        },
+                // All supported property IDs. This list is checked by
+                // DefaultConfigSupportedPropertyIds_test.
+                .initialValue =
+                        {.int32Values =
+                                 {291504388, 289472773, 291504390, 289472775, 289407240, 289407241,
+                                  289472780, 286261505, 286261506, 289407235, 289472779, 291504647,
+                                  289408517, 356518832, 356516106, 291504644, 291504649, 291504656,
+                                  291504901, 291504903, 287310600, 291504905, 287310602, 287310603,
+                                  291504908, 291504904, 392168201, 392168202, 289408514, 289408001,
+                                  287310850, 287310851, 287310853, 289475088, 289475104, 289475120,
+                                  354419984, 320865540, 320865556, 354419975, 354419976, 354419986,
+                                  354419973, 354419974, 354419978, 354419977, 356517120, 356517121,
+                                  356582673, 356517139, 289408269, 356517131, 358614275, 291570965,
+                                  291505923, 289408270, 289408512, 287310855, 289408000, 289408008,
+                                  289408009, 289407747, 291504900, 568332561, 371198722, 373295872,
+                                  320867268, 322964416, 290521862, 287310858, 287310859, 289475072,
+                                  289475073, 289409539, 299896064, 299896065, 299896066, 299896067,
+                                  289410560, 289410561, 289410562, 289410563, 289410576, 289410577,
+                                  289410578, 289410579, 289476368, 299895808, 639631617, 627048706,
+                                  591397123, 554696964, 289410873, 289410874, 287313669, 299896583,
+                                  299896584, 299896585, 299896586, 299896587, 286265121, 286265122,
+                                  286265123, 290457094, 290459441, 299896626, 290459443, 289410868,
+                                  289476405, 299896630, 289410871, 292556600, 557853201, 559950353,
+                                  555756049, 554707473, 289410887, 557846324, 557911861, 568332086,
+                                  557846327, 560992056, 289476424}},
+        },
+#endif  // ENABLE_GET_PROP_CONFIGS_BY_MULTIPLE_REQUESTS
 };
 
 }  // impl
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp
new file mode 100644
index 0000000..aa05daa
--- /dev/null
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <vector>
+
+#include "vhal_v2_0/DefaultConfig.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace impl {
+
+using ::testing::ElementsAreArray;
+
+// Test that VHAL_SUPPORTED_PROPERTY_IDS contains all supported property IDs.
+TEST(DefaultConfigSupportedPropertyIdsTest, testIncludeAllSupportedIds) {
+    const int32_t vhalSupportedPropertyIdsPropId = 289476424;
+
+    std::vector<int32_t> allSupportedIds;
+    std::vector<int32_t> configuredSupportedIds;
+
+    for (const auto& property : impl::kVehicleProperties) {
+        int propId = property.config.prop;
+        allSupportedIds.push_back(propId);
+
+        if (propId == vhalSupportedPropertyIdsPropId) {
+            configuredSupportedIds = property.initialValue.int32Values;
+        }
+    }
+
+    ASSERT_THAT(allSupportedIds, ElementsAreArray(configuredSupportedIds));
+}
+
+}  // namespace impl
+}  // namespace V2_0
+}  // namespace vehicle
+}  // namespace automotive
+}  // namespace hardware
+}  // namespace android
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
index e3c8dd6..25a1940 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
@@ -141,7 +141,7 @@
 TEST_F(DefaultVhalImplTest, testListProperties) {
     std::vector<VehiclePropConfig> configs = mHal->listProperties();
 
-    EXPECT_EQ((size_t)121, configs.size());
+    EXPECT_EQ((size_t)123, configs.size());
 }
 
 TEST_F(DefaultVhalImplTest, testGetDefaultPropertyFloat) {
diff --git a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
index 65cd795..9a93e1a 100644
--- a/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
+++ b/automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h
@@ -40,6 +40,7 @@
 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
 using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
+using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
 using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
 using ::aidl::android::hardware::automotive::vehicle::VehicleGear;
 using ::aidl::android::hardware::automotive::vehicle::VehicleHvacFanDirection;
@@ -180,6 +181,523 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::EV_BATTERY_DISPLAY_UNITS),
+                         .access = VehiclePropertyAccess::READ_WRITE,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                         .configArray = {toInt(VehicleUnit::WATT_HOUR),
+                                         toInt(VehicleUnit::AMPERE_HOURS),
+                                         toInt(VehicleUnit::KILOWATT_HOUR)},
+                 },
+         .initialValue = {.int32Values = {toInt(VehicleUnit::KILOWATT_HOUR)}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_BUCKLED),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+                               {SEAT_1_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_LEFT, {.int32Values = {0}}},
+                               {SEAT_2_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_HEIGHT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {10}}},
+                               {SEAT_1_RIGHT, {.int32Values = {10}}},
+                               {SEAT_2_LEFT, {.int32Values = {10}}},
+                               {SEAT_2_RIGHT, {.int32Values = {10}}},
+                               {SEAT_2_CENTER, {.int32Values = {10}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BELT_HEIGHT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+                               {SEAT_1_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_LEFT, {.int32Values = {0}}},
+                               {SEAT_2_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_FORE_AFT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+                               {SEAT_1_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_LEFT, {.int32Values = {0}}},
+                               {SEAT_2_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_FORE_AFT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+                               {SEAT_1_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_LEFT, {.int32Values = {0}}},
+                               {SEAT_2_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_1_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+                               {SEAT_1_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_LEFT, {.int32Values = {0}}},
+                               {SEAT_2_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_1_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+                               {SEAT_1_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_LEFT, {.int32Values = {0}}},
+                               {SEAT_2_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_2_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+                               {SEAT_1_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_LEFT, {.int32Values = {0}}},
+                               {SEAT_2_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_BACKREST_ANGLE_2_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialAreaValues = {{SEAT_1_LEFT, {.int32Values = {0}}},
+                               {SEAT_1_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_LEFT, {.int32Values = {0}}},
+                               {SEAT_2_RIGHT, {.int32Values = {0}}},
+                               {SEAT_2_CENTER, {.int32Values = {0}}}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_HEIGHT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_HEIGHT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_DEPTH_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_DEPTH_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_TILT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_TILT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_FORE_AFT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -10,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_FORE_AFT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_LUMBAR_SIDE_SUPPORT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_HEIGHT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_ANGLE_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_ANGLE_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_FORE_AFT_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = 0,
+                                                      .maxInt32Value = 10}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::SEAT_HEADREST_FORE_AFT_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::SEAT_OCCUPANCY),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -359,8 +877,9 @@
                          .prop = toInt(VehicleProperty::VEHICLE_CURB_WEIGHT),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::STATIC,
+                         .configArray = {/*gross weight kg=*/2948},
                  },
-         .initialValue = {.int32Values = {30}}},
+         .initialValue = {.int32Values = {2211 /*kg*/}}},
 
         {.config =
                  {
@@ -467,6 +986,24 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::FUEL_VOLUME_DISPLAY_UNITS),
+                         .access = VehiclePropertyAccess::READ_WRITE,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                         .configArray = {(int)VehicleUnit::LITER, (int)VehicleUnit::US_GALLON},
+                 },
+         .initialValue = {.int32Values = {(int)VehicleUnit::LITER}}},
+
+        {.config =
+                 {
+                         .prop = toInt(
+                                 VehicleProperty::FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME),
+                         .access = VehiclePropertyAccess::READ_WRITE,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                 },
+         .initialValue = {.int32Values = {1}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::HW_KEY_INPUT),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -493,6 +1030,12 @@
                          .int32Values = {0, 0, 0},
                  }},
 
+        {.config = {.prop = toInt(VehicleProperty::HVAC_ACTUAL_FAN_SPEED_RPM),
+                    .access = VehiclePropertyAccess::READ,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_ALL}}},
+         .initialValue = {.int32Values = {50}}},
+
         {.config = {.prop = toInt(VehicleProperty::HVAC_POWER_ON),
                     .access = VehiclePropertyAccess::READ_WRITE,
                     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -630,6 +1173,25 @@
                                     }}},
          .initialValue = {.int32Values = {0}}},  // +ve values for heating and -ve for cooling
 
+        {.config = {.prop = toInt(VehicleProperty::HVAC_SIDE_MIRROR_HEAT),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{
+                            .areaId = toInt(VehicleAreaMirror::DRIVER_LEFT) |
+                                      toInt(VehicleAreaMirror::DRIVER_RIGHT),
+                            .minInt32Value = 0,
+                            .maxInt32Value = 2,
+                    }}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_CURRENT),
+                    .access = VehiclePropertyAccess::READ,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = HVAC_LEFT},
+                                    VehicleAreaConfig{.areaId = HVAC_RIGHT}}},
+         .initialAreaValues = {{HVAC_LEFT, {.floatValues = {17.3f}}},
+                               {HVAC_RIGHT, {.floatValues = {19.1f}}}}},
+
         {.config = {.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET),
                     .access = VehiclePropertyAccess::READ_WRITE,
                     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -722,6 +1284,16 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::ENGINE_COOLANT_TEMP),
+                         .access = VehiclePropertyAccess::READ,
+                         .changeMode = VehiclePropertyChangeMode::CONTINUOUS,
+                         .minSampleRate = 1.0f,
+                         .maxSampleRate = 10.0f,
+                 },
+         .initialValue = {.floatValues = {75.0f}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::ENGINE_OIL_LEVEL),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -781,6 +1353,76 @@
                                      .areaId = DOOR_REAR, .minInt32Value = 0, .maxInt32Value = 1}}},
          .initialValue = {.int32Values = {0}}},
 
+        {.config = {.prop = toInt(VehicleProperty::MIRROR_Z_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs =
+                            {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+                                               .minInt32Value = -3,
+                                               .maxInt32Value = 3},
+                             VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+                                               .minInt32Value = -3,
+                                               .maxInt32Value = 3},
+                             VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
+                                               .minInt32Value = -3,
+                                               .maxInt32Value = 3}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::MIRROR_Z_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs =
+                            {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+                                               .minInt32Value = -1,
+                                               .maxInt32Value = 1},
+                             VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+                                               .minInt32Value = -1,
+                                               .maxInt32Value = 1},
+                             VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
+                                               .minInt32Value = -1,
+                                               .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::MIRROR_Y_POS),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs =
+                            {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+                                               .minInt32Value = -3,
+                                               .maxInt32Value = 3},
+                             VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+                                               .minInt32Value = -3,
+                                               .maxInt32Value = 3},
+                             VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
+                                               .minInt32Value = -3,
+                                               .maxInt32Value = 3}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::MIRROR_Y_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs =
+                            {VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_LEFT),
+                                               .minInt32Value = -1,
+                                               .maxInt32Value = 1},
+                             VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_RIGHT),
+                                               .minInt32Value = -1,
+                                               .maxInt32Value = 1},
+                             VehicleAreaConfig{.areaId = toInt(VehicleAreaMirror::DRIVER_CENTER),
+                                               .minInt32Value = -1,
+                                               .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
+        {.config = {.prop = toInt(VehicleProperty::MIRROR_LOCK),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
+         .initialValue = {.int32Values = {1}}},
+
+        {.config = {.prop = toInt(VehicleProperty::MIRROR_FOLD),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE},
+         .initialValue = {.int32Values = {1}}},
+
         {.config = {.prop = toInt(VehicleProperty::WINDOW_LOCK),
                     .access = VehiclePropertyAccess::READ_WRITE,
                     .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -809,6 +1451,26 @@
                                                       .maxInt32Value = 10}}},
          .initialValue = {.int32Values = {0}}},
 
+        {.config = {.prop = toInt(VehicleProperty::WINDOW_MOVE),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = WINDOW_1_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = WINDOW_1_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = WINDOW_2_LEFT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = WINDOW_2_RIGHT,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1},
+                                    VehicleAreaConfig{.areaId = WINDOW_ROOF_TOP_1,
+                                                      .minInt32Value = -1,
+                                                      .maxInt32Value = 1}}},
+         .initialValue = {.int32Values = {0}}},
+
         {.config =
                  {
                          .prop = WHEEL_TICK,
@@ -891,14 +1553,6 @@
 
         {.config =
                  {
-                         .prop = toInt(VehicleProperty::FOG_LIGHTS_STATE),
-                         .access = VehiclePropertyAccess::READ,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
-
-        {.config =
-                 {
                          .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_STATE),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -923,6 +1577,24 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::CABIN_LIGHTS_STATE),
+                         .access = VehiclePropertyAccess::READ,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                 },
+         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+        {.config = {.prop = toInt(VehicleProperty::READING_LIGHTS_STATE),
+                    .access = VehiclePropertyAccess::READ,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
+         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::HEADLIGHTS_SWITCH),
                          .access = VehiclePropertyAccess::READ_WRITE,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
@@ -937,14 +1609,7 @@
                  },
          .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
 
-        {.config =
-                 {
-                         .prop = toInt(VehicleProperty::FOG_LIGHTS_SWITCH),
-                         .access = VehiclePropertyAccess::READ_WRITE,
-                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
-                 },
-         .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
-
+        // FOG_LIGHTS_SWITCH must not be implemented when FRONT_FOG_LIGHTS_SWITCH is implemented
         {.config =
                  {
                          .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_SWITCH),
@@ -953,6 +1618,7 @@
                  },
          .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
 
+        // FOG_LIGHTS_SWITCH must not be implemented when REAR_FOG_LIGHTS_SWITCH is implemented
         {.config =
                  {
                          .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_SWITCH),
@@ -971,6 +1637,24 @@
 
         {.config =
                  {
+                         .prop = toInt(VehicleProperty::CABIN_LIGHTS_SWITCH),
+                         .access = VehiclePropertyAccess::READ_WRITE,
+                         .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                 },
+         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+        {.config = {.prop = toInt(VehicleProperty::READING_LIGHTS_SWITCH),
+                    .access = VehiclePropertyAccess::READ_WRITE,
+                    .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+                    .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT},
+                                    VehicleAreaConfig{.areaId = SEAT_1_RIGHT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_LEFT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_RIGHT},
+                                    VehicleAreaConfig{.areaId = SEAT_2_CENTER}}},
+         .initialValue = {.int32Values = {LIGHT_STATE_ON}}},
+
+        {.config =
+                 {
                          .prop = toInt(VehicleProperty::EVS_SERVICE_REQUEST),
                          .access = VehiclePropertyAccess::READ,
                          .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
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 b64c1a6..20c34aa 100644
--- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
+++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp
@@ -217,17 +217,16 @@
             [[fallthrough]];
         case toInt(VehicleApPowerStateReport::WAIT_FOR_VHAL):
             // CPMS is in WAIT_FOR_VHAL state, simply move to ON and send back to HAL.
-            // Must erase existing state because in the case when Car Service crashes, the power
-            // state would already be ON when we receive WAIT_FOR_VHAL and thus new property change
-            // event would be generated. However, Car Service always expect a property change event
-            // even though there is not actual state change.
-            mServerSidePropStore->removeValuesForProperty(
-                    toInt(VehicleProperty::AP_POWER_STATE_REQ));
             prop = createApPowerStateReq(VehicleApPowerStateReq::ON);
 
-            // ALWAYS update status for generated property value
+            // ALWAYS update status for generated property value, and force a property update event
+            // because in the case when Car Service crashes, the power state would already be ON
+            // when we receive WAIT_FOR_VHAL and thus new property change event would be generated.
+            // However, Car Service always expect a property change event even though there is no
+            // actual state change.
             if (auto writeResult =
-                        mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true);
+                        mServerSidePropStore->writeValue(std::move(prop), /*updateStatus=*/true,
+                                                         VehiclePropertyStore::EventMode::ALWAYS);
                 !writeResult.ok()) {
                 return StatusError(getErrorCode(writeResult))
                        << "failed to write AP_POWER_STATE_REQ into property store, error: "
@@ -894,10 +893,10 @@
             return;
         }
         result.value()->timestamp = elapsedRealtimeNano();
-        // Must remove the value before writing, otherwise, we would generate no update event since
-        // the value is the same.
-        mServerSidePropStore->removeValue(*result.value());
-        mServerSidePropStore->writeValue(std::move(result.value()));
+        // For continuous properties, we must generate a new onPropertyChange event periodically
+        // according to the sample rate.
+        mServerSidePropStore->writeValue(std::move(result.value()), /*updateStatus=*/true,
+                                         VehiclePropertyStore::EventMode::ALWAYS);
     });
     mRecurrentTimer->registerTimerCallback(interval, action);
     mRecurrentActions[propIdAreaId] = action;
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index a7fcdcf..8bc3c20 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
@@ -42,6 +42,7 @@
 #include <aidl/android/hardware/automotive/vehicle/VehicleApPowerStateReq.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleArea.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleAreaDoor.h>
+#include <aidl/android/hardware/automotive/vehicle/VehicleAreaMirror.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleAreaSeat.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleAreaWheel.h>
 #include <aidl/android/hardware/automotive/vehicle/VehicleAreaWindow.h>
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
index ddc4f68..3d25cd3 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h
@@ -46,6 +46,33 @@
     using ValueResultType = VhalResult<VehiclePropValuePool::RecyclableType>;
     using ValuesResultType = VhalResult<std::vector<VehiclePropValuePool::RecyclableType>>;
 
+    enum class EventMode : uint8_t {
+        /**
+         * Only invoke OnValueChangeCallback if the new property value (ignoring timestamp) is
+         * different than the existing value.
+         *
+         * This should be used for regular cases.
+         */
+        ON_VALUE_CHANGE,
+        /**
+         * Always invoke OnValueChangeCallback.
+         *
+         * This should be used for the special properties that are used for delivering event, e.g.
+         * HW_KEY_INPUT.
+         */
+        ALWAYS,
+        /**
+         * Never invoke OnValueChangeCallback.
+         *
+         * This should be used for continuous property subscription when the sample rate for the
+         * subscription is smaller than the refresh rate for the property. E.g., the vehicle speed
+         * is refreshed at 20hz, but we are only subscribing at 10hz. In this case, we want to
+         * generate the property change event at 10hz, not 20hz, but we still want to refresh the
+         * timestamp (via writeValue) at 20hz.
+         */
+        NEVER,
+    };
+
     explicit VehiclePropertyStore(std::shared_ptr<VehiclePropValuePool> valuePool)
         : mValuePool(valuePool) {}
 
@@ -72,8 +99,10 @@
     // 'status' would be initialized to {@code VehiclePropertyStatus::AVAILABLE}, if this is to
     // override an existing value, the status for the existing value would be used for the
     // overridden value.
+    // 'EventMode' controls whether the 'OnValueChangeCallback' will be called for this operation.
     VhalResult<void> writeValue(VehiclePropValuePool::RecyclableType propValue,
-                                bool updateStatus = false);
+                                bool updateStatus = false,
+                                EventMode mode = EventMode::ON_VALUE_CHANGE);
 
     // Remove a given property value from the property store. The 'propValue' would be used to
     // generate the key for the value to remove.
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
index 8521c4d..2eca6b7 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp
@@ -48,7 +48,7 @@
         std::scoped_lock<std::mutex> lockGuard(mLock);
 
         // Aligns the nextTime to multiply of interval.
-        int64_t nextTime = ceil(elapsedRealtimeNano() / intervalInNano) * intervalInNano;
+        int64_t nextTime = ceil(uptimeNanos() / intervalInNano) * intervalInNano;
 
         std::unique_ptr<CallbackInfo> info = std::make_unique<CallbackInfo>();
         info->callback = callback;
@@ -128,7 +128,7 @@
             }
             // The first element is the nearest next event.
             int64_t nextTime = mCallbackQueue[0]->nextTime;
-            int64_t now = elapsedRealtimeNano();
+            int64_t now = uptimeNanos();
             if (nextTime > now) {
                 interval = nextTime - now;
             } else {
@@ -146,7 +146,7 @@
 
         {
             ScopedLockAssertion lockAssertion(mLock);
-            int64_t now = elapsedRealtimeNano();
+            int64_t now = uptimeNanos();
             while (mCallbackQueue.size() > 0) {
                 int64_t nextTime = mCallbackQueue[0]->nextTime;
                 if (nextTime > now) {
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index c8fb994..646dc0e 100644
--- a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
@@ -106,7 +106,8 @@
 }
 
 VhalResult<void> VehiclePropertyStore::writeValue(VehiclePropValuePool::RecyclableType propValue,
-                                                  bool updateStatus) {
+                                                  bool updateStatus,
+                                                  VehiclePropertyStore::EventMode eventMode) {
     std::scoped_lock<std::mutex> g(mLock);
 
     int32_t propId = propValue->prop;
@@ -145,7 +146,12 @@
     }
 
     record->values[recId] = std::move(propValue);
-    if (valueUpdated && mOnValueChangeCallback != nullptr) {
+
+    if (eventMode == EventMode::NEVER) {
+        return {};
+    }
+
+    if ((eventMode == EventMode::ALWAYS || valueUpdated) && mOnValueChangeCallback != nullptr) {
         mOnValueChangeCallback(*(record->values[recId]));
     }
     return {};
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 4d6f811..fea5034 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
@@ -448,6 +448,67 @@
     ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
 }
 
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackNoUpdateForTimestampChange) {
+    VehiclePropValue updatedValue{
+            .prop = INVALID_PROP_ID,
+    };
+    VehiclePropValue fuelCapacity = {
+            .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+            .value = {.floatValues = {1.0}},
+    };
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+    mStore->setOnValueChangeCallback(
+            [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+
+    // Write the same value with different timestamp should succeed but should not trigger callback.
+    fuelCapacity.timestamp = 1;
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+    ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
+}
+
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackForceUpdate) {
+    VehiclePropValue updatedValue{
+            .prop = INVALID_PROP_ID,
+    };
+    VehiclePropValue fuelCapacity = {
+            .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+            .value = {.floatValues = {1.0}},
+    };
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+    mStore->setOnValueChangeCallback(
+            [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+
+    fuelCapacity.timestamp = 1;
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), /*updateStatus=*/false,
+                                        VehiclePropertyStore::EventMode::ALWAYS));
+
+    ASSERT_EQ(updatedValue, fuelCapacity);
+}
+
+TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackForceNoUpdate) {
+    VehiclePropValue updatedValue{
+            .prop = INVALID_PROP_ID,
+    };
+    VehiclePropValue fuelCapacity = {
+            .prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY),
+            .value = {.floatValues = {1.0}},
+    };
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity)));
+
+    mStore->setOnValueChangeCallback(
+            [&updatedValue](const VehiclePropValue& value) { updatedValue = value; });
+    fuelCapacity.value.floatValues[0] = 2.0;
+    fuelCapacity.timestamp = 1;
+
+    ASSERT_RESULT_OK(mStore->writeValue(mValuePool->obtain(fuelCapacity), /*updateStatus=*/false,
+                                        VehiclePropertyStore::EventMode::NEVER));
+
+    ASSERT_EQ(updatedValue.prop, INVALID_PROP_ID);
+}
+
 }  // namespace vehicle
 }  // namespace automotive
 }  // namespace hardware
diff --git a/bluetooth/audio/utils/Android.bp b/bluetooth/audio/utils/Android.bp
index 674dd11..70797a7 100644
--- a/bluetooth/audio/utils/Android.bp
+++ b/bluetooth/audio/utils/Android.bp
@@ -63,6 +63,31 @@
     generated_headers: ["le_audio_codec_capabilities"],
 }
 
+cc_test {
+    name: "BluetoothLeAudioCodecsProviderTest",
+    srcs: [
+        "aidl_session/BluetoothLeAudioCodecsProvider.cpp",
+        "aidl_session/BluetoothLeAudioCodecsProviderTest.cpp",
+    ],
+    header_libs: [
+        "libxsdc-utils",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "android.hardware.bluetooth.audio-V2-ndk",
+        "libxml2",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+    test_options: {
+        unit_test: false,
+    },
+    generated_sources: ["le_audio_codec_capabilities"],
+    generated_headers: ["le_audio_codec_capabilities"],
+}
+
 xsd_config {
     name: "le_audio_codec_capabilities",
     srcs: ["le_audio_codec_capabilities/le_audio_codec_capabilities.xsd"],
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
index 855dd28..faebbbf 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothAudioCodecs.cpp
@@ -398,8 +398,11 @@
   }
 
   if (kDefaultOffloadLeAudioCapabilities.empty()) {
+    auto le_audio_offload_setting =
+        BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile();
     kDefaultOffloadLeAudioCapabilities =
-        BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities();
+        BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
+            le_audio_offload_setting);
   }
 
   return kDefaultOffloadLeAudioCapabilities;
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
index bf49270..1dec900 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.cpp
@@ -34,20 +34,40 @@
 
 static std::vector<LeAudioCodecCapabilitiesSetting> leAudioCodecCapabilities;
 
-std::vector<LeAudioCodecCapabilitiesSetting>
-BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities() {
-  if (!leAudioCodecCapabilities.empty()) {
-    return leAudioCodecCapabilities;
-  }
+static bool isInvalidFileContent = false;
 
-  const auto le_audio_offload_setting =
+std::optional<setting::LeAudioOffloadSetting>
+BluetoothLeAudioCodecsProvider::ParseFromLeAudioOffloadSettingFile() {
+  if (!leAudioCodecCapabilities.empty() || isInvalidFileContent) {
+    return std::nullopt;
+  }
+  auto le_audio_offload_setting =
       setting::readLeAudioOffloadSetting(kLeAudioCodecCapabilitiesFile);
   if (!le_audio_offload_setting.has_value()) {
     LOG(ERROR) << __func__ << ": Failed to read "
                << kLeAudioCodecCapabilitiesFile;
+  }
+  return le_audio_offload_setting;
+}
+
+std::vector<LeAudioCodecCapabilitiesSetting>
+BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
+    const std::optional<setting::LeAudioOffloadSetting>&
+        le_audio_offload_setting) {
+  if (!leAudioCodecCapabilities.empty()) {
+    return leAudioCodecCapabilities;
+  }
+
+  if (!le_audio_offload_setting.has_value()) {
+    LOG(ERROR)
+        << __func__
+        << ": input le_audio_offload_setting content need to be non empty";
     return {};
   }
 
+  ClearLeAudioCodecCapabilities();
+  isInvalidFileContent = true;
+
   std::vector<setting::Scenario> supported_scenarios =
       GetScenarios(le_audio_offload_setting);
   if (supported_scenarios.empty()) {
@@ -79,9 +99,18 @@
 
   leAudioCodecCapabilities =
       ComposeLeAudioCodecCapabilities(supported_scenarios);
+  isInvalidFileContent = leAudioCodecCapabilities.empty();
+
   return leAudioCodecCapabilities;
 }
 
+void BluetoothLeAudioCodecsProvider::ClearLeAudioCodecCapabilities() {
+  leAudioCodecCapabilities.clear();
+  configuration_map_.clear();
+  codec_configuration_map_.clear();
+  strategy_configuration_map_.clear();
+}
+
 std::vector<setting::Scenario> BluetoothLeAudioCodecsProvider::GetScenarios(
     const std::optional<setting::LeAudioOffloadSetting>&
         le_audio_offload_setting) {
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
index 402235f..e879984 100644
--- a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProvider.h
@@ -31,8 +31,13 @@
 
 class BluetoothLeAudioCodecsProvider {
  public:
+  static std::optional<setting::LeAudioOffloadSetting>
+  ParseFromLeAudioOffloadSettingFile();
   static std::vector<LeAudioCodecCapabilitiesSetting>
-  GetLeAudioCodecCapabilities();
+  GetLeAudioCodecCapabilities(
+      const std::optional<setting::LeAudioOffloadSetting>&
+          le_audio_offload_setting);
+  static void ClearLeAudioCodecCapabilities();
 
  private:
   static inline std::unordered_map<std::string, setting::Configuration>
diff --git a/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp
new file mode 100644
index 0000000..5393cd7
--- /dev/null
+++ b/bluetooth/audio/utils/aidl_session/BluetoothLeAudioCodecsProviderTest.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <optional>
+#include <tuple>
+
+#include "BluetoothLeAudioCodecsProvider.h"
+
+using aidl::android::hardware::bluetooth::audio::BluetoothLeAudioCodecsProvider;
+using aidl::android::hardware::bluetooth::audio::
+    LeAudioCodecCapabilitiesSetting;
+using aidl::android::hardware::bluetooth::audio::setting::AudioLocation;
+using aidl::android::hardware::bluetooth::audio::setting::CodecConfiguration;
+using aidl::android::hardware::bluetooth::audio::setting::
+    CodecConfigurationList;
+using aidl::android::hardware::bluetooth::audio::setting::CodecType;
+using aidl::android::hardware::bluetooth::audio::setting::Configuration;
+using aidl::android::hardware::bluetooth::audio::setting::ConfigurationList;
+using aidl::android::hardware::bluetooth::audio::setting::LeAudioOffloadSetting;
+using aidl::android::hardware::bluetooth::audio::setting::Scenario;
+using aidl::android::hardware::bluetooth::audio::setting::ScenarioList;
+using aidl::android::hardware::bluetooth::audio::setting::StrategyConfiguration;
+using aidl::android::hardware::bluetooth::audio::setting::
+    StrategyConfigurationList;
+
+typedef std::tuple<std::vector<ScenarioList>, std::vector<ConfigurationList>,
+                   std::vector<CodecConfigurationList>,
+                   std::vector<StrategyConfigurationList>>
+    OffloadSetting;
+
+// Define valid components for each list
+// Scenario
+static const Scenario kValidScenario(std::make_optional("OneChanStereo_16_1"),
+                                     std::make_optional("OneChanStereo_16_1"));
+// Configuration
+static const Configuration kValidConfigOneChanStereo_16_1(
+    std::make_optional("OneChanStereo_16_1"), std::make_optional("LC3_16k_1"),
+    std::make_optional("STEREO_ONE_CIS_PER_DEVICE"));
+// CodecConfiguration
+static const CodecConfiguration kValidCodecLC3_16k_1(
+    std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
+    std::nullopt, std::make_optional(16000), std::make_optional(7500),
+    std::make_optional(30), std::nullopt);
+// StrategyConfiguration
+static const StrategyConfiguration kValidStrategyStereoOneCis(
+    std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
+    std::make_optional(AudioLocation::STEREO), std::make_optional(2),
+    std::make_optional(1));
+static const StrategyConfiguration kValidStrategyStereoTwoCis(
+    std::make_optional("STEREO_TWO_CISES_PER_DEVICE"),
+    std::make_optional(AudioLocation::STEREO), std::make_optional(1),
+    std::make_optional(2));
+static const StrategyConfiguration kValidStrategyMonoOneCis(
+    std::make_optional("MONO_ONE_CIS_PER_DEVICE"),
+    std::make_optional(AudioLocation::MONO), std::make_optional(1),
+    std::make_optional(1));
+
+// Define valid test list built from above valid components
+// Scenario, Configuration, CodecConfiguration, StrategyConfiguration
+static const std::vector<ScenarioList> kValidScenarioList = {
+    ScenarioList(std::vector<Scenario>{kValidScenario})};
+static const std::vector<ConfigurationList> kValidConfigurationList = {
+    ConfigurationList(
+        std::vector<Configuration>{kValidConfigOneChanStereo_16_1})};
+static const std::vector<CodecConfigurationList> kValidCodecConfigurationList =
+    {CodecConfigurationList(
+        std::vector<CodecConfiguration>{kValidCodecLC3_16k_1})};
+static const std::vector<StrategyConfigurationList>
+    kValidStrategyConfigurationList = {
+        StrategyConfigurationList(std::vector<StrategyConfiguration>{
+            kValidStrategyStereoOneCis, kValidStrategyStereoTwoCis,
+            kValidStrategyMonoOneCis})};
+
+class BluetoothLeAudioCodecsProviderTest
+    : public ::testing::TestWithParam<OffloadSetting> {
+ public:
+  static std::vector<OffloadSetting> CreateTestCases(
+      const std::vector<ScenarioList>& scenario_lists,
+      const std::vector<ConfigurationList>& configuration_lists,
+      const std::vector<CodecConfigurationList>& codec_configuration_lists,
+      const std::vector<StrategyConfigurationList>&
+          strategy_configuration_lists) {
+    // make each vector in output test_cases has only one element
+    // to match the input of test params
+    // normally only one vector in input has multiple elements
+    // we just split elements in this vector to several vector
+    std::vector<OffloadSetting> test_cases;
+    for (const auto& scenario_list : scenario_lists) {
+      for (const auto& configuration_list : configuration_lists) {
+        for (const auto& codec_configuration_list : codec_configuration_lists) {
+          for (const auto& strategy_configuration_list :
+               strategy_configuration_lists) {
+            test_cases.push_back(CreateTestCase(
+                scenario_list, configuration_list, codec_configuration_list,
+                strategy_configuration_list));
+          }
+        }
+      }
+    }
+    return test_cases;
+  }
+
+ protected:
+  void Initialize() {
+    BluetoothLeAudioCodecsProvider::ClearLeAudioCodecCapabilities();
+  }
+
+  std::vector<LeAudioCodecCapabilitiesSetting> RunTestCase() {
+    auto& [scenario_lists, configuration_lists, codec_configuration_lists,
+           strategy_configuration_lists] = GetParam();
+    LeAudioOffloadSetting le_audio_offload_setting(
+        scenario_lists, configuration_lists, codec_configuration_lists,
+        strategy_configuration_lists);
+    auto le_audio_codec_capabilities =
+        BluetoothLeAudioCodecsProvider::GetLeAudioCodecCapabilities(
+            std::make_optional(le_audio_offload_setting));
+    return le_audio_codec_capabilities;
+  }
+
+ private:
+  static inline OffloadSetting CreateTestCase(
+      const ScenarioList& scenario_list,
+      const ConfigurationList& configuration_list,
+      const CodecConfigurationList& codec_configuration_list,
+      const StrategyConfigurationList& strategy_configuration_list) {
+    return std::make_tuple(
+        std::vector<ScenarioList>{scenario_list},
+        std::vector<ConfigurationList>{configuration_list},
+        std::vector<CodecConfigurationList>{codec_configuration_list},
+        std::vector<StrategyConfigurationList>{strategy_configuration_list});
+  }
+};
+
+class GetScenariosTest : public BluetoothLeAudioCodecsProviderTest {
+ public:
+  static std::vector<ScenarioList> CreateInvalidScenarios() {
+    std::vector<ScenarioList> invalid_scenario_test_cases;
+    invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
+        Scenario(std::nullopt, std::make_optional("OneChanStereo_16_1"))}));
+
+    invalid_scenario_test_cases.push_back(ScenarioList(std::vector<Scenario>{
+        Scenario(std::make_optional("OneChanStereo_16_1"), std::nullopt)}));
+
+    invalid_scenario_test_cases.push_back(ScenarioList(
+        std::vector<Scenario>{Scenario(std::nullopt, std::nullopt)}));
+
+    invalid_scenario_test_cases.push_back(
+        ScenarioList(std::vector<Scenario>{}));
+
+    return invalid_scenario_test_cases;
+  }
+};
+
+TEST_P(GetScenariosTest, InvalidScenarios) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(le_audio_codec_capabilities.empty());
+}
+
+class UpdateConfigurationsToMapTest
+    : public BluetoothLeAudioCodecsProviderTest {
+ public:
+  static std::vector<ConfigurationList> CreateInvalidConfigurations() {
+    std::vector<ConfigurationList> invalid_configuration_test_cases;
+    invalid_configuration_test_cases.push_back(
+        ConfigurationList(std::vector<Configuration>{
+            Configuration(std::nullopt, std::make_optional("LC3_16k_1"),
+                          std::make_optional("STEREO_ONE_CIS_PER_DEVICE"))}));
+
+    invalid_configuration_test_cases.push_back(
+        ConfigurationList(std::vector<Configuration>{Configuration(
+            std::make_optional("OneChanStereo_16_1"), std::nullopt,
+            std::make_optional("STEREO_ONE_CIS_PER_DEVICE"))}));
+
+    invalid_configuration_test_cases.push_back(
+        ConfigurationList(std::vector<Configuration>{
+            Configuration(std::make_optional("OneChanStereo_16_1"),
+                          std::make_optional("LC3_16k_1"), std::nullopt)}));
+
+    invalid_configuration_test_cases.push_back(
+        ConfigurationList(std::vector<Configuration>{}));
+
+    return invalid_configuration_test_cases;
+  }
+};
+
+TEST_P(UpdateConfigurationsToMapTest, InvalidConfigurations) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(le_audio_codec_capabilities.empty());
+}
+
+class UpdateCodecConfigurationsToMapTest
+    : public BluetoothLeAudioCodecsProviderTest {
+ public:
+  static std::vector<CodecConfigurationList>
+  CreateInvalidCodecConfigurations() {
+    std::vector<CodecConfigurationList> invalid_codec_configuration_test_cases;
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::nullopt, std::make_optional(CodecType::LC3), std::nullopt,
+            std::make_optional(16000), std::make_optional(7500),
+            std::make_optional(30), std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::make_optional("LC3_16k_1"), std::nullopt, std::nullopt,
+            std::make_optional(16000), std::make_optional(7500),
+            std::make_optional(30), std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
+            std::nullopt, std::nullopt, std::make_optional(7500),
+            std::make_optional(30), std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
+            std::nullopt, std::make_optional(16000), std::nullopt,
+            std::make_optional(30), std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(CodecConfigurationList(
+        std::vector<CodecConfiguration>{CodecConfiguration(
+            std::make_optional("LC3_16k_1"), std::make_optional(CodecType::LC3),
+            std::nullopt, std::make_optional(16000), std::make_optional(7500),
+            std::nullopt, std::nullopt)}));
+
+    invalid_codec_configuration_test_cases.push_back(
+        CodecConfigurationList(std::vector<CodecConfiguration>{}));
+
+    return invalid_codec_configuration_test_cases;
+  }
+};
+
+TEST_P(UpdateCodecConfigurationsToMapTest, InvalidCodecConfigurations) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(le_audio_codec_capabilities.empty());
+}
+
+class UpdateStrategyConfigurationsToMapTest
+    : public BluetoothLeAudioCodecsProviderTest {
+ public:
+  static std::vector<StrategyConfigurationList>
+  CreateInvalidStrategyConfigurations() {
+    std::vector<StrategyConfigurationList>
+        invalid_strategy_configuration_test_cases;
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
+                std::make_optional(AudioLocation::STEREO),
+                std::make_optional(2), std::make_optional(2))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("MONO_ONE_CIS_PER_DEVICE"),
+                std::make_optional(AudioLocation::STEREO),
+                std::make_optional(2), std::make_optional(2))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::nullopt, std::make_optional(AudioLocation::STEREO),
+                std::make_optional(2), std::make_optional(1))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("STEREO_ONE_CIS_PER_DEVICE"), std::nullopt,
+                std::make_optional(2), std::make_optional(1))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
+                std::make_optional(AudioLocation::STEREO), std::nullopt,
+                std::make_optional(1))}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(
+            std::vector<StrategyConfiguration>{StrategyConfiguration(
+                std::make_optional("STEREO_ONE_CIS_PER_DEVICE"),
+                std::make_optional(AudioLocation::STEREO),
+                std::make_optional(2), std::nullopt)}));
+
+    invalid_strategy_configuration_test_cases.push_back(
+        StrategyConfigurationList(std::vector<StrategyConfiguration>{}));
+
+    return invalid_strategy_configuration_test_cases;
+  }
+};
+
+TEST_P(UpdateStrategyConfigurationsToMapTest, InvalidStrategyConfigurations) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(le_audio_codec_capabilities.empty());
+}
+
+class ComposeLeAudioCodecCapabilitiesTest
+    : public BluetoothLeAudioCodecsProviderTest {
+ public:
+};
+
+TEST_P(ComposeLeAudioCodecCapabilitiesTest, CodecCapabilitiesNotEmpty) {
+  Initialize();
+  auto le_audio_codec_capabilities = RunTestCase();
+  ASSERT_TRUE(!le_audio_codec_capabilities.empty());
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetScenariosTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, GetScenariosTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        GetScenariosTest::CreateInvalidScenarios(), kValidConfigurationList,
+        kValidCodecConfigurationList, kValidStrategyConfigurationList)));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(UpdateConfigurationsToMapTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, UpdateConfigurationsToMapTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        kValidScenarioList,
+        UpdateConfigurationsToMapTest::CreateInvalidConfigurations(),
+        kValidCodecConfigurationList, kValidStrategyConfigurationList)));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    UpdateCodecConfigurationsToMapTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, UpdateCodecConfigurationsToMapTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        kValidScenarioList, kValidConfigurationList,
+        UpdateCodecConfigurationsToMapTest::CreateInvalidCodecConfigurations(),
+        kValidStrategyConfigurationList)));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    UpdateStrategyConfigurationsToMapTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, UpdateStrategyConfigurationsToMapTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        kValidScenarioList, kValidConfigurationList,
+        kValidCodecConfigurationList,
+        UpdateStrategyConfigurationsToMapTest::
+            CreateInvalidStrategyConfigurations())));
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
+    ComposeLeAudioCodecCapabilitiesTest);
+INSTANTIATE_TEST_SUITE_P(
+    BluetoothLeAudioCodecsProviderTest, ComposeLeAudioCodecCapabilitiesTest,
+    ::testing::ValuesIn(BluetoothLeAudioCodecsProviderTest::CreateTestCases(
+        kValidScenarioList, kValidConfigurationList,
+        kValidCodecConfigurationList, kValidStrategyConfigurationList)));
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
index 57705bc..f940000 100644
--- a/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
+++ b/camera/device/aidl/android/hardware/camera/device/ICameraDevice.aidl
@@ -279,8 +279,10 @@
      * with specified torchStrength if the torch is OFF.
      *
      * The torchStrength value must be within the valid range i.e. >=1 and
-     * <= FLASH_INFO_STRENGTH_MAXIMUM_LEVEL. Whenever the torch is turned OFF,
-     * the brightness level will reset to FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
+     * <= FLASH_INFO_STRENGTH_MAXIMUM_LEVEL. The FLASH_INFO_STRENGTH_MAXIMUM_LEVEL must
+     * be set to a level which will not cause any burn out issues. Whenever
+     * the torch is turned OFF, the brightness level will reset to
+     * FLASH_INFO_STRENGTH_DEFAULT_LEVEL.
      * When the client calls setTorchMode(ON) after turnOnTorchWithStrengthLevel(N),
      * the flash unit will have brightness level equal to N. This level does not
      * represent the real brightness units. It is linear in nature i.e. flashlight
diff --git a/contexthub/aidl/default/ContextHub.cpp b/contexthub/aidl/default/ContextHub.cpp
index 4c23cbc..35e4650 100644
--- a/contexthub/aidl/default/ContextHub.cpp
+++ b/contexthub/aidl/default/ContextHub.cpp
@@ -107,10 +107,9 @@
 ScopedAStatus ContextHub::onHostEndpointDisconnected(char16_t in_hostEndpointId) {
     if (mConnectedHostEndpoints.count(in_hostEndpointId) > 0) {
         mConnectedHostEndpoints.erase(in_hostEndpointId);
-        return ndk::ScopedAStatus::ok();
-    } else {
-        return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT));
     }
+
+    return ndk::ScopedAStatus::ok();
 }
 
 }  // namespace contexthub
diff --git a/fastboot/aidl/default/Android.bp b/fastboot/aidl/default/Android.bp
index 5cd4542..0c96b33 100644
--- a/fastboot/aidl/default/Android.bp
+++ b/fastboot/aidl/default/Android.bp
@@ -22,16 +22,20 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
-cc_library {
-    name: "android.hardware.fastboot-impl-mock",
-    recovery: true,
+cc_binary {
+    name: "android.hardware.fastboot-service.example_recovery",
+    init_rc: ["android.hardware.fastboot-service.example_recovery.rc"],
+    vintf_fragments: ["android.hardware.fastboot-service.example.xml"],
+    recovery_available: true,
     srcs: [
         "Fastboot.cpp",
+        "main.cpp",
     ],
     relative_install_path: "hw",
     shared_libs: [
         "libbase",
         "libbinder_ndk",
+        "liblog",
         "libutils",
         "libcutils",
         "android.hardware.fastboot-V1-ndk",
diff --git a/fastboot/aidl/default/android.hardware.fastboot-service.example.xml b/fastboot/aidl/default/android.hardware.fastboot-service.example.xml
new file mode 100644
index 0000000..9490f98
--- /dev/null
+++ b/fastboot/aidl/default/android.hardware.fastboot-service.example.xml
@@ -0,0 +1,8 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.fastboot</name>
+        <version>1</version>
+        <fqname>IFastboot/default</fqname>
+    </hal>
+</manifest>
+
diff --git a/fastboot/aidl/default/android.hardware.fastboot-service.example_recovery.rc b/fastboot/aidl/default/android.hardware.fastboot-service.example_recovery.rc
new file mode 100644
index 0000000..5d4ee13
--- /dev/null
+++ b/fastboot/aidl/default/android.hardware.fastboot-service.example_recovery.rc
@@ -0,0 +1,6 @@
+service vendor.fastboot-default /system/bin/hw/android.hardware.fastboot-service.example_recovery
+    class hal
+    seclabel u:r:hal_fastboot_default:s0
+    user system
+    group system
+    interface aidl android.hardware.fastboot.IFastboot/default
diff --git a/fastboot/aidl/default/main.cpp b/fastboot/aidl/default/main.cpp
new file mode 100644
index 0000000..1b1b41d
--- /dev/null
+++ b/fastboot/aidl/default/main.cpp
@@ -0,0 +1,38 @@
+
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include "Fastboot.h"
+
+using aidl::android::hardware::fastboot::Fastboot;
+using aidl::android::hardware::fastboot::IFastboot;
+
+int main(int, char* argv[]) {
+    android::base::InitLogging(argv, android::base::KernelLogger);
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+    std::shared_ptr<IFastboot> service = ndk::SharedRefBase::make<Fastboot>();
+
+    const std::string instance = std::string(IFastboot::descriptor) + "/default";
+    auto status = AServiceManager_addService(service->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK) << "Failed to add service " << instance << " " << status;
+    LOG(INFO) << "IFastboot AIDL service running...";
+
+    ABinderProcess_joinThreadPool();
+    return EXIT_FAILURE;  // should not reach
+}
diff --git a/fastboot/aidl/fastbootshim/Android.bp b/fastboot/aidl/fastbootshim/Android.bp
new file mode 100644
index 0000000..c843c12
--- /dev/null
+++ b/fastboot/aidl/fastbootshim/Android.bp
@@ -0,0 +1,61 @@
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_interfaces_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_defaults {
+    name: "libfastbootshim_defaults",
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    static_libs: [
+        "android.hardware.fastboot-V1-ndk",
+        "android.hardware.fastboot@1.0",
+        "android.hardware.fastboot@1.1",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder_ndk",
+        "libcutils",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+}
+
+// Shim library that wraps a HIDL Fastboot object into an AIDL Fastboot object.
+cc_library_static {
+    name: "libfastbootshim",
+    defaults: ["libfastbootshim_defaults"],
+    recovery_available: true,
+    srcs: [
+        "fastbootshim.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+}
diff --git a/fastboot/aidl/fastbootshim/fastbootshim.cpp b/fastboot/aidl/fastbootshim/fastbootshim.cpp
new file mode 100644
index 0000000..4ab67f3
--- /dev/null
+++ b/fastboot/aidl/fastbootshim/fastbootshim.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fastbootshim.h>
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::Void;
+using ::android::hardware::fastboot::V1_0::FileSystemType;
+using ::android::hardware::fastboot::V1_0::Result;
+using ::android::hardware::fastboot::V1_0::Status;
+
+using ndk::ScopedAStatus;
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace fastboot {
+ScopedAStatus ResultToAStatus(Result result) {
+    switch (result.status) {
+        case Status::SUCCESS:
+            return ScopedAStatus::ok();
+        case Status::NOT_SUPPORTED:
+            return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+        case Status::INVALID_ARGUMENT:
+            return ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+        case Status::FAILURE_UNKNOWN:
+            return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+                    BnFastboot::FAILURE_UNKNOWN, ("Error " + std::string(result.message)).c_str());
+    }
+    return ScopedAStatus::fromServiceSpecificErrorWithMessage(
+            BnFastboot::FAILURE_UNKNOWN,
+            ("Unrecognized status value " + toString(result.status)).c_str());
+}
+FastbootShim::FastbootShim(const sp<HidlFastboot>& service) : service_(service) {}
+
+ScopedAStatus FastbootShim::getPartitionType(const std::string& in_partitionName,
+                                             FileSystemType* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    if (in_partitionName.empty()) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+                                                           "Invalid partition name");
+    }
+    const hidl_string partition = in_partitionName;
+    auto ret = service_->getPartitionType(partition, [&](auto type, auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = static_cast<aidl::android::hardware::fastboot::FileSystemType>(type);
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::doOemCommand(const std::string& in_oemCmd, std::string* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    *_aidl_return = "";
+    if (in_oemCmd.empty()) {
+        return ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT, "Invalid command");
+    }
+    const hidl_string oemCmdArgs = in_oemCmd;
+    auto ret = service_->doOemCommand(oemCmdArgs, [&](auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = std::string(result.message.c_str());
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::getVariant(std::string* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    *_aidl_return = "";
+    auto ret = service_->getVariant([&](auto& variant, auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = std::string(variant.c_str());
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::getOffModeChargeState(bool* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    *_aidl_return = false;
+    auto ret = service_->getOffModeChargeState([&](auto state, auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = state;
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::getBatteryVoltageFlashingThreshold(int32_t* _aidl_return) {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    *_aidl_return = 0;
+    auto ret = service_->getBatteryVoltageFlashingThreshold([&](auto batteryVoltage, auto& result) {
+        out_result = result;
+        if (out_result.status != Status::SUCCESS) return;
+        *_aidl_return = batteryVoltage;
+    });
+    return ResultToAStatus(out_result);
+}
+
+ScopedAStatus FastbootShim::doOemSpecificErase() {
+    Result out_result = {Status::FAILURE_UNKNOWN, ""};
+    auto ret = service_->doOemSpecificErase([&](auto& result) { out_result = result; });
+    return ResultToAStatus(out_result);
+}
+
+}  // namespace fastboot
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/fastboot/aidl/fastbootshim/include/fastbootshim.h b/fastboot/aidl/fastbootshim/include/fastbootshim.h
new file mode 100644
index 0000000..410a03e
--- /dev/null
+++ b/fastboot/aidl/fastbootshim/include/fastbootshim.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/fastboot/BnFastboot.h>
+#include <android/hardware/fastboot/1.1/IFastboot.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace fastboot {
+// Shim that wraps HIDL IFastboot with AIDL BnFastboot
+class FastbootShim : public BnFastboot {
+    using HidlFastboot = ::android::hardware::fastboot::V1_1::IFastboot;
+
+  public:
+    explicit FastbootShim(const ::android::sp<HidlFastboot>& service);
+    ::ndk::ScopedAStatus doOemCommand(const std::string& in_oemCmd,
+                                      std::string* _aidl_return) override;
+    ::ndk::ScopedAStatus doOemSpecificErase() override;
+    ::ndk::ScopedAStatus getBatteryVoltageFlashingThreshold(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getOffModeChargeState(bool* _aidl_return) override;
+    ::ndk::ScopedAStatus getPartitionType(
+            const std::string& in_partitionName,
+            ::aidl::android::hardware::fastboot::FileSystemType* _aidl_return) override;
+    ::ndk::ScopedAStatus getVariant(std::string* _aidl_return) override;
+
+  private:
+    ::android::sp<HidlFastboot> service_;
+};
+
+}  // namespace fastboot
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 5473062..80abd92 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1919,30 +1919,32 @@
 
     // The following check assumes that canonical CBOR encoding is used for the COSE_Key.
     if (testMode) {
-        EXPECT_THAT(cppbor::prettyPrint(parsedPayload.get()),
-                    MatchesRegex("{\n"
-                                 "  1 : 2,\n"   // kty: EC2
-                                 "  3 : -7,\n"  // alg: ES256
-                                 "  -1 : 1,\n"  // EC id: P256
-                                 // The regex {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}} matches a
-                                 // sequence of 32 hexadecimal bytes, enclosed in braces and
-                                 // separated by commas. In this case, some Ed25519 public key.
-                                 "  -2 : {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}},\n"  // pub_x: data
-                                 "  -3 : {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}},\n"  // pub_y: data
-                                 "  -70000 : null,\n"                              // test marker
-                                 "}"));
+        EXPECT_THAT(
+                cppbor::prettyPrint(parsedPayload.get()),
+                MatchesRegex("\\{\n"
+                             "  1 : 2,\n"   // kty: EC2
+                             "  3 : -7,\n"  // alg: ES256
+                             "  -1 : 1,\n"  // EC id: P256
+                             // The regex {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}} matches a
+                             // sequence of 32 hexadecimal bytes, enclosed in braces and
+                             // separated by commas. In this case, some Ed25519 public key.
+                             "  -2 : \\{(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}\\},\n"  // pub_x: data
+                             "  -3 : \\{(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}\\},\n"  // pub_y: data
+                             "  -70000 : null,\n"                                  // test marker
+                             "\\}"));
     } else {
-        EXPECT_THAT(cppbor::prettyPrint(parsedPayload.get()),
-                    MatchesRegex("{\n"
-                                 "  1 : 2,\n"   // kty: EC2
-                                 "  3 : -7,\n"  // alg: ES256
-                                 "  -1 : 1,\n"  // EC id: P256
-                                 // The regex {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}} matches a
-                                 // sequence of 32 hexadecimal bytes, enclosed in braces and
-                                 // separated by commas. In this case, some Ed25519 public key.
-                                 "  -2 : {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}},\n"  // pub_x: data
-                                 "  -3 : {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}},\n"  // pub_y: data
-                                 "}"));
+        EXPECT_THAT(
+                cppbor::prettyPrint(parsedPayload.get()),
+                MatchesRegex("\\{\n"
+                             "  1 : 2,\n"   // kty: EC2
+                             "  3 : -7,\n"  // alg: ES256
+                             "  -1 : 1,\n"  // EC id: P256
+                             // The regex {(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}} matches a
+                             // sequence of 32 hexadecimal bytes, enclosed in braces and
+                             // separated by commas. In this case, some Ed25519 public key.
+                             "  -2 : \\{(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}\\},\n"  // pub_x: data
+                             "  -3 : \\{(0x[0-9a-f]{2}, ){31}0x[0-9a-f]{2}\\},\n"  // pub_y: data
+                             "\\}"));
     }
 }
 
diff --git a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
index 5bbae4c..0c61c25 100644
--- a/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
+++ b/security/keymint/aidl/vts/performance/KeyMintBenchmark.cpp
@@ -16,16 +16,21 @@
 
 #define LOG_TAG "keymint_benchmark"
 
+#include <iostream>
+
 #include <base/command_line.h>
 #include <benchmark/benchmark.h>
-#include <iostream>
 
 #include <aidl/Vintf.h>
 #include <aidl/android/hardware/security/keymint/ErrorCode.h>
 #include <aidl/android/hardware/security/keymint/IKeyMintDevice.h>
 #include <android/binder_manager.h>
 #include <binder/IServiceManager.h>
+
 #include <keymint_support/authorization_set.h>
+#include <keymint_support/openssl_utils.h>
+#include <openssl/curve25519.h>
+#include <openssl/x509.h>
 
 #define SMALL_MESSAGE_SIZE 64
 #define MEDIUM_MESSAGE_SIZE 1024
@@ -119,6 +124,22 @@
         return {};
     }
 
+    string getAlgorithmString(string transform) {
+        if (transform.find("AES") != string::npos) {
+            return "AES";
+        } else if (transform.find("Hmac") != string::npos) {
+            return "HMAC";
+        } else if (transform.find("DESede") != string::npos) {
+            return "TRIPLE_DES";
+        } else if (transform.find("RSA") != string::npos) {
+            return "RSA";
+        } else if (transform.find("EC") != string::npos) {
+            return "EC";
+        }
+        std::cerr << "Can't find algorithm for " << transform << std::endl;
+        return "";
+    }
+
     Digest getDigest(string transform) {
         if (transform.find("MD5") != string::npos) {
             return Digest::MD5;
@@ -135,29 +156,56 @@
             return Digest::SHA_2_512;
         } else if (transform.find("RSA") != string::npos &&
                    transform.find("OAEP") != string::npos) {
-            return Digest::SHA1;
+            if (securityLevel_ == SecurityLevel::STRONGBOX) {
+                return Digest::SHA_2_256;
+            } else {
+                return Digest::SHA1;
+            }
         } else if (transform.find("Hmac") != string::npos) {
             return Digest::SHA_2_256;
         }
         return Digest::NONE;
     }
 
+    string getDigestString(string transform) {
+        if (transform.find("MD5") != string::npos) {
+            return "MD5";
+        } else if (transform.find("SHA1") != string::npos ||
+                   transform.find("SHA-1") != string::npos) {
+            return "SHA1";
+        } else if (transform.find("SHA224") != string::npos) {
+            return "SHA_2_224";
+        } else if (transform.find("SHA256") != string::npos) {
+            return "SHA_2_256";
+        } else if (transform.find("SHA384") != string::npos) {
+            return "SHA_2_384";
+        } else if (transform.find("SHA512") != string::npos) {
+            return "SHA_2_512";
+        } else if (transform.find("RSA") != string::npos &&
+                   transform.find("OAEP") != string::npos) {
+            if (securityLevel_ == SecurityLevel::STRONGBOX) {
+                return "SHA_2_256";
+            } else {
+                return "SHA1";
+            }
+        } else if (transform.find("Hmac") != string::npos) {
+            return "SHA_2_256";
+        }
+        return "";
+    }
+
     optional<EcCurve> getCurveFromLength(int keySize) {
         switch (keySize) {
             case 224:
                 return EcCurve::P_224;
-                break;
             case 256:
                 return EcCurve::P_256;
-                break;
             case 384:
                 return EcCurve::P_384;
-                break;
             case 521:
                 return EcCurve::P_521;
-                break;
             default:
-                return {};
+                return std::nullopt;
         }
     }
 
@@ -261,6 +309,109 @@
         return GetReturnErrorCode(result);
     }
 
+    /* Copied the function LocalRsaEncryptMessage from
+     * hardware/interfaces/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp in VTS.
+     * Replaced asserts with the condition check and return false in case of failure condition.
+     * Require return value to skip the benchmark test case from further execution in case
+     * LocalRsaEncryptMessage fails.
+     */
+    optional<string> LocalRsaEncryptMessage(const string& message, const AuthorizationSet& params) {
+        // Retrieve the public key from the leaf certificate.
+        if (cert_chain_.empty()) {
+            std::cerr << "Local RSA encrypt Error: invalid cert_chain_" << std::endl;
+            return "Failure";
+        }
+        X509_Ptr key_cert(parse_cert_blob(cert_chain_[0].encodedCertificate));
+        EVP_PKEY_Ptr pub_key(X509_get_pubkey(key_cert.get()));
+        RSA_Ptr rsa(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pub_key.get())));
+
+        // Retrieve relevant tags.
+        Digest digest = Digest::NONE;
+        Digest mgf_digest = Digest::SHA1;
+        PaddingMode padding = PaddingMode::NONE;
+
+        auto digest_tag = params.GetTagValue(TAG_DIGEST);
+        if (digest_tag.has_value()) digest = digest_tag.value();
+        auto pad_tag = params.GetTagValue(TAG_PADDING);
+        if (pad_tag.has_value()) padding = pad_tag.value();
+        auto mgf_tag = params.GetTagValue(TAG_RSA_OAEP_MGF_DIGEST);
+        if (mgf_tag.has_value()) mgf_digest = mgf_tag.value();
+
+        const EVP_MD* md = openssl_digest(digest);
+        const EVP_MD* mgf_md = openssl_digest(mgf_digest);
+
+        // Set up encryption context.
+        EVP_PKEY_CTX_Ptr ctx(EVP_PKEY_CTX_new(pub_key.get(), /* engine= */ nullptr));
+        if (EVP_PKEY_encrypt_init(ctx.get()) <= 0) {
+            std::cerr << "Local RSA encrypt Error: Encryption init failed" << std::endl;
+            return "Failure";
+        }
+
+        int rc = -1;
+        switch (padding) {
+            case PaddingMode::NONE:
+                rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_NO_PADDING);
+                break;
+            case PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
+                rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PADDING);
+                break;
+            case PaddingMode::RSA_OAEP:
+                rc = EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING);
+                break;
+            default:
+                break;
+        }
+        if (rc <= 0) {
+            std::cerr << "Local RSA encrypt Error: Set padding failed" << std::endl;
+            return "Failure";
+        }
+        if (padding == PaddingMode::RSA_OAEP) {
+            if (!EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), md)) {
+                std::cerr << "Local RSA encrypt Error: Set digest failed: " << ERR_peek_last_error()
+                          << std::endl;
+                return "Failure";
+            }
+            if (!EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), mgf_md)) {
+                std::cerr << "Local RSA encrypt Error: Set digest failed: " << ERR_peek_last_error()
+                          << std::endl;
+                return "Failure";
+            }
+        }
+
+        // Determine output size.
+        size_t outlen;
+        if (EVP_PKEY_encrypt(ctx.get(), nullptr /* out */, &outlen,
+                             reinterpret_cast<const uint8_t*>(message.data()),
+                             message.size()) <= 0) {
+            std::cerr << "Local RSA encrypt Error: Determine output size failed: "
+                      << ERR_peek_last_error() << std::endl;
+            return "Failure";
+        }
+
+        // Left-zero-pad the input if necessary.
+        const uint8_t* to_encrypt = reinterpret_cast<const uint8_t*>(message.data());
+        size_t to_encrypt_len = message.size();
+
+        std::unique_ptr<string> zero_padded_message;
+        if (padding == PaddingMode::NONE && to_encrypt_len < outlen) {
+            zero_padded_message.reset(new string(outlen, '\0'));
+            memcpy(zero_padded_message->data() + (outlen - to_encrypt_len), message.data(),
+                   message.size());
+            to_encrypt = reinterpret_cast<const uint8_t*>(zero_padded_message->data());
+            to_encrypt_len = outlen;
+        }
+
+        // Do the encryption.
+        string output(outlen, '\0');
+        if (EVP_PKEY_encrypt(ctx.get(), reinterpret_cast<uint8_t*>(output.data()), &outlen,
+                             to_encrypt, to_encrypt_len) <= 0) {
+            std::cerr << "Local RSA encrypt Error: Encryption failed: " << ERR_peek_last_error()
+                      << std::endl;
+            return "Failure";
+        }
+        return output;
+    }
+
     SecurityLevel securityLevel_;
     string name_;
 
@@ -268,12 +419,13 @@
     ErrorCode GenerateKey(const AuthorizationSet& key_desc,
                           const optional<AttestationKey>& attest_key = std::nullopt) {
         key_blob_.clear();
+        cert_chain_.clear();
         KeyCreationResult creationResult;
         Status result = keymint_->generateKey(key_desc.vector_data(), attest_key, &creationResult);
         if (result.isOk()) {
             key_blob_ = std::move(creationResult.keyBlob);
+            cert_chain_ = std::move(creationResult.certificateChain);
             creationResult.keyCharacteristics.clear();
-            creationResult.certificateChain.clear();
         }
         return GetReturnErrorCode(result);
     }
@@ -338,6 +490,11 @@
         return ErrorCode::UNKNOWN_ERROR;
     }
 
+    X509_Ptr parse_cert_blob(const vector<uint8_t>& blob) {
+        const uint8_t* p = blob.data();
+        return X509_Ptr(d2i_X509(nullptr /* allocate new */, &p, blob.size()));
+    }
+
     std::shared_ptr<IKeyMintOperation> op_;
     vector<Certificate> cert_chain_;
     vector<uint8_t> key_blob_;
@@ -390,6 +547,10 @@
     BENCHMARK_KM_MSG(encrypt, transform, keySize, msgSize) \
     BENCHMARK_KM_MSG(decrypt, transform, keySize, msgSize)
 
+// Skip public key operations as they are not supported in KeyMint.
+#define BENCHMARK_KM_ASYM_CIPHER(transform, keySize, msgSize)   \
+    BENCHMARK_KM_MSG(decrypt, transform, keySize, msgSize)
+
 #define BENCHMARK_KM_CIPHER_ALL_MSGS(transform, keySize) \
     BENCHMARK_KM_ALL_MSGS(encrypt, transform, keySize)   \
     BENCHMARK_KM_ALL_MSGS(decrypt, transform, keySize)
@@ -397,12 +558,43 @@
 #define BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, keySize) \
     BENCHMARK_KM_ALL_MSGS(sign, transform, keySize)         \
     BENCHMARK_KM_ALL_MSGS(verify, transform, keySize)
-// clang-format on
+
+// Skip public key operations as they are not supported in KeyMint.
+#define BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, keySize) \
+    BENCHMARK_KM_ALL_MSGS(sign, transform, keySize) \
+    // clang-format on
 
 /*
  * ============= KeyGen TESTS ==================
  */
+
+static bool isValidSBKeySize(string transform, int keySize) {
+    std::optional<Algorithm> algorithm = keymintTest->getAlgorithm(transform);
+    switch (algorithm.value()) {
+        case Algorithm::AES:
+            return (keySize == 128 || keySize == 256);
+        case Algorithm::HMAC:
+            return (keySize % 8 == 0 && keySize >= 64 && keySize <= 512);
+        case Algorithm::TRIPLE_DES:
+            return (keySize == 168);
+        case Algorithm::RSA:
+            return (keySize == 2048);
+        case Algorithm::EC:
+            return (keySize == 256);
+    }
+    return false;
+}
+
 static void keygen(benchmark::State& state, string transform, int keySize) {
+    // Skip the test for unsupported key size in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX &&
+        !isValidSBKeySize(transform, keySize)) {
+        state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                             " is not supported in StrongBox for algorithm: " +
+                             keymintTest->getAlgorithmString(transform))
+                                    .c_str());
+        return;
+    }
     addDefaultLabel(state);
     for (auto _ : state) {
         if (!keymintTest->GenerateKey(transform, keySize)) {
@@ -438,8 +630,24 @@
 /*
  * ============= SIGNATURE TESTS ==================
  */
-
 static void sign(benchmark::State& state, string transform, int keySize, int msgSize) {
+    // Skip the test for unsupported key size or unsupported digest in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX) {
+        if (!isValidSBKeySize(transform, keySize)) {
+            state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                                 " is not supported in StrongBox for algorithm: " +
+                                 keymintTest->getAlgorithmString(transform))
+                                        .c_str());
+            return;
+        }
+        if (keymintTest->getDigest(transform) != Digest::SHA_2_256) {
+            state.SkipWithError(
+                    ("Skipped for STRONGBOX: Digest: " + keymintTest->getDigestString(transform) +
+                     " is not supported in StrongBox")
+                            .c_str());
+            return;
+        }
+    }
     addDefaultLabel(state);
     if (!keymintTest->GenerateKey(transform, keySize, true)) {
         state.SkipWithError(
@@ -469,6 +677,23 @@
 }
 
 static void verify(benchmark::State& state, string transform, int keySize, int msgSize) {
+    // Skip the test for unsupported key size or unsupported digest in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX) {
+        if (!isValidSBKeySize(transform, keySize)) {
+            state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                                 " is not supported in StrongBox for algorithm: " +
+                                 keymintTest->getAlgorithmString(transform))
+                                        .c_str());
+            return;
+        }
+        if (keymintTest->getDigest(transform) != Digest::SHA_2_256) {
+            state.SkipWithError(
+                    ("Skipped for STRONGBOX: Digest: " + keymintTest->getDigestString(transform) +
+                     " is not supported in StrongBox")
+                            .c_str());
+            return;
+        }
+    }
     addDefaultLabel(state);
     if (!keymintTest->GenerateKey(transform, keySize, true)) {
         state.SkipWithError(
@@ -525,10 +750,10 @@
 BENCHMARK_KM_SIGNATURE_ALL_HMAC_KEYS(HmacSHA512)
 
 #define BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(transform) \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 224)      \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 256)      \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 384)      \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 521)
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 224)      \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 256)      \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 384)      \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 521)
 
 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(NONEwithECDSA);
 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA1withECDSA);
@@ -538,13 +763,14 @@
 BENCHMARK_KM_SIGNATURE_ALL_ECDSA_KEYS(SHA512withECDSA);
 
 #define BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(transform) \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 2048)   \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 3072)   \
-    BENCHMARK_KM_SIGNATURE_ALL_MSGS(transform, 4096)
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 2048)   \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 3072)   \
+    BENCHMARK_KM_ASYM_SIGNATURE_ALL_MSGS(transform, 4096)
 
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(MD5withRSA);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA1withRSA);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA);
+BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA256withRSA);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA);
 
@@ -553,6 +779,7 @@
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA224withRSA/PSS);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA384withRSA/PSS);
 BENCHMARK_KM_SIGNATURE_ALL_RSA_KEYS(SHA512withRSA/PSS);
+
 // clang-format on
 
 /*
@@ -560,6 +787,15 @@
  */
 
 static void encrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
+    // Skip the test for unsupported key size in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX &&
+        (!isValidSBKeySize(transform, keySize))) {
+        state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                             " is not supported in StrongBox for algorithm: " +
+                             keymintTest->getAlgorithmString(transform))
+                                    .c_str());
+        return;
+    }
     addDefaultLabel(state);
     if (!keymintTest->GenerateKey(transform, keySize)) {
         state.SkipWithError(
@@ -589,6 +825,15 @@
 }
 
 static void decrypt(benchmark::State& state, string transform, int keySize, int msgSize) {
+    // Skip the test for unsupported key size in StrongBox
+    if (keymintTest->securityLevel_ == SecurityLevel::STRONGBOX &&
+        (!isValidSBKeySize(transform, keySize))) {
+        state.SkipWithError(("Skipped for STRONGBOX: Keysize: " + std::to_string(keySize) +
+                             " is not supported in StrongBox for algorithm: " +
+                             keymintTest->getAlgorithmString(transform))
+                                    .c_str());
+        return;
+    }
     addDefaultLabel(state);
     if (!keymintTest->GenerateKey(transform, keySize)) {
         state.SkipWithError(
@@ -598,23 +843,34 @@
     AuthorizationSet out_params;
     AuthorizationSet in_params = keymintTest->getOperationParams(transform);
     string message = keymintTest->GenerateMessage(msgSize);
-    auto error = keymintTest->Begin(KeyPurpose::ENCRYPT, in_params, &out_params);
-    if (error != ErrorCode::OK) {
-        state.SkipWithError(
-                ("Encryption begin error, " + std::to_string(keymintTest->getError())).c_str());
-        return;
+    optional<string> encryptedMessage;
+
+    if (keymintTest->getAlgorithm(transform).value() == Algorithm::RSA) {
+        // Public key operation not supported, doing local Encryption
+        encryptedMessage = keymintTest->LocalRsaEncryptMessage(message, in_params);
+        if ((keySize / 8) != (*encryptedMessage).size()) {
+            state.SkipWithError("Local Encryption falied");
+            return;
+        }
+    } else {
+        auto error = keymintTest->Begin(KeyPurpose::ENCRYPT, in_params, &out_params);
+        if (error != ErrorCode::OK) {
+            state.SkipWithError(
+                    ("Encryption begin error, " + std::to_string(keymintTest->getError())).c_str());
+            return;
+        }
+        encryptedMessage = keymintTest->Process(message);
+        if (!encryptedMessage) {
+            state.SkipWithError(
+                    ("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
+            return;
+        }
+        in_params.push_back(out_params);
+        out_params.Clear();
     }
-    auto encryptedMessage = keymintTest->Process(message);
-    if (!encryptedMessage) {
-        state.SkipWithError(
-                ("Encryption error, " + std::to_string(keymintTest->getError())).c_str());
-        return;
-    }
-    in_params.push_back(out_params);
-    out_params.Clear();
     for (auto _ : state) {
         state.PauseTiming();
-        error = keymintTest->Begin(KeyPurpose::DECRYPT, in_params, &out_params);
+        auto error = keymintTest->Begin(KeyPurpose::DECRYPT, in_params, &out_params);
         if (error != ErrorCode::OK) {
             state.SkipWithError(
                     ("Decryption begin error, " + std::to_string(keymintTest->getError())).c_str());
@@ -649,9 +905,9 @@
 BENCHMARK_KM_CIPHER_ALL_MSGS(DESede/ECB/PKCS7Padding, 168);
 
 #define BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(transform, msgSize) \
-    BENCHMARK_KM_CIPHER(transform, 2048, msgSize)            \
-    BENCHMARK_KM_CIPHER(transform, 3072, msgSize)            \
-    BENCHMARK_KM_CIPHER(transform, 4096, msgSize)
+    BENCHMARK_KM_ASYM_CIPHER(transform, 2048, msgSize)            \
+    BENCHMARK_KM_ASYM_CIPHER(transform, 3072, msgSize)            \
+    BENCHMARK_KM_ASYM_CIPHER(transform, 4096, msgSize)
 
 BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/NoPadding, SMALL_MESSAGE_SIZE);
 BENCHMARK_KM_CIPHER_ALL_RSA_KEYS(RSA/ECB/PKCS1Padding, SMALL_MESSAGE_SIZE);
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 3f48320..d7226cd 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -78,6 +78,7 @@
     name: "libkeymint_remote_prov_support_test",
     srcs: ["remote_prov_utils_test.cpp"],
     static_libs: [
+        "android.hardware.security.rkp-V3-ndk",
         "libgmock",
         "libgtest_main",
     ],
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index ddc6ee0..01602ab 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -59,7 +59,10 @@
                                 const std::shared_ptr<IVibratorCallback>& callback) {
     LOG(VERBOSE) << "Vibrator on for timeoutMs: " << timeoutMs;
     if (callback != nullptr) {
-        std::thread([=] {
+        // Note that thread lambdas aren't using implicit capture [=], to avoid capturing "this",
+        // which may be asynchronously destructed.
+        // If "this" is needed, use [sharedThis = this->ref<Vibrator>()].
+        std::thread([timeoutMs, callback] {
             LOG(VERBOSE) << "Starting on on another thread";
             usleep(timeoutMs * 1000);
             LOG(VERBOSE) << "Notifying on complete";
@@ -87,7 +90,7 @@
     constexpr size_t kEffectMillis = 100;
 
     if (callback != nullptr) {
-        std::thread([=] {
+        std::thread([callback] {
             LOG(VERBOSE) << "Starting perform on another thread";
             usleep(kEffectMillis * 1000);
             LOG(VERBOSE) << "Notifying perform complete";
@@ -174,7 +177,8 @@
         }
     }
 
-    std::thread([=] {
+    // The thread may theoretically outlive the vibrator, so take a proper reference to it.
+    std::thread([sharedThis = this->ref<Vibrator>(), composite, callback] {
         LOG(VERBOSE) << "Starting compose on another thread";
 
         for (auto& e : composite) {
@@ -185,7 +189,7 @@
                          << e.scale;
 
             int32_t durationMs;
-            getPrimitiveDuration(e.primitive, &durationMs);
+            sharedThis->getPrimitiveDuration(e.primitive, &durationMs);
             usleep(durationMs * 1000);
         }
 
@@ -396,7 +400,7 @@
         }
     }
 
-    std::thread([=] {
+    std::thread([totalDuration, callback] {
         LOG(VERBOSE) << "Starting composePwle on another thread";
         usleep(totalDuration * 1000);
         if (callback != nullptr) {
diff --git a/vibrator/aidl/default/VibratorManager.cpp b/vibrator/aidl/default/VibratorManager.cpp
index 7cf9e6a..26edf5a 100644
--- a/vibrator/aidl/default/VibratorManager.cpp
+++ b/vibrator/aidl/default/VibratorManager.cpp
@@ -66,7 +66,7 @@
 ndk::ScopedAStatus VibratorManager::triggerSynced(
         const std::shared_ptr<IVibratorCallback>& callback) {
     LOG(INFO) << "Vibrator Manager trigger synced";
-    std::thread([=] {
+    std::thread([callback] {
         if (callback != nullptr) {
             LOG(INFO) << "Notifying perform complete";
             callback->onComplete();
diff --git a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
index 44fa3be..e8ed26a 100644
--- a/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorManagerTargetTest.cpp
@@ -96,6 +96,7 @@
     if (!(capabilities & IVibratorManager::CAP_SYNC)) return;
     if (vibratorIds.empty()) return;
     EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
+    EXPECT_TRUE(manager->cancelSynced().isOk());
 }
 
 TEST_P(VibratorAidl, PrepareSyncedEmptySetIsInvalid) {
@@ -208,6 +209,7 @@
         EXPECT_TRUE(manager->prepareSynced(vibratorIds).isOk());
         Status status = manager->triggerSynced(callback);
         EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
+        EXPECT_TRUE(manager->cancelSynced().isOk());
     }
 }