mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:23:37 +00:00
Merge "Allow using area name in debug command." into main
This commit is contained in:
@@ -327,6 +327,8 @@ class FakeVehicleHardware : public IVehicleHardware {
|
||||
static android::base::Result<float> safelyParseFloat(int index, const std::string& s);
|
||||
static android::base::Result<int32_t> parsePropId(const std::vector<std::string>& options,
|
||||
size_t index);
|
||||
static android::base::Result<int32_t> parseAreaId(const std::vector<std::string>& options,
|
||||
size_t index, int32_t propId);
|
||||
};
|
||||
|
||||
} // namespace fake
|
||||
|
||||
@@ -1902,6 +1902,37 @@ Result<int32_t> FakeVehicleHardware::parsePropId(const std::vector<std::string>&
|
||||
return safelyParseInt<int32_t>(index, propIdStr);
|
||||
}
|
||||
|
||||
// Parses areaId option ("-a"). It can be an Integer or a string in the form of "AREA_1" or
|
||||
// "AREA_1 | AREA_2 | ..."
|
||||
Result<int32_t> FakeVehicleHardware::parseAreaId(const std::vector<std::string>& options,
|
||||
size_t index, int32_t propId) {
|
||||
const std::string& areaIdStr = options[index];
|
||||
auto result = safelyParseInt<int32_t>(index, areaIdStr);
|
||||
if (result.ok()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check for pattern matching "AREA_1 | AREA_2 | AREA_3".
|
||||
std::regex pattern(R"(^\w+(?:( )?\|( )?\w+)*$)");
|
||||
std::smatch match;
|
||||
int32_t areaId = 0;
|
||||
if (!std::regex_match(areaIdStr, match, pattern)) {
|
||||
return result;
|
||||
}
|
||||
pattern = R"(\w+)";
|
||||
|
||||
std::sregex_iterator end;
|
||||
for (std::sregex_iterator it(areaIdStr.begin(), areaIdStr.end(), pattern); it != end; it++) {
|
||||
// Parse each areas contained in this areaId.
|
||||
auto result = stringToArea(it->str(), propId);
|
||||
if (!result.ok()) {
|
||||
return result;
|
||||
}
|
||||
areaId |= result.value();
|
||||
}
|
||||
return areaId;
|
||||
}
|
||||
|
||||
std::string FakeVehicleHardware::dumpSpecificProperty(const std::vector<std::string>& options) {
|
||||
if (auto result = checkArgumentsSize(options, /*minSize=*/2); !result.ok()) {
|
||||
return getErrorMsg(result);
|
||||
@@ -1958,6 +1989,7 @@ Result<VehiclePropValue> FakeVehicleHardware::parsePropOptions(
|
||||
prop.status = VehiclePropertyStatus::AVAILABLE;
|
||||
optionIndex++;
|
||||
std::unordered_set<std::string> parsedOptions;
|
||||
int32_t areaIdIndex = -1;
|
||||
|
||||
while (optionIndex < options.size()) {
|
||||
std::string argType = options[optionIndex];
|
||||
@@ -2032,13 +2064,7 @@ Result<VehiclePropValue> FakeVehicleHardware::parsePropOptions(
|
||||
if (argValuesSize != 1) {
|
||||
return Error() << "Expect exact one value when using \"-a\"\n";
|
||||
}
|
||||
auto int32Result = safelyParseInt<int32_t>(currentIndex, argValues[0]);
|
||||
if (!int32Result.ok()) {
|
||||
return Error() << StringPrintf("Area ID: \"%s\" is not a valid int: %s\n",
|
||||
argValues[0].c_str(),
|
||||
getErrorMsg(int32Result).c_str());
|
||||
}
|
||||
prop.areaId = int32Result.value();
|
||||
areaIdIndex = currentIndex;
|
||||
} else if (EqualsIgnoreCase(argType, "-t")) {
|
||||
if (argValuesSize != 1) {
|
||||
return Error() << "Expect exact one value when using \"-t\"\n";
|
||||
@@ -2055,6 +2081,17 @@ Result<VehiclePropValue> FakeVehicleHardware::parsePropOptions(
|
||||
}
|
||||
}
|
||||
|
||||
if (areaIdIndex != -1) {
|
||||
auto int32Result = parseAreaId(options, areaIdIndex, prop.prop);
|
||||
if (!int32Result.ok()) {
|
||||
return Error() << StringPrintf(
|
||||
"Area ID: \"%s\" is not a valid int or "
|
||||
"one or more area names: %s\n",
|
||||
options[areaIdIndex].c_str(), getErrorMsg(int32Result).c_str());
|
||||
}
|
||||
prop.areaId = int32Result.value();
|
||||
}
|
||||
|
||||
return prop;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReport;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateReq;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleApPowerStateShutdownParam;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaSeat;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
|
||||
@@ -2781,6 +2782,8 @@ TEST_P(FakeVehicleHardwareSetPropTest, cmdSetOneProperty) {
|
||||
|
||||
std::vector<SetPropTestCase> GenSetPropParams() {
|
||||
std::string infoMakeProperty = std::to_string(toInt(VehicleProperty::INFO_MAKE));
|
||||
std::string testVendorProperty =
|
||||
std::to_string(toInt(TestVendorProperty::VENDOR_EXTENSION_FLOAT_PROPERTY));
|
||||
return {
|
||||
{"success_set_string", {"--set", infoMakeProperty, "-s", CAR_MAKE}, true},
|
||||
{"success_set_with_name", {"--set", "INFO_MAKE", "-s", CAR_MAKE}, true},
|
||||
@@ -2889,6 +2892,14 @@ std::vector<SetPropTestCase> GenSetPropParams() {
|
||||
{"--set", infoMakeProperty, "-a", "-s", CAR_MAKE},
|
||||
false,
|
||||
"Expect exact one value"},
|
||||
{"fail_invalid_area_name",
|
||||
{"--set", testVendorProperty, "-a", "ROW_1_LEFT|NO_SUCH_AREA", "-f", "1.234"},
|
||||
false,
|
||||
"not a valid int or one or more area names"},
|
||||
{"fail_invalid_area_format",
|
||||
{"--set", testVendorProperty, "-a", "ROW_1_LEFT|||ROW_2_LEFT", "-f", "1.234"},
|
||||
false,
|
||||
"not a valid int or one or more area names"},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2933,6 +2944,86 @@ TEST_F(FakeVehicleHardwareTest, SetComplexPropTest) {
|
||||
ASSERT_EQ(3.402823466E+38f, value.value.floatValues[2]);
|
||||
}
|
||||
|
||||
TEST_F(FakeVehicleHardwareTest, SetPropertyWithPropertyNameAreaId) {
|
||||
int32_t areaId = toInt(VehicleAreaSeat::ROW_1_LEFT);
|
||||
getHardware()->dump(
|
||||
{"--set", "HVAC_TEMPERATURE_SET", "-a", std::to_string(areaId), "-f", "22.345"});
|
||||
|
||||
VehiclePropValue requestProp;
|
||||
requestProp.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET);
|
||||
requestProp.areaId = areaId;
|
||||
auto result = getValue(requestProp);
|
||||
|
||||
ASSERT_TRUE(result.ok());
|
||||
VehiclePropValue value = result.value();
|
||||
ASSERT_EQ(value.prop, toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
|
||||
ASSERT_EQ(value.areaId, areaId);
|
||||
ASSERT_EQ(1u, value.value.floatValues.size());
|
||||
ASSERT_EQ(22.345f, value.value.floatValues[0]);
|
||||
}
|
||||
|
||||
TEST_F(FakeVehicleHardwareTest, SetPropertyWithPropertyNameAreaName) {
|
||||
int32_t areaId = toInt(VehicleAreaSeat::ROW_1_LEFT);
|
||||
getHardware()->dump({"--set", "HVAC_TEMPERATURE_SET", "-a", "ROW_1_LEFT", "-f", "22.345"});
|
||||
|
||||
VehiclePropValue requestProp;
|
||||
requestProp.prop = toInt(VehicleProperty::HVAC_TEMPERATURE_SET);
|
||||
requestProp.areaId = areaId;
|
||||
auto result = getValue(requestProp);
|
||||
|
||||
ASSERT_TRUE(result.ok());
|
||||
VehiclePropValue value = result.value();
|
||||
ASSERT_EQ(value.prop, toInt(VehicleProperty::HVAC_TEMPERATURE_SET));
|
||||
ASSERT_EQ(value.areaId, areaId);
|
||||
ASSERT_EQ(1u, value.value.floatValues.size());
|
||||
ASSERT_EQ(22.345f, value.value.floatValues[0]);
|
||||
}
|
||||
|
||||
TEST_F(FakeVehicleHardwareTest, GetPropertyWithPropertyNameAreaName) {
|
||||
auto result = getHardware()->dump({"--get", "HVAC_TEMPERATURE_SET", "-a", "ROW_1_LEFT"});
|
||||
|
||||
// Default value is 17
|
||||
ASSERT_THAT(result.buffer, ContainsRegex("17"));
|
||||
|
||||
getHardware()->dump({"--set", "HVAC_TEMPERATURE_SET", "-a", "ROW_1_LEFT", "-f", "22"});
|
||||
result = getHardware()->dump({"--get", "HVAC_TEMPERATURE_SET", "-a", "ROW_1_LEFT"});
|
||||
|
||||
ASSERT_THAT(result.buffer, ContainsRegex("22"));
|
||||
}
|
||||
|
||||
TEST_F(FakeVehicleHardwareTest, SetPropertyWithPropertyNameTwoAreasInOneId) {
|
||||
int32_t propId = toInt(TestVendorProperty::VENDOR_EXTENSION_FLOAT_PROPERTY);
|
||||
std::string testVendorProperty = std::to_string(propId);
|
||||
getHardware()->dump({"--set", testVendorProperty, "-a", "ROW_1_LEFT|ROW_2_LEFT|ROW_2_CENTER",
|
||||
"-f", "1.234"});
|
||||
|
||||
VehiclePropValue requestProp;
|
||||
requestProp.prop = propId;
|
||||
int32_t areaId = toInt(VehicleAreaSeat::ROW_1_LEFT) | toInt(VehicleAreaSeat::ROW_2_LEFT) |
|
||||
toInt(VehicleAreaSeat::ROW_2_CENTER);
|
||||
requestProp.areaId = areaId;
|
||||
auto result = getValue(requestProp);
|
||||
|
||||
ASSERT_TRUE(result.ok());
|
||||
VehiclePropValue value = result.value();
|
||||
ASSERT_EQ(value.prop, propId);
|
||||
ASSERT_EQ(value.areaId, areaId);
|
||||
ASSERT_EQ(1u, value.value.floatValues.size());
|
||||
ASSERT_EQ(1.234f, value.value.floatValues[0]);
|
||||
|
||||
// Ignore space between two areas.
|
||||
getHardware()->dump({"--set", testVendorProperty, "-a",
|
||||
"ROW_1_LEFT | ROW_2_LEFT | ROW_2_CENTER", "-f", "2.345"});
|
||||
result = getValue(requestProp);
|
||||
|
||||
ASSERT_TRUE(result.ok());
|
||||
value = result.value();
|
||||
ASSERT_EQ(value.prop, propId);
|
||||
ASSERT_EQ(value.areaId, areaId);
|
||||
ASSERT_EQ(1u, value.value.floatValues.size());
|
||||
ASSERT_EQ(2.345f, value.value.floatValues[0]);
|
||||
}
|
||||
|
||||
struct OptionsTestCase {
|
||||
std::string name;
|
||||
std::vector<std::string> options;
|
||||
|
||||
@@ -337,6 +337,9 @@ inline std::string propIdToString(int32_t propId) {
|
||||
// This is for debug purpose only.
|
||||
android::base::Result<int32_t> stringToPropId(const std::string& propName);
|
||||
|
||||
// This is for debug purpose only. Converts an area's name to its enum definition.
|
||||
android::base::Result<int32_t> stringToArea(const std::string& areaName, int32_t propId);
|
||||
|
||||
template <typename T>
|
||||
void roundToNearestResolution(std::vector<T>& arrayToSanitize, float resolution) {
|
||||
if (resolution == 0) {
|
||||
|
||||
@@ -25,7 +25,13 @@ namespace vehicle {
|
||||
|
||||
using ::aidl::android::hardware::automotive::vehicle::StatusCode;
|
||||
using ::aidl::android::hardware::automotive::vehicle::toString;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleArea;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaConfig;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaDoor;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaMirror;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaSeat;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWheel;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleAreaWindow;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropConfig;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehicleProperty;
|
||||
using ::aidl::android::hardware::automotive::vehicle::VehiclePropertyGroup;
|
||||
@@ -44,7 +50,7 @@ class PropertyIdByNameSingleton {
|
||||
return instance;
|
||||
}
|
||||
|
||||
Result<int32_t> getPropertyId(const std::string& name) {
|
||||
Result<int32_t> getPropertyId(const std::string& name) const {
|
||||
auto it = mPropertyIdByName.find(name);
|
||||
if (it == mPropertyIdByName.end()) {
|
||||
return Error();
|
||||
@@ -66,6 +72,52 @@ class PropertyIdByNameSingleton {
|
||||
}
|
||||
};
|
||||
|
||||
class AreaByNameSingleton {
|
||||
public:
|
||||
static AreaByNameSingleton& getInstance() {
|
||||
static AreaByNameSingleton instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
Result<int32_t> getArea(const std::string& name, int32_t propId) const {
|
||||
VehicleArea areaType = getPropArea(propId);
|
||||
|
||||
auto mapIt = mAreaByNameByAreaType.find(areaType);
|
||||
if (mapIt == mAreaByNameByAreaType.end()) {
|
||||
return Error() << "Invalid area type for property ID: " << propIdToString(propId);
|
||||
}
|
||||
|
||||
const auto& areaByName = mapIt->second;
|
||||
auto it = areaByName.find(name);
|
||||
if (it == areaByName.end()) {
|
||||
return Error() << "Invalid area name for property " << propIdToString(propId) << ": "
|
||||
<< name;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
AreaByNameSingleton(AreaByNameSingleton const&) = delete;
|
||||
void operator=(AreaByNameSingleton const&) = delete;
|
||||
|
||||
private:
|
||||
std::unordered_map<VehicleArea, std::unordered_map<std::string, int32_t>> mAreaByNameByAreaType;
|
||||
|
||||
AreaByNameSingleton() {
|
||||
populateMap(VehicleArea::WINDOW, ndk::internal::enum_values<VehicleAreaWindow>);
|
||||
populateMap(VehicleArea::MIRROR, ndk::internal::enum_values<VehicleAreaMirror>);
|
||||
populateMap(VehicleArea::SEAT, ndk::internal::enum_values<VehicleAreaSeat>);
|
||||
populateMap(VehicleArea::DOOR, ndk::internal::enum_values<VehicleAreaDoor>);
|
||||
populateMap(VehicleArea::WHEEL, ndk::internal::enum_values<VehicleAreaWheel>);
|
||||
}
|
||||
|
||||
template <class T, std::size_t N>
|
||||
void populateMap(VehicleArea areaType, std::array<T, N> values) {
|
||||
for (unsigned int i = 0; i < values.size(); i++) {
|
||||
mAreaByNameByAreaType[areaType].emplace(toString(values[i]), toInt(values[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
Result<void> checkPropValue(const VehiclePropValue& value, const VehiclePropConfig* config) {
|
||||
@@ -254,6 +306,10 @@ Result<int32_t> stringToPropId(const std::string& propName) {
|
||||
return PropertyIdByNameSingleton::getInstance().getPropertyId(propName);
|
||||
}
|
||||
|
||||
Result<int32_t> stringToArea(const std::string& areaName, int32_t propId) {
|
||||
return AreaByNameSingleton::getInstance().getArea(areaName, propId);
|
||||
}
|
||||
|
||||
} // namespace vehicle
|
||||
} // namespace automotive
|
||||
} // namespace hardware
|
||||
|
||||
Reference in New Issue
Block a user