Support debug setValue.
Test: atest android.hardware.automotive.vehicle@2.0-default-impl-unit-tests
Bug: 193565753
Change-Id: I603f9fb986b2b131d05a23fb1cc1517f99c5bf0a
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
index 0aaa4c1..2facc4b 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.cpp
@@ -370,10 +370,11 @@
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 @@
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 @@
"\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";
+ "\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::genFakeData(
+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 @@
}
}
+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], ×tamp)) {
+ 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
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h
index 5858325..8754846 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultVehicleHalServer.h
@@ -45,6 +45,9 @@
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 @@
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); }};
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
index 2268df8..e3c8dd6 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/tests/DefaultVhalImpl_test.cpp
@@ -71,6 +71,8 @@
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 @@
"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 @@
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