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

Commit 92096000 authored by Yu Shan's avatar Yu Shan
Browse files

Support debug setValue.

Test: atest android.hardware.automotive.vehicle@2.0-default-impl-unit-tests
Bug: 193565753
Change-Id: I603f9fb986b2b131d05a23fb1cc1517f99c5bf0a
parent 612dbf6f
Loading
Loading
Loading
Loading
+91 −5
Original line number Diff line number Diff line
@@ -370,10 +370,11 @@ IVehicleServer::DumpResult DefaultVehicleHalServer::onDump(
        return result;
    }

    return debug(options);
    return debugCommand(options);
}

IVehicleServer::DumpResult DefaultVehicleHalServer::debug(const std::vector<std::string>& options) {
IVehicleServer::DumpResult DefaultVehicleHalServer::debugCommand(
        const std::vector<std::string>& options) {
    DumpResult result;
    // This is a debug command for the HAL, caller should not continue to dump state.
    result.callerShouldDumpState = false;
@@ -389,7 +390,9 @@ IVehicleServer::DumpResult DefaultVehicleHalServer::debug(const std::vector<std:
        result.buffer += getHelpInfo();
        return result;
    } else if (command == "--genfakedata") {
        return genFakeData(options);
        return genFakeDataCommand(options);
    } else if (command == "--setint" || command == "--setfloat" || command == "--setbool") {
        return setValueCommand(options);
    }

    result.buffer += "Unknown command: \"" + command + "\"\n";
@@ -411,10 +414,19 @@ std::string DefaultVehicleHalServer::getHelpInfo() {
           "\tStop a json generator: \n"
           "\t--debughal --genfakedata --stopjson [jsonFilePath(string)]\n"
           "\tGenerate key press: \n"
           "\t--debughal --genfakedata --keypress [keyCode(int32)] [display[int32]]\n";
}

IVehicleServer::DumpResult DefaultVehicleHalServer::genFakeData(
           "\t--debughal --genfakedata --keypress [keyCode(int32)] [display[int32]]\n"
           "\tSet a int property value: \n"
           "\t--setint [propID(int32)] [value(int32)] [timestamp(int64)] "
           "[areaID(int32)(optional)]\n"
           "\tSet a boolean property value: \n"
           "\t--setbool [propID(int32)] [value(\"true\"/\"false\")] [timestamp(int64)] "
           "[areaID(int32)(optional)]\n"
           "\tSet a float property value: \n"
           "\t--setfloat [propID(int32)] [value(float)] [timestamp(int64)] "
           "[areaID(int32)(optional)]\n";
}

IVehicleServer::DumpResult DefaultVehicleHalServer::genFakeDataCommand(
        const std::vector<std::string>& options) {
    DumpResult result;
    // This is a debug command for the HAL, caller should not continue to dump state.
@@ -597,6 +609,80 @@ void DefaultVehicleHalServer::overrideProperties(const char* overrideDir) {
    }
}

IVehicleServer::DumpResult DefaultVehicleHalServer::setValueCommand(
        const std::vector<std::string>& options) {
    DumpResult result;
    // This is a debug command for the HAL, caller should not continue to dump state.
    result.callerShouldDumpState = false;
    // --debughal --set* [propID(int32)] [value] [timestamp(int64)]
    // [areaId(int32)(optional)]
    if (options.size() != 5 && options.size() != 6) {
        result.buffer +=
                "incorrect argument count, need 5 or 6 arguments for --setint or --setfloat or "
                "--setbool\n";
        result.buffer += getHelpInfo();
        return result;
    }
    std::unique_ptr<VehiclePropValue> updatedPropValue;
    int32_t propId;
    int32_t intValue;
    float floatValue;
    int64_t timestamp;
    int32_t areaId = 0;
    if (options[1] == "--setint") {
        updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::INT32, 1));
        if (!android::base::ParseInt(options[3], &intValue)) {
            result.buffer += "failed to parse value as int: \"" + options[3] + "\"\n";
            result.buffer += getHelpInfo();
            return result;
        }
        updatedPropValue->value.int32Values[0] = intValue;
    } else if (options[1] == "--setbool") {
        updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::BOOLEAN, 1));
        if (options[3] == "true" || options[3] == "True") {
            updatedPropValue->value.int32Values[0] = 1;
        } else if (options[3] == "false" || options[3] == "False") {
            updatedPropValue->value.int32Values[0] = 0;
        } else {
            result.buffer += "failed to parse value as bool, only accepts true/false: \"" +
                             options[3] + "\"\n";
            result.buffer += getHelpInfo();
            return result;
        }
    } else {
        updatedPropValue = std::move(createVehiclePropValue(VehiclePropertyType::FLOAT, 1));
        if (!android::base::ParseFloat(options[3], &floatValue)) {
            result.buffer += "failed to parse value as float: \"" + options[3] + "\"\n";
            result.buffer += getHelpInfo();
            return result;
        }
        updatedPropValue->value.floatValues[0] = floatValue;
    }
    if (!android::base::ParseInt(options[2], &propId)) {
        result.buffer += "failed to parse propID as int: \"" + options[2] + "\"\n";
        result.buffer += getHelpInfo();
        return result;
    }
    updatedPropValue->prop = propId;
    if (!android::base::ParseInt(options[4], &timestamp)) {
        result.buffer += "failed to parse timestamp as int: \"" + options[4] + "\"\n";
        result.buffer += getHelpInfo();
        return result;
    }
    updatedPropValue->timestamp = timestamp;
    if (options.size() == 6) {
        if (!android::base::ParseInt(options[5], &areaId)) {
            result.buffer += "failed to parse areaID as int: \"" + options[5] + "\"\n";
            result.buffer += getHelpInfo();
            return result;
        }
    }
    updatedPropValue->areaId = areaId;

    onPropertyValueFromCar(*updatedPropValue, /*updateStatus=*/true);
    return result;
}

}  // namespace impl

}  // namespace V2_0
+14 −2
Original line number Diff line number Diff line
@@ -45,6 +45,9 @@ class DefaultVehicleHalServer : public IVehicleServer {

    StatusCode onSetProperty(const VehiclePropValue& value, bool updateStatus) override;

    // Dump/debug the Default VHAL server. If options is empty, the internal information for the
    // server would be dumped. Otherwise, the options would be treated as debug commands and sent
    // to debug function to handle the commands.
    DumpResult onDump(const std::vector<std::string>& options) override;

    // Set the Property Value Pool used in this server
@@ -67,16 +70,25 @@ class DefaultVehicleHalServer : public IVehicleServer {

    void storePropInitialValue(const ConfigDeclaration& config);

    DumpResult debug(const std::vector<std::string>& options);
    // Handles debug commands. The first option must be "--debughal" otherwise the command would be
    // ignored. The second option specifies the operations to execute. Different operations require
    // different input options, for detail, see the helpInfo printed by getHelpInfo().
    DumpResult debugCommand(const std::vector<std::string>& options);

    // Gets help info. Contains the usage for different debug commands.
    std::string getHelpInfo();

    DumpResult genFakeData(const std::vector<std::string>& options);
    // If "persist.vendor.vhal_init_value_override" is true, try to override the properties default
    // values according to JSON files in 'overrideDir'. Would be called in constructor using
    // VENDOR_OVERRIDE_DIR as overrideDir.
    void maybeOverrideProperties(const char* overrideDir);

    // Handles "--genfakedata" debug command.
    DumpResult genFakeDataCommand(const std::vector<std::string>& options);

    // Handles "--setint" or "--setfloat" or "--setbool" debug command.
    DumpResult setValueCommand(const std::vector<std::string>& options);

  protected:
    GeneratorHub mGeneratorHub{
            [this](const VehiclePropValue& value) { return onFakeValueGenerated(value); }};
+129 −1
Original line number Diff line number Diff line
@@ -71,6 +71,8 @@ using ::android::hardware::automotive::vehicle::V2_0::VehiclePropValuePool;
using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVehicleConnector;
using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVehicleHal;
using ::android::hardware::automotive::vehicle::V2_0::impl::DefaultVhalImplTestHelper;
using ::android::hardware::automotive::vehicle::V2_0::impl::DOOR_1_LEFT;
using ::android::hardware::automotive::vehicle::V2_0::impl::DOOR_1_RIGHT;
using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_ALL;
using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_LEFT;
using ::android::hardware::automotive::vehicle::V2_0::impl::HVAC_RIGHT;
@@ -661,7 +663,28 @@ std::vector<OptionsTestCase> GenInvalidOptions() {
             "failed to parse keyCode as int: \"0.1\""},
            {"genfakedata_keypress_invalid_display",
             {"--debughal", "--genfakedata", "--keypress", "1", "0.1"},
             "failed to parse display as int: \"0.1\""}};
             "failed to parse display as int: \"0.1\""},
            {"setint_no_args", {"--debughal", "--setint"}, "incorrect argument count"},
            {"setint_invalid_prop_id",
             {"--debughal", "--setint", "abcd", "0", "0", "0"},
             "failed to parse propID as int: \"abcd\""},
            {"setint_invalid_value",
             {"--debughal", "--setint", "0", "1.1", "0", "0"},
             "failed to parse value as int: \"1.1\""},
            {"setint_invalid_timestamp",
             {"--debughal", "--setint", "0", "0", "1.1", "0"},
             "failed to parse timestamp as int: \"1.1\""},
            {"setint_invalid_areaId",
             {"--debughal", "--setint", "0", "0", "0", "1.1"},
             "failed to parse areaID as int: \"1.1\""},
            {"setbool_no_args", {"--debughal", "--setbool"}, "incorrect argument count"},
            {"setbool_invalid_value",
             {"--debughal", "--setbool", "0", "1", "0", "0"},
             "failed to parse value as bool"},
            {"setfloat_no_args", {"--debughal", "--setfloat"}, "incorrect argument count"},
            {"setfloat_invalid_value",
             {"--debughal", "--setfloat", "0", "abcd", "0", "0"},
             "failed to parse value as float: \"abcd\""}};
}

