From 2558bf60c4e8200c091b408d5996f9110c6bc84c Mon Sep 17 00:00:00 2001 From: Yu Shan Date: Wed, 22 May 2024 17:44:32 -0700 Subject: [PATCH] Allow using property name in debug command. Add stringToPropertyId to VehicleUtils and use that in FakeVehicleHardware to support commands like "--set PERF_VEHICLE_SPEED". Test: atest VehicleUtilsTest FakeVehicleHardwareTest Bug: 342260344 Merged-In: If317929376eb18bb0c28f87c4d7a3321c58d72b1 Change-Id: If317929376eb18bb0c28f87c4d7a3321c58d72b1 --- .../hardware/include/FakeVehicleHardware.h | 22 +++++----- .../hardware/src/FakeVehicleHardware.cpp | 16 ++++++-- .../hardware/test/FakeVehicleHardwareTest.cpp | 23 +++++++++-- .../impl/utils/common/include/VehicleUtils.h | 4 ++ .../impl/utils/common/src/VehicleUtils.cpp | 41 +++++++++++++++++++ .../utils/common/test/VehicleUtilsTest.cpp | 17 ++++++++ 6 files changed, 106 insertions(+), 17 deletions(-) diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h index 583e40b369..79d3e77f84 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/include/FakeVehicleHardware.h @@ -269,16 +269,6 @@ class FakeVehicleHardware : public IVehicleHardware { std::string dumpInjectEvent(const std::vector& options); std::string dumpSubscriptions(); - template - android::base::Result safelyParseInt(int index, const std::string& s) { - T out; - if (!::android::base::ParseInt(s, &out)) { - return android::base::Error() << android::base::StringPrintf( - "non-integer argument at index %d: %s\n", index, s.c_str()); - } - return out; - } - android::base::Result safelyParseFloat(int index, const std::string& s); std::vector getOptionValues(const std::vector& options, size_t* index); android::base::Result @@ -325,6 +315,18 @@ class FakeVehicleHardware : public IVehicleHardware { const aidl::android::hardware::automotive::vehicle::VehiclePropConfig& vehiclePropConfig, int32_t areaId); + template + static android::base::Result safelyParseInt(int index, const std::string& s) { + T out; + if (!::android::base::ParseInt(s, &out)) { + return android::base::Error() << android::base::StringPrintf( + "non-integer argument at index %d: %s\n", index, s.c_str()); + } + return out; + } + static android::base::Result safelyParseFloat(int index, const std::string& s); + static android::base::Result parsePropId(const std::vector& options, + size_t index); }; } // namespace fake 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 e057d3dfe4..200e3d3964 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/src/FakeVehicleHardware.cpp @@ -1892,6 +1892,16 @@ Result FakeVehicleHardware::checkArgumentsSize(const std::vector FakeVehicleHardware::parsePropId(const std::vector& options, + size_t index) { + const std::string& propIdStr = options[index]; + auto result = stringToPropId(propIdStr); + if (result.ok()) { + return result; + } + return safelyParseInt(index, propIdStr); +} + std::string FakeVehicleHardware::dumpSpecificProperty(const std::vector& options) { if (auto result = checkArgumentsSize(options, /*minSize=*/2); !result.ok()) { return getErrorMsg(result); @@ -1902,7 +1912,7 @@ std::string FakeVehicleHardware::dumpSpecificProperty(const std::vector(i, options[i]); + auto propResult = parsePropId(options, i); if (!propResult.ok()) { msg += getErrorMsg(propResult); continue; @@ -1938,9 +1948,9 @@ Result FakeVehicleHardware::parsePropOptions( // --set/get/inject-event PROP [-f f1 f2...] [-i i1 i2...] [-i64 i1 i2...] [-s s1 s2...] // [-b b1 b2...] [-a a] [-t timestamp] size_t optionIndex = 1; - auto result = safelyParseInt(optionIndex, options[optionIndex]); + auto result = parsePropId(options, optionIndex); if (!result.ok()) { - return Error() << StringPrintf("Property value: \"%s\" is not a valid int: %s\n", + return Error() << StringPrintf("Property ID/Name: \"%s\" is not valid: %s\n", options[optionIndex].c_str(), getErrorMsg(result).c_str()); } VehiclePropValue prop = {}; diff --git a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp index cab33e10e8..0924360b9f 100644 --- a/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp +++ b/automotive/vehicle/aidl/impl/fake_impl/hardware/test/FakeVehicleHardwareTest.cpp @@ -2613,6 +2613,23 @@ TEST_F(FakeVehicleHardwareTest, testDumpSpecificProperties) { prop1.c_str(), prop2.c_str(), prop2.c_str()))); } +TEST_F(FakeVehicleHardwareTest, testDumpSpecificPropertiesWithName) { + std::vector options; + options.push_back("--get"); + std::string prop1 = "INFO_FUEL_CAPACITY"; + std::string prop2 = "TIRE_PRESSURE"; + int prop1Int = toInt(VehicleProperty::INFO_FUEL_CAPACITY); + int prop2Int = toInt(VehicleProperty::TIRE_PRESSURE); + options.push_back(prop1); + options.push_back(prop2); + DumpResult result = getHardware()->dump(options); + ASSERT_FALSE(result.callerShouldDumpState); + ASSERT_NE(result.buffer, ""); + ASSERT_THAT(result.buffer, + ContainsRegex(StringPrintf("1:.*prop: %d.*\n2-0:.*prop: %d.*\n2-1:.*prop: %d.*\n", + prop1Int, prop2Int, prop2Int))); +} + TEST_F(FakeVehicleHardwareTest, testDumpSpecificPropertiesInvalidProp) { std::vector options; options.push_back("--get"); @@ -2766,6 +2783,7 @@ std::vector GenSetPropParams() { std::string infoMakeProperty = std::to_string(toInt(VehicleProperty::INFO_MAKE)); return { {"success_set_string", {"--set", infoMakeProperty, "-s", CAR_MAKE}, true}, + {"success_set_with_name", {"--set", "INFO_MAKE", "-s", CAR_MAKE}, true}, {"success_set_bytes", {"--set", infoMakeProperty, "-b", "0xdeadbeef"}, true}, {"success_set_bytes_caps", {"--set", infoMakeProperty, "-b", "0xDEADBEEF"}, true}, {"success_set_int", {"--set", infoMakeProperty, "-i", "2147483647"}, true}, @@ -2790,10 +2808,7 @@ std::vector GenSetPropParams() { false, "No values specified"}, {"fail_unknown_options", {"--set", infoMakeProperty, "-abcd"}, false, "Unknown option"}, - {"fail_invalid_property", - {"--set", "not valid", "-s", CAR_MAKE}, - false, - "not a valid int"}, + {"fail_invalid_property", {"--set", "not_valid", "-s", CAR_MAKE}, false, "not valid"}, {"fail_duplicate_string", {"--set", infoMakeProperty, "-s", CAR_MAKE, "-s", CAR_MAKE}, false, diff --git a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h index aca725df56..f48bb2aa34 100644 --- a/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h +++ b/automotive/vehicle/aidl/impl/utils/common/include/VehicleUtils.h @@ -328,11 +328,15 @@ struct PropIdAreaIdHash { } }; +// This is for debug purpose only. inline std::string propIdToString(int32_t propId) { return toString( static_cast(propId)); } +// This is for debug purpose only. +android::base::Result stringToPropId(const std::string& propName); + template void roundToNearestResolution(std::vector& arrayToSanitize, float resolution) { if (resolution == 0) { diff --git a/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp b/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp index f85728d4b6..4d06e4e32d 100644 --- a/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp +++ b/automotive/vehicle/aidl/impl/utils/common/src/VehicleUtils.cpp @@ -16,14 +16,18 @@ #include "VehicleUtils.h" +#include + namespace android { namespace hardware { namespace automotive { namespace vehicle { using ::aidl::android::hardware::automotive::vehicle::StatusCode; +using ::aidl::android::hardware::automotive::vehicle::toString; using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig; using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig; +using ::aidl::android::hardware::automotive::vehicle::VehicleProperty; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup; using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyType; using ::aidl::android::hardware::automotive::vehicle::VehiclePropValue; @@ -31,6 +35,39 @@ using ::android::base::Error; using ::android::base::Result; using ::ndk::ScopedAStatus; +namespace { + +class PropertyIdByNameSingleton { + public: + static PropertyIdByNameSingleton& getInstance() { + static PropertyIdByNameSingleton instance; + return instance; + } + + Result getPropertyId(const std::string& name) { + auto it = mPropertyIdByName.find(name); + if (it == mPropertyIdByName.end()) { + return Error(); + } + return it->second; + } + + PropertyIdByNameSingleton(PropertyIdByNameSingleton const&) = delete; + void operator=(PropertyIdByNameSingleton const&) = delete; + + private: + std::unordered_map mPropertyIdByName; + + PropertyIdByNameSingleton() { + constexpr auto values = ndk::internal::enum_values; + for (unsigned int i = 0; i < values.size(); i++) { + mPropertyIdByName.emplace(toString(values[i]), toInt(values[i])); + } + } +}; + +} // namespace + Result checkPropValue(const VehiclePropValue& value, const VehiclePropConfig* config) { int32_t property = value.prop; VehiclePropertyType type = getPropType(property); @@ -213,6 +250,10 @@ std::string VhalError::print() const { return aidl::android::hardware::automotive::vehicle::toString(mCode); } +Result stringToPropId(const std::string& propName) { + return PropertyIdByNameSingleton::getInstance().getPropertyId(propName); +} + } // namespace vehicle } // namespace automotive } // namespace hardware diff --git a/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp b/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp index 9abb2a2fe6..1048877201 100644 --- a/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp +++ b/automotive/vehicle/aidl/impl/utils/common/test/VehicleUtilsTest.cpp @@ -770,6 +770,23 @@ TEST(VehicleUtilsTest, testVhalError) { ASSERT_EQ(result.error().message(), "error message: INVALID_ARG"); } +TEST(VehicleUtilsTest, testPropIdToString) { + ASSERT_EQ(propIdToString(toInt(VehicleProperty::PERF_VEHICLE_SPEED)), "PERF_VEHICLE_SPEED"); +} + +TEST(VehicleUtilsTest, testStringToPropId) { + auto result = stringToPropId("PERF_VEHICLE_SPEED"); + + ASSERT_TRUE(result.ok()); + ASSERT_EQ(result.value(), toInt(VehicleProperty::PERF_VEHICLE_SPEED)); +} + +TEST(VehicleUtilsTest, testStringToPropId_InvalidName) { + auto result = stringToPropId("PERF_VEHICLE_SPEED12345"); + + ASSERT_FALSE(result.ok()); +} + class InvalidPropValueTest : public testing::TestWithParam {}; INSTANTIATE_TEST_SUITE_P(InvalidPropValueTests, InvalidPropValueTest,