summaryrefslogtreecommitdiff
path: root/automotive
diff options
context:
space:
mode:
Diffstat (limited to 'automotive')
-rw-r--r--automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl4
-rw-r--r--automotive/evs/aidl/android/hardware/automotive/evs/IEvsCameraStream.aidl5
-rw-r--r--automotive/vehicle/2.0/default/Android.bp24
-rw-r--r--automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h53
-rw-r--r--automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultConfigSupportedPropertyIds_test.cpp56
-rw-r--r--automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp2
-rw-r--r--automotive/vehicle/aidl/impl/default_config/include/DefaultConfig.h745
-rw-r--r--automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp23
-rw-r--r--automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h5
-rw-r--r--automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h1
-rw-r--r--automotive/vehicle/aidl/impl/utils/common/include/VehiclePropertyStore.h31
-rw-r--r--automotive/vehicle/aidl/impl/utils/common/src/RecurrentTimer.cpp71
-rw-r--r--automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp10
-rw-r--r--automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp27
-rw-r--r--automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp61
15 files changed, 1053 insertions, 65 deletions
diff --git a/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl b/automotive/evs/aidl/android/hardware/automotive/evs/EvsEventDesc.aidl
index ebff98f077..3abdb54e6c 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 @@ parcelable EvsEventDesc {
@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 2c2b44caf5..c599d58635 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 @@ oneway interface IEvsCameraStream {
/**
* 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 0d3253b9f8..33e211ca8c 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -84,7 +84,10 @@ cc_library_static {
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 @@ cc_test {
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 cfbbbd3224..55a7720fc2 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 @@ const ConfigDeclaration kVehicleProperties[]{
},
.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 @@ const ConfigDeclaration kVehicleProperties[]{
},
},
#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 0000000000..aa05daafdc
--- /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 e3c8dd6c79..25a1940e0e 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 @@ class DefaultVhalImplTest : public ::testing::Test {
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 e00f775a04..622846a301 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::RawPropValues;
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;
@@ -124,6 +125,13 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.config =
{
+ .prop = toInt(VehicleProperty::INFO_VIN),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::STATIC,
+ },
+ .initialValue = {.stringValue = "1GCARVIN123456789"}},
+ {.config =
+ {
.prop = toInt(VehicleProperty::INFO_MAKE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::STATIC,
@@ -173,6 +181,557 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.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_MEMORY_SELECT),
+ .access = VehiclePropertyAccess::WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 3}}},
+ .initialValue = {.int32Values = {1}}},
+
+ {.config = {.prop = toInt(VehicleProperty::SEAT_MEMORY_SET),
+ .access = VehiclePropertyAccess::WRITE,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ .areaConfigs = {VehicleAreaConfig{.areaId = SEAT_1_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = SEAT_1_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = SEAT_2_LEFT,
+ .minInt32Value = 0,
+ .maxInt32Value = 3},
+ VehicleAreaConfig{.areaId = SEAT_2_RIGHT,
+ .minInt32Value = 0,
+ .maxInt32Value = 3}}},
+ .initialValue = {.int32Values = {1}}},
+
+ {.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,
@@ -352,8 +911,9 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.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 =
{
@@ -460,6 +1020,24 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.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,
@@ -486,6 +1064,12 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.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,
@@ -623,6 +1207,25 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
}}},
.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,
@@ -715,6 +1318,16 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.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,
@@ -774,6 +1387,76 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.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,
@@ -802,6 +1485,26 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
.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,
@@ -884,7 +1587,7 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.config =
{
- .prop = toInt(VehicleProperty::FOG_LIGHTS_STATE),
+ .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_STATE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
@@ -892,7 +1595,7 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.config =
{
- .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_STATE),
+ .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_STATE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
@@ -900,7 +1603,7 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.config =
{
- .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_STATE),
+ .prop = toInt(VehicleProperty::HAZARD_LIGHTS_STATE),
.access = VehiclePropertyAccess::READ,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
@@ -908,12 +1611,22 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.config =
{
- .prop = toInt(VehicleProperty::HAZARD_LIGHTS_STATE),
+ .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),
@@ -930,17 +1643,19 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
},
.initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+ // FOG_LIGHTS_SWITCH must not be implemented when FRONT_FOG_LIGHTS_SWITCH is implemented
{.config =
{
- .prop = toInt(VehicleProperty::FOG_LIGHTS_SWITCH),
+ .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_SWITCH),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
.initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+ // FOG_LIGHTS_SWITCH must not be implemented when REAR_FOG_LIGHTS_SWITCH is implemented
{.config =
{
- .prop = toInt(VehicleProperty::FRONT_FOG_LIGHTS_SWITCH),
+ .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_SWITCH),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
@@ -948,7 +1663,7 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.config =
{
- .prop = toInt(VehicleProperty::REAR_FOG_LIGHTS_SWITCH),
+ .prop = toInt(VehicleProperty::HAZARD_LIGHTS_SWITCH),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
@@ -956,11 +1671,21 @@ const std::vector<ConfigDeclaration> kVehicleProperties = {
{.config =
{
- .prop = toInt(VehicleProperty::HAZARD_LIGHTS_SWITCH),
+ .prop = toInt(VehicleProperty::CABIN_LIGHTS_SWITCH),
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE,
},
- .initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+ .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 =
{
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 b64c1a65cc..20c34aa12e 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 @@ VhalResult<void> FakeVehicleHardware::setApPowerStateReport(const VehiclePropVal
[[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 @@ StatusCode FakeVehicleHardware::updateSampleRate(int32_t propId, int32_t areaId,
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/RecurrentTimer.h b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
index 5f0f7161c2..cd2b72713c 100644
--- a/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
+++ b/automotive/vehicle/aidl/impl/utils/common/include/RecurrentTimer.h
@@ -83,8 +83,9 @@ class RecurrentTimer final {
// each time we might introduce outdated elements to the top. We must make sure the heap is
// always valid from the top.
void removeInvalidCallbackLocked() REQUIRES(mLock);
- // Pops the next closest callback (must be valid) from the heap.
- std::unique_ptr<CallbackInfo> popNextCallbackLocked() REQUIRES(mLock);
+ // Gets the next calblack to run (must be valid) from the heap, update its nextTime and put
+ // it back to the heap.
+ std::shared_ptr<Callback> getNextCallbackLocked(int64_t now) REQUIRES(mLock);
};
} // namespace vehicle
diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleHalTypes.h
index a7fcdcf99d..8bc3c20ad8 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 ddc4f684aa..3d25cd3a41 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 @@ class VehiclePropertyStore final {
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 @@ class VehiclePropertyStore final {
// '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 8521c4db7c..908564c2ff 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 @@ void RecurrentTimer::registerTimerCallback(int64_t intervalInNano,
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;
@@ -101,68 +101,71 @@ void RecurrentTimer::removeInvalidCallbackLocked() {
}
}
-std::unique_ptr<RecurrentTimer::CallbackInfo> RecurrentTimer::popNextCallbackLocked() {
+std::shared_ptr<RecurrentTimer::Callback> RecurrentTimer::getNextCallbackLocked(int64_t now) {
std::pop_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
- std::unique_ptr<CallbackInfo> info = std::move(mCallbackQueue[mCallbackQueue.size() - 1]);
- mCallbackQueue.pop_back();
+ auto& callbackInfo = mCallbackQueue[mCallbackQueue.size() - 1];
+ auto nextCallback = callbackInfo->callback;
+ // intervalCount is the number of interval we have to advance until we pass now.
+ size_t intervalCount = (now - callbackInfo->nextTime) / callbackInfo->interval + 1;
+ callbackInfo->nextTime += intervalCount * callbackInfo->interval;
+ std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
+
// Make sure the first element is always valid.
removeInvalidCallbackLocked();
- return info;
+
+ return nextCallback;
}
void RecurrentTimer::loop() {
- std::unique_lock<std::mutex> uniqueLock(mLock);
-
+ std::vector<std::shared_ptr<Callback>> callbacksToRun;
while (true) {
- // Wait until the timer exits or we have at least one recurrent callback.
- mCond.wait(uniqueLock, [this] {
- ScopedLockAssertion lockAssertion(mLock);
- return mStopRequested || mCallbackQueue.size() != 0;
- });
-
- int64_t interval;
{
+ std::unique_lock<std::mutex> uniqueLock(mLock);
ScopedLockAssertion lockAssertion(mLock);
+ // Wait until the timer exits or we have at least one recurrent callback.
+ mCond.wait(uniqueLock, [this] {
+ ScopedLockAssertion lockAssertion(mLock);
+ return mStopRequested || mCallbackQueue.size() != 0;
+ });
+
+ int64_t interval;
if (mStopRequested) {
return;
}
// 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 {
interval = 0;
}
- }
- // Wait for the next event or the timer exits.
- if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] {
- ScopedLockAssertion lockAssertion(mLock);
- return mStopRequested;
- })) {
- return;
- }
+ // Wait for the next event or the timer exits.
+ if (mCond.wait_for(uniqueLock, std::chrono::nanoseconds(interval), [this] {
+ ScopedLockAssertion lockAssertion(mLock);
+ return mStopRequested;
+ })) {
+ return;
+ }
- {
- ScopedLockAssertion lockAssertion(mLock);
- int64_t now = elapsedRealtimeNano();
+ now = uptimeNanos();
+ callbacksToRun.clear();
while (mCallbackQueue.size() > 0) {
int64_t nextTime = mCallbackQueue[0]->nextTime;
if (nextTime > now) {
break;
}
- std::unique_ptr<CallbackInfo> info = popNextCallbackLocked();
- info->nextTime += info->interval;
-
- auto callback = info->callback;
- mCallbackQueue.push_back(std::move(info));
- std::push_heap(mCallbackQueue.begin(), mCallbackQueue.end(), CallbackInfo::cmp);
-
- (*callback)();
+ callbacksToRun.push_back(getNextCallbackLocked(now));
}
}
+
+ // Do not execute the callback while holding the lock.
+ for (size_t i = 0; i < callbacksToRun.size(); i++) {
+ (*callbacksToRun[i])();
+ }
}
}
diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehiclePropertyStore.cpp
index c8fb994684..646dc0e618 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 @@ void VehiclePropertyStore::registerProperty(const VehiclePropConfig& config,
}
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 @@ VhalResult<void> VehiclePropertyStore::writeValue(VehiclePropValuePool::Recyclab
}
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/RecurrentTimerTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
index a033a248cd..141efc135b 100644
--- a/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
+++ b/automotive/vehicle/aidl/impl/utils/common/test/RecurrentTimerTest.cpp
@@ -186,6 +186,33 @@ TEST_F(RecurrentTimerTest, testRegisterSameCallbackMultipleTimes) {
ASSERT_EQ(countTimerCallbackQueue(&timer), static_cast<size_t>(0));
}
+TEST_F(RecurrentTimerTest, testRegisterCallbackMultipleTimesNoDeadLock) {
+ // We want to avoid the following situation:
+ // Caller holds a lock while calling registerTimerCallback, registerTimerCallback will try
+ // to obtain an internal lock inside timer.
+ // Meanwhile an recurrent action happens with timer holding an internal lock. The action
+ // tries to obtain the lock currently hold by the caller.
+ // The solution is that while calling recurrent actions, timer must not hold the internal lock.
+
+ std::unique_ptr<RecurrentTimer> timer = std::make_unique<RecurrentTimer>();
+ std::mutex lock;
+ for (size_t i = 0; i < 1000; i++) {
+ std::scoped_lock<std::mutex> lockGuard(lock);
+ auto action = std::make_shared<RecurrentTimer::Callback>([&lock] {
+ // While calling this function, the timer must not hold lock in order not to dead
+ // lock.
+ std::scoped_lock<std::mutex> lockGuard(lock);
+ });
+ // 10ms
+ int64_t interval = 10'000'000;
+ timer->registerTimerCallback(interval, action);
+ // Sleep for a little while to let the recurrent actions begin.
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ }
+ // Make sure we stop the timer before we destroy lock.
+ timer.reset();
+}
+
} // namespace vehicle
} // namespace automotive
} // namespace hardware
diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehiclePropertyStoreTest.cpp
index 4d6f811795..fea5034db9 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 @@ TEST_F(VehiclePropertyStoreTest, testPropertyChangeCallbackNoUpdate) {
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