Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eb20a855 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Allow using area name in debug command." into main am: a43970d4 am: 29ee4dbf

parents 2880f16d 29ee4dbf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+44 −7
Original line number Diff line number Diff line
@@ -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;
}

+91 −0
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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) {
+57 −1
Original line number Diff line number Diff line
@@ -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