Loading automotive/vehicle/2.0/utils/UserHalHelper.cpp +15 −4 Original line number Diff line number Diff line Loading @@ -60,11 +60,22 @@ Result<void> parseUserInfo(const hidl_vec<int32_t>& int32Values, size_t startPos << int32Values.size(); } userInfo->userId = int32Values[startPos]; auto userFlags = verifyAndCast<UserFlags>(int32Values[startPos + 1]); if (!userFlags.ok()) { return Error() << "Invalid user flags: " << userFlags.error(); } userInfo->flags = *userFlags; int32_t intUserFlags = int32Values[startPos + 1]; int32_t expectedUserFlags = 0; for (const auto& v : hidl_enum_range<UserFlags>()) { int32_t intEnumUserFlag = static_cast<int32_t>(v); if ((intUserFlags & intEnumUserFlag) != 0) { expectedUserFlags |= intEnumUserFlag; } } if (intUserFlags != expectedUserFlags) { return Error() << "Invalid user flags: " << intUserFlags << ", must be '|' of UserFlags"; } // intUserFlags is actually not a valid UserFlags enum, instead, it is a 'bit or' of possible // multiple UserFlags. However, because the HAL interface was defined incorrectly, we have to // cast it to UserFlags here, which is defined behavior because the underlying type for // UserFlags is int32_t and our intUserFlags is within the range of int32_t. userInfo->flags = static_cast<UserFlags>(intUserFlags); return {}; } Loading automotive/vehicle/2.0/utils/tests/UserHalHelper_test.cpp +57 −1 Original line number Diff line number Diff line Loading @@ -54,6 +54,10 @@ constexpr int32_t VEHICLE_REQUEST = static_cast<int32_t>(SwitchUserMessageType:: constexpr int32_t GUEST_USER = static_cast<int32_t>(UserFlags::GUEST); constexpr int32_t NONE_USER = static_cast<int32_t>(UserFlags::NONE); constexpr int32_t SYSTEM_USER = static_cast<int32_t>(UserFlags::SYSTEM); constexpr int32_t ADMIN_USER = static_cast<int32_t>(UserFlags::ADMIN); constexpr int32_t SYSTEM_ADMIN_USER = static_cast<int32_t>(UserFlags::SYSTEM | UserFlags::ADMIN); // 0x1111 is not a valid UserFlags combination. constexpr int32_t INVALID_USER_FLAG = 0x1111; constexpr int32_t USER_ID_ASSOC_KEY_FOB = static_cast<int32_t>(UserIdentificationAssociationType::KEY_FOB); Loading @@ -72,7 +76,7 @@ constexpr int32_t USER_ID_ASSOC_NO_USER = } // namespace TEST(UserHalHelperTest, TestToInitialUserInfoRequest) { TEST(UserHalHelperTest, TestToInitialUserInfoRequestSystemUser) { VehiclePropValue propValue{ .prop = INITIAL_USER_INFO, .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, SYSTEM_USER, Loading @@ -92,6 +96,58 @@ TEST(UserHalHelperTest, TestToInitialUserInfoRequest) { EXPECT_THAT(actual.value(), Eq(expected)); } TEST(UserHalHelperTest, TestToInitialUserInfoRequestAdminUser) { VehiclePropValue propValue{ .prop = INITIAL_USER_INFO, .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, ADMIN_USER, 10, NONE_USER}}, }; InitialUserInfoRequest expected{ .requestId = 23, .requestType = InitialUserInfoRequestType::FIRST_BOOT_AFTER_OTA, .usersInfo = {{10, UserFlags::NONE}, 2, {{0, UserFlags::ADMIN}, {10, UserFlags::NONE}}}, }; auto actual = toInitialUserInfoRequest(propValue); ASSERT_TRUE(actual.ok()) << actual.error().message(); EXPECT_THAT(actual.value(), Eq(expected)); } TEST(UserHalHelperTest, TestToInitialUserInfoRequestUserFlagsBitCombination) { // SYSTEM_ADMIN_USER is two UserFlags combined and is itself not a defined UserFlags enum. VehiclePropValue propValue{ .prop = INITIAL_USER_INFO, .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, SYSTEM_ADMIN_USER, 10, NONE_USER}}, }; InitialUserInfoRequest expected{ .requestId = 23, .requestType = InitialUserInfoRequestType::FIRST_BOOT_AFTER_OTA, .usersInfo = {{10, UserFlags::NONE}, 2, {{0, static_cast<UserFlags>(SYSTEM_ADMIN_USER)}, {10, UserFlags::NONE}}}, }; auto actual = toInitialUserInfoRequest(propValue); ASSERT_TRUE(actual.ok()) << actual.error().message(); EXPECT_THAT(actual.value(), Eq(expected)); } TEST(UserHalHelperTest, TestToInitialUserInfoRequestUserInvalidUserFlag) { // 0x1111 is not a valid UserFlags flag combination. VehiclePropValue propValue{ .prop = INITIAL_USER_INFO, .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, INVALID_USER_FLAG, 10, NONE_USER}}, }; auto actual = toInitialUserInfoRequest(propValue); EXPECT_FALSE(actual.ok()) << "No error returned on invalid user flags"; } TEST(UserHalHelperTest, TestFailsToInitialUserInfoRequestWithMismatchingPropType) { VehiclePropValue propValue{ .prop = INT32_MAX, Loading automotive/vehicle/TEST_MAPPING +6 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,12 @@ }, { "name": "VehicleHalVehicleUtilsTest" }, { "name": "FakeVehicleHardwareTest" }, { "name": "FakeVehicleHalValueGeneratorsTest" } ] } automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -105,7 +105,7 @@ enum VehicleProperty { EV_BATTERY_DISPLAY_UNITS = 289408515, FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 287311364, VEHICLE_SPEED_DISPLAY_UNITS = 289408517, EPOCH_TIME = 290457094, ANDROID_EPOCH_TIME = 290457094, STORAGE_ENCRYPTION_BINDING_SEED = 292554247, ENV_OUTSIDE_TEMPERATURE = 291505923, AP_POWER_STATE_REQ = 289475072, Loading automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl +18 −10 Original line number Diff line number Diff line Loading @@ -1035,24 +1035,32 @@ enum VehicleProperty { VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000 + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32 /** * Current date and time, encoded as Unix time (in milliseconds). * Current date and time, encoded as Epoch time (in milliseconds). * This value denotes the number of milliseconds seconds that have * elapsed since 1/1/1970 UTC. * * Reading this value will give you the system’s time. This can be * useful to synchronize other vehicle systems (dash clock etc). * CarServices will write to this value to give VHAL the Android system's * time, if the VHAL supports this property. This can be useful to * synchronize other vehicle systems (dash clock etc) with Android's time. * * Writing this value will update the ‘ExternalTimeSuggestion’ * value (if enabled). This value may be consumed by the “Time * Detector Service”, if other sources do not have a higher * priority. For information on how to adjust time source * priorities see Time Detector Service documentation. * AAOS writes to this property once during boot, and * will thereafter write only when some time-source changes are propagated. * AAOS will fill in VehiclePropValue.timestamp correctly. * Note that AAOS will not send updates for natural elapse of time. * int64Values[0] = provided Unix time (in milliseconds) * * Note that the property may take >0 ms to get propagated through the stack * and, having a timestamped property helps reduce any time drift. So, * for all writes to the property, the timestamp can be used to negate this * drift: * drift = elapsedTime - PropValue.timestamp * effectiveTime = PropValue.value.int64Values[0] + drift * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:READ_WRITE * @access VehiclePropertyAccess:WRITE_ONLY * @unit VehicleUnit:MILLI_SECS */ EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000 ANDROID_EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000 + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64 /** * External encryption binding seed. Loading Loading
automotive/vehicle/2.0/utils/UserHalHelper.cpp +15 −4 Original line number Diff line number Diff line Loading @@ -60,11 +60,22 @@ Result<void> parseUserInfo(const hidl_vec<int32_t>& int32Values, size_t startPos << int32Values.size(); } userInfo->userId = int32Values[startPos]; auto userFlags = verifyAndCast<UserFlags>(int32Values[startPos + 1]); if (!userFlags.ok()) { return Error() << "Invalid user flags: " << userFlags.error(); } userInfo->flags = *userFlags; int32_t intUserFlags = int32Values[startPos + 1]; int32_t expectedUserFlags = 0; for (const auto& v : hidl_enum_range<UserFlags>()) { int32_t intEnumUserFlag = static_cast<int32_t>(v); if ((intUserFlags & intEnumUserFlag) != 0) { expectedUserFlags |= intEnumUserFlag; } } if (intUserFlags != expectedUserFlags) { return Error() << "Invalid user flags: " << intUserFlags << ", must be '|' of UserFlags"; } // intUserFlags is actually not a valid UserFlags enum, instead, it is a 'bit or' of possible // multiple UserFlags. However, because the HAL interface was defined incorrectly, we have to // cast it to UserFlags here, which is defined behavior because the underlying type for // UserFlags is int32_t and our intUserFlags is within the range of int32_t. userInfo->flags = static_cast<UserFlags>(intUserFlags); return {}; } Loading
automotive/vehicle/2.0/utils/tests/UserHalHelper_test.cpp +57 −1 Original line number Diff line number Diff line Loading @@ -54,6 +54,10 @@ constexpr int32_t VEHICLE_REQUEST = static_cast<int32_t>(SwitchUserMessageType:: constexpr int32_t GUEST_USER = static_cast<int32_t>(UserFlags::GUEST); constexpr int32_t NONE_USER = static_cast<int32_t>(UserFlags::NONE); constexpr int32_t SYSTEM_USER = static_cast<int32_t>(UserFlags::SYSTEM); constexpr int32_t ADMIN_USER = static_cast<int32_t>(UserFlags::ADMIN); constexpr int32_t SYSTEM_ADMIN_USER = static_cast<int32_t>(UserFlags::SYSTEM | UserFlags::ADMIN); // 0x1111 is not a valid UserFlags combination. constexpr int32_t INVALID_USER_FLAG = 0x1111; constexpr int32_t USER_ID_ASSOC_KEY_FOB = static_cast<int32_t>(UserIdentificationAssociationType::KEY_FOB); Loading @@ -72,7 +76,7 @@ constexpr int32_t USER_ID_ASSOC_NO_USER = } // namespace TEST(UserHalHelperTest, TestToInitialUserInfoRequest) { TEST(UserHalHelperTest, TestToInitialUserInfoRequestSystemUser) { VehiclePropValue propValue{ .prop = INITIAL_USER_INFO, .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, SYSTEM_USER, Loading @@ -92,6 +96,58 @@ TEST(UserHalHelperTest, TestToInitialUserInfoRequest) { EXPECT_THAT(actual.value(), Eq(expected)); } TEST(UserHalHelperTest, TestToInitialUserInfoRequestAdminUser) { VehiclePropValue propValue{ .prop = INITIAL_USER_INFO, .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, ADMIN_USER, 10, NONE_USER}}, }; InitialUserInfoRequest expected{ .requestId = 23, .requestType = InitialUserInfoRequestType::FIRST_BOOT_AFTER_OTA, .usersInfo = {{10, UserFlags::NONE}, 2, {{0, UserFlags::ADMIN}, {10, UserFlags::NONE}}}, }; auto actual = toInitialUserInfoRequest(propValue); ASSERT_TRUE(actual.ok()) << actual.error().message(); EXPECT_THAT(actual.value(), Eq(expected)); } TEST(UserHalHelperTest, TestToInitialUserInfoRequestUserFlagsBitCombination) { // SYSTEM_ADMIN_USER is two UserFlags combined and is itself not a defined UserFlags enum. VehiclePropValue propValue{ .prop = INITIAL_USER_INFO, .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, SYSTEM_ADMIN_USER, 10, NONE_USER}}, }; InitialUserInfoRequest expected{ .requestId = 23, .requestType = InitialUserInfoRequestType::FIRST_BOOT_AFTER_OTA, .usersInfo = {{10, UserFlags::NONE}, 2, {{0, static_cast<UserFlags>(SYSTEM_ADMIN_USER)}, {10, UserFlags::NONE}}}, }; auto actual = toInitialUserInfoRequest(propValue); ASSERT_TRUE(actual.ok()) << actual.error().message(); EXPECT_THAT(actual.value(), Eq(expected)); } TEST(UserHalHelperTest, TestToInitialUserInfoRequestUserInvalidUserFlag) { // 0x1111 is not a valid UserFlags flag combination. VehiclePropValue propValue{ .prop = INITIAL_USER_INFO, .value = {.int32Values = {23, FIRST_BOOT_AFTER_OTA, 10, NONE_USER, 2, 0, INVALID_USER_FLAG, 10, NONE_USER}}, }; auto actual = toInitialUserInfoRequest(propValue); EXPECT_FALSE(actual.ok()) << "No error returned on invalid user flags"; } TEST(UserHalHelperTest, TestFailsToInitialUserInfoRequestWithMismatchingPropType) { VehiclePropValue propValue{ .prop = INT32_MAX, Loading
automotive/vehicle/TEST_MAPPING +6 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,12 @@ }, { "name": "VehicleHalVehicleUtilsTest" }, { "name": "FakeVehicleHardwareTest" }, { "name": "FakeVehicleHalValueGeneratorsTest" } ] }
automotive/vehicle/aidl/aidl_api/android.hardware.automotive.vehicle/current/android/hardware/automotive/vehicle/VehicleProperty.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -105,7 +105,7 @@ enum VehicleProperty { EV_BATTERY_DISPLAY_UNITS = 289408515, FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME = 287311364, VEHICLE_SPEED_DISPLAY_UNITS = 289408517, EPOCH_TIME = 290457094, ANDROID_EPOCH_TIME = 290457094, STORAGE_ENCRYPTION_BINDING_SEED = 292554247, ENV_OUTSIDE_TEMPERATURE = 291505923, AP_POWER_STATE_REQ = 289475072, Loading
automotive/vehicle/aidl/android/hardware/automotive/vehicle/VehicleProperty.aidl +18 −10 Original line number Diff line number Diff line Loading @@ -1035,24 +1035,32 @@ enum VehicleProperty { VEHICLE_SPEED_DISPLAY_UNITS = 0x0605 + 0x10000000 + 0x01000000 + 0x00400000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT32 /** * Current date and time, encoded as Unix time (in milliseconds). * Current date and time, encoded as Epoch time (in milliseconds). * This value denotes the number of milliseconds seconds that have * elapsed since 1/1/1970 UTC. * * Reading this value will give you the system’s time. This can be * useful to synchronize other vehicle systems (dash clock etc). * CarServices will write to this value to give VHAL the Android system's * time, if the VHAL supports this property. This can be useful to * synchronize other vehicle systems (dash clock etc) with Android's time. * * Writing this value will update the ‘ExternalTimeSuggestion’ * value (if enabled). This value may be consumed by the “Time * Detector Service”, if other sources do not have a higher * priority. For information on how to adjust time source * priorities see Time Detector Service documentation. * AAOS writes to this property once during boot, and * will thereafter write only when some time-source changes are propagated. * AAOS will fill in VehiclePropValue.timestamp correctly. * Note that AAOS will not send updates for natural elapse of time. * int64Values[0] = provided Unix time (in milliseconds) * * Note that the property may take >0 ms to get propagated through the stack * and, having a timestamped property helps reduce any time drift. So, * for all writes to the property, the timestamp can be used to negate this * drift: * drift = elapsedTime - PropValue.timestamp * effectiveTime = PropValue.value.int64Values[0] + drift * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @access VehiclePropertyAccess:READ_WRITE * @access VehiclePropertyAccess:WRITE_ONLY * @unit VehicleUnit:MILLI_SECS */ EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000 ANDROID_EPOCH_TIME = 0x0606 + 0x10000000 + 0x01000000 + 0x00500000, // VehiclePropertyGroup:SYSTEM,VehicleArea:GLOBAL,VehiclePropertyType:INT64 /** * External encryption binding seed. Loading