INSTANTIATE_TEST_SUITE_P(
@@ -1263,4 +1286,109 @@ TEST_F(DefaultVhalImplTest, testInitialUserInfo) {
    EXPECT_EQ(0, events[0]->value.int32Values[3]);
}

TEST_F(DefaultVhalImplTest, testDebugSetInt) {
    hidl_vec<hidl_string> options = {"--debughal", "--setint",
                                     getPropIdString(VehicleProperty::INFO_MODEL_YEAR), "2022",
                                     "1000"};
    hidl_handle fd = {};
    int memfd = createMemfd(&fd);
    // Clear existing events.
    mEventQueue.flush();

    EXPECT_FALSE(mHal->dump(fd, options));

    lseek(memfd, 0, SEEK_SET);
    char buf[10240] = {};
    // The dumped info should be empty.
    read(memfd, buf, sizeof(buf));
    EXPECT_STREQ("", buf);

    auto events = mEventQueue.flush();
    ASSERT_EQ((size_t)1, events.size());
    ASSERT_EQ((size_t)1, events[0]->value.int32Values.size());
    EXPECT_EQ(2022, events[0]->value.int32Values[0]);
    EXPECT_EQ(1000, events[0]->timestamp);

    VehiclePropValue value;
    StatusCode status;
    value.prop = toInt(VehicleProperty::INFO_MODEL_YEAR);
    auto gotValue = mHal->get(value, &status);
    ASSERT_EQ(StatusCode::OK, status);
    ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
    EXPECT_EQ(2022, gotValue->value.int32Values[0]);
}

TEST_F(DefaultVhalImplTest, testDebugSetBool) {
    char doorLeft[100];
    snprintf(doorLeft, sizeof(doorLeft), "%d", DOOR_1_LEFT);
    hidl_vec<hidl_string> options = {
            "--debughal", "--setbool", getPropIdString(VehicleProperty::DOOR_LOCK),
            "false",      "1000",      doorLeft};
    hidl_handle fd = {};
    int memfd = createMemfd(&fd);
    // Clear existing events.
    mEventQueue.flush();

    EXPECT_FALSE(mHal->dump(fd, options));

    lseek(memfd, 0, SEEK_SET);
    char buf[10240] = {};
    // The dumped info should be empty.
    read(memfd, buf, sizeof(buf));
    EXPECT_STREQ("", buf);

    auto events = mEventQueue.flush();
    ASSERT_EQ((size_t)1, events.size());
    EXPECT_EQ(0, events[0]->value.int32Values[0]);
    EXPECT_EQ(DOOR_1_LEFT, events[0]->areaId);
    EXPECT_EQ(1000, events[0]->timestamp);

    VehiclePropValue value;
    StatusCode status;
    value.prop = toInt(VehicleProperty::DOOR_LOCK);
    value.areaId = DOOR_1_LEFT;
    auto gotValue = mHal->get(value, &status);
    ASSERT_EQ(StatusCode::OK, status);
    ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
    EXPECT_EQ(0, gotValue->value.int32Values[0]);

    value.areaId = DOOR_1_RIGHT;
    gotValue = mHal->get(value, &status);
    ASSERT_EQ(StatusCode::OK, status);
    ASSERT_EQ((size_t)1, gotValue->value.int32Values.size());
    EXPECT_EQ(1, gotValue->value.int32Values[0]);
}

TEST_F(DefaultVhalImplTest, testDebugSetFloat) {
    hidl_vec<hidl_string> options = {"--debughal", "--setfloat",
                                     getPropIdString(VehicleProperty::INFO_FUEL_CAPACITY), "10.5",
                                     "1000"};
    hidl_handle fd = {};
    int memfd = createMemfd(&fd);
    // Clear existing events.
    mEventQueue.flush();

    EXPECT_FALSE(mHal->dump(fd, options));

    lseek(memfd, 0, SEEK_SET);
    char buf[10240] = {};
    // The dumped info should be empty.
    read(memfd, buf, sizeof(buf));
    EXPECT_STREQ("", buf);

    auto events = mEventQueue.flush();
    ASSERT_EQ((size_t)1, events.size());
    ASSERT_EQ((size_t)1, events[0]->value.floatValues.size());
    EXPECT_EQ(10.5, events[0]->value.floatValues[0]);
    EXPECT_EQ(1000, events[0]->timestamp);

    VehiclePropValue value;
    StatusCode status;
    value.prop = toInt(VehicleProperty::INFO_FUEL_CAPACITY);
    auto gotValue = mHal->get(value, &status);
    ASSERT_EQ(StatusCode::OK, status);
    ASSERT_EQ((size_t)1, gotValue->value.floatValues.size());
    EXPECT_EQ(10.5, gotValue->value.floatValues[0]);
}

}  // namespace