Add --keyinputv2 and --motioninput options to genfakedata.

- These are required to send keyinputv2 and motioninput events via fake
  VHal.

Fix: 263184145
Test: Manually tested by sending events
Test: atest FakeVehicleHardwareTest
Change-Id: I078f6e27d4a0de5ac145f9c2058f53f8567ba293
This commit is contained in:
Gaurav Bhola 2023-01-04 18:16:00 -08:00
parent d30ff95a38
commit 259c71fdf5
4 changed files with 396 additions and 1 deletions

View file

@ -1743,6 +1743,77 @@
]
}
},
{
"property": "VehicleProperty::HW_KEY_INPUT_V2",
"defaultValue": {
"int32Values": [
0,
0,
0,
0
],
"int64Values": [
0
]
},
"areas": [
{
"areaId": "Constants::SEAT_1_LEFT"
},
{
"areaId": "Constants::SEAT_1_RIGHT"
},
{
"areaId": "Constants::SEAT_2_LEFT"
},
{
"areaId": "Constants::SEAT_2_RIGHT"
},
{
"areaId": "Constants::SEAT_2_CENTER"
}
]
},
{
"property": "VehicleProperty::HW_MOTION_INPUT",
"defaultValue": {
"int32Values": [
0,
0,
0,
0,
1,
0,
0
],
"floatValues": [
0,
0,
0,
0
],
"int64Values": [
0
]
},
"areas": [
{
"areaId": "Constants::SEAT_1_LEFT"
},
{
"areaId": "Constants::SEAT_1_RIGHT"
},
{
"areaId": "Constants::SEAT_2_LEFT"
},
{
"areaId": "Constants::SEAT_2_RIGHT"
},
{
"areaId": "Constants::SEAT_2_CENTER"
}
]
},
{
"property": "VehicleProperty::HW_ROTARY_INPUT",
"defaultValue": {

View file

@ -240,6 +240,14 @@ class FakeVehicleHardware : public IVehicleHardware {
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwInputKeyProp(
aidl::android::hardware::automotive::vehicle::VehicleHwKeyInputAction action,
int32_t keyCode, int32_t targetDisplay);
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwKeyInputV2Prop(
int32_t area, int32_t targetDisplay, int32_t keyCode, int32_t action,
int32_t repeatCount);
static aidl::android::hardware::automotive::vehicle::VehiclePropValue createHwMotionInputProp(
int32_t area, int32_t display, int32_t inputType, int32_t action, int32_t buttonState,
int32_t pointerCount, int32_t pointerId[], int32_t toolType[], float xData[],
float yData[], float pressure[], float size[]);
static std::string genFakeDataHelp();
static std::string parseErrMsg(std::string fieldName, std::string value, std::string type);
};

View file

@ -672,6 +672,14 @@ provided, it would iterate indefinitely.
--genfakedata --keypress [keyCode(int32)] [display[int32]]: Generate key press.
--genfakedata --keyinputv2 [area(int32)] [display(int32)] [keyCode[int32]] [action[int32]]
[repeatCount(int32)]
--genfakedata --motioninput [area(int32)] [display(int32)] [inputType[int32]] [action[int32]]
[buttonState(int32)] --pointer [pointerId(int32)] [toolType(int32)] [xData(float)] [yData(float)]
[pressure(float)] [size(float)]
Generate a motion input event. --pointer option can be specified multiple times.
)";
}
@ -802,6 +810,135 @@ std::string FakeVehicleHardware::genFakeDataCommand(const std::vector<std::strin
onValueChangeCallback(
createHwInputKeyProp(VehicleHwKeyInputAction::ACTION_UP, keyCode, display));
return "keypress event generated successfully";
} else if (command == "--keyinputv2") {
int32_t area;
int32_t display;
int32_t keyCode;
int32_t action;
int32_t repeatCount;
// --genfakedata --keyinputv2 [area(int32)] [display(int32)] [keyCode[int32]]
// [action[int32]] [repeatCount(int32)]
if (options.size() != 7) {
return "incorrect argument count, need 7 arguments for --genfakedata --keyinputv2\n";
}
if (!android::base::ParseInt(options[2], &area)) {
return parseErrMsg("area", options[2], "int");
}
if (!android::base::ParseInt(options[3], &display)) {
return parseErrMsg("display", options[3], "int");
}
if (!android::base::ParseInt(options[4], &keyCode)) {
return parseErrMsg("keyCode", options[4], "int");
}
if (!android::base::ParseInt(options[5], &action)) {
return parseErrMsg("action", options[5], "int");
}
if (!android::base::ParseInt(options[6], &repeatCount)) {
return parseErrMsg("repeatCount", options[6], "int");
}
// Send back to HAL
onValueChangeCallback(createHwKeyInputV2Prop(area, display, keyCode, action, repeatCount));
return StringPrintf(
"keyinputv2 event generated successfully with area:%d, display:%d,"
" keyCode:%d, action:%d, repeatCount:%d",
area, display, keyCode, action, repeatCount);
} else if (command == "--motioninput") {
int32_t area;
int32_t display;
int32_t inputType;
int32_t action;
int32_t buttonState;
int32_t pointerCount;
// --genfakedata --motioninput [area(int32)] [display(int32)] [inputType[int32]]
// [action[int32]] [buttonState(int32)] [pointerCount(int32)]
// --pointer [pointerId(int32)] [toolType(int32)] [xData(float)] [yData(float)]
// [pressure(float)] [size(float)]
int optionsSize = (int)options.size();
if (optionsSize / 7 < 2) {
return "incorrect argument count, need at least 14 arguments for --genfakedata "
"--motioninput including at least 1 --pointer\n";
}
if (optionsSize % 7 != 0) {
return "incorrect argument count, need 6 arguments for every --pointer\n";
}
pointerCount = (int)optionsSize / 7 - 1;
if (!android::base::ParseInt(options[2], &area)) {
return parseErrMsg("area", options[2], "int");
}
if (!android::base::ParseInt(options[3], &display)) {
return parseErrMsg("display", options[3], "int");
}
if (!android::base::ParseInt(options[4], &inputType)) {
return parseErrMsg("inputType", options[4], "int");
}
if (!android::base::ParseInt(options[5], &action)) {
return parseErrMsg("action", options[5], "int");
}
if (!android::base::ParseInt(options[6], &buttonState)) {
return parseErrMsg("buttonState", options[6], "int");
}
int32_t pointerId[pointerCount];
int32_t toolType[pointerCount];
float xData[pointerCount];
float yData[pointerCount];
float pressure[pointerCount];
float size[pointerCount];
for (int i = 7, pc = 0; i < optionsSize; i += 7, pc += 1) {
int offset = i;
if (options[offset] != "--pointer") {
return "--pointer is needed for the motion input\n";
}
offset += 1;
if (!android::base::ParseInt(options[offset], &pointerId[pc])) {
return parseErrMsg("pointerId", options[offset], "int");
}
offset += 1;
if (!android::base::ParseInt(options[offset], &toolType[pc])) {
return parseErrMsg("toolType", options[offset], "int");
}
offset += 1;
if (!android::base::ParseFloat(options[offset], &xData[pc])) {
return parseErrMsg("xData", options[offset], "float");
}
offset += 1;
if (!android::base::ParseFloat(options[offset], &yData[pc])) {
return parseErrMsg("yData", options[offset], "float");
}
offset += 1;
if (!android::base::ParseFloat(options[offset], &pressure[pc])) {
return parseErrMsg("pressure", options[offset], "float");
}
offset += 1;
if (!android::base::ParseFloat(options[offset], &size[pc])) {
return parseErrMsg("size", options[offset], "float");
}
}
// Send back to HAL
onValueChangeCallback(createHwMotionInputProp(area, display, inputType, action, buttonState,
pointerCount, pointerId, toolType, xData,
yData, pressure, size));
std::string successMessage = StringPrintf(
"motion event generated successfully with area:%d, display:%d,"
" inputType:%d, action:%d, buttonState:%d, pointerCount:%d\n",
area, display, inputType, action, buttonState, pointerCount);
for (int i = 0; i < pointerCount; i++) {
successMessage += StringPrintf(
"Pointer #%d {\n"
" id:%d , tooltype:%d \n"
" x:%f , y:%f\n"
" pressure: %f, data: %f\n"
"}\n",
i, pointerId[i], toolType[i], xData[i], yData[i], pressure[i], size[i]);
}
return successMessage;
}
return StringPrintf("Unknown command: \"%s\"\n%s", command.c_str(), genFakeDataHelp().c_str());
@ -819,6 +956,59 @@ VehiclePropValue FakeVehicleHardware::createHwInputKeyProp(VehicleHwKeyInputActi
return value;
}
VehiclePropValue FakeVehicleHardware::createHwKeyInputV2Prop(int32_t area, int32_t targetDisplay,
int32_t keyCode, int32_t action,
int32_t repeatCount) {
VehiclePropValue value = {.prop = toInt(VehicleProperty::HW_KEY_INPUT_V2),
.areaId = area,
.timestamp = elapsedRealtimeNano(),
.status = VehiclePropertyStatus::AVAILABLE,
.value.int32Values = {targetDisplay, keyCode, action, repeatCount},
.value.int64Values = {elapsedRealtimeNano()}};
return value;
}
VehiclePropValue FakeVehicleHardware::createHwMotionInputProp(
int32_t area, int32_t display, int32_t inputType, int32_t action, int32_t buttonState,
int32_t pointerCount, int32_t pointerId[], int32_t toolType[], float xData[], float yData[],
float pressure[], float size[]) {
std::vector<int> intValues;
intValues.push_back(display);
intValues.push_back(inputType);
intValues.push_back(action);
intValues.push_back(buttonState);
intValues.push_back(pointerCount);
for (int i = 0; i < pointerCount; i++) {
intValues.push_back(pointerId[i]);
}
for (int i = 0; i < pointerCount; i++) {
intValues.push_back(toolType[i]);
}
std::vector<float> floatValues;
for (int i = 0; i < pointerCount; i++) {
floatValues.push_back(xData[i]);
}
for (int i = 0; i < pointerCount; i++) {
floatValues.push_back(yData[i]);
}
for (int i = 0; i < pointerCount; i++) {
floatValues.push_back(pressure[i]);
}
for (int i = 0; i < pointerCount; i++) {
floatValues.push_back(size[i]);
}
VehiclePropValue value = {.prop = toInt(VehicleProperty::HW_MOTION_INPUT),
.areaId = area,
.timestamp = elapsedRealtimeNano(),
.status = VehiclePropertyStatus::AVAILABLE,
.value.int32Values = intValues,
.value.floatValues = floatValues,
.value.int64Values = {elapsedRealtimeNano()}};
return value;
}
void FakeVehicleHardware::eventFromVehicleBus(const VehiclePropValue& value) {
mServerSidePropStore->writeValue(mValuePool->obtain(value));
}

View file

@ -1776,7 +1776,61 @@ std::vector<OptionsTestCase> GenInvalidOptions() {
"failed to parse keyCode as int: \"0.1\""},
{"genfakedata_keypress_invalid_display",
{"--genfakedata", "--keypress", "1", "0.1"},
"failed to parse display as int: \"0.1\""}};
"failed to parse display as int: \"0.1\""},
{"genfakedata_keyinputv2_incorrect_arguments",
{"--genfakedata", "--keyinputv2", "1", "1"},
"incorrect argument count, need 7 arguments for --genfakedata --keyinputv2\n"},
{"genfakedata_keyinputv2_invalid_area",
{"--genfakedata", "--keyinputv2", "0.1", "1", "1", "1", "1"},
"failed to parse area as int: \"0.1\""},
{"genfakedata_keyinputv2_invalid_display",
{"--genfakedata", "--keyinputv2", "1", "0.1", "1", "1", "1"},
"failed to parse display as int: \"0.1\""},
{"genfakedata_keyinputv2_invalid_keycode",
{"--genfakedata", "--keyinputv2", "1", "1", "0.1", "1", "1"},
"failed to parse keyCode as int: \"0.1\""},
{"genfakedata_keyinputv2_invalid_action",
{"--genfakedata", "--keyinputv2", "1", "1", "1", "0.1", "1"},
"failed to parse action as int: \"0.1\""},
{"genfakedata_keyinputv2_invalid_repeatcount",
{"--genfakedata", "--keyinputv2", "1", "1", "1", "1", "0.1"},
"failed to parse repeatCount as int: \"0.1\""},
{"genfakedata_motioninput_invalid_argument_count",
{"--genfakedata", "--motioninput", "1", "1", "1", "1", "1"},
"incorrect argument count, need at least 14 arguments for --genfakedata "
"--motioninput including at least 1 --pointer\n"},
{"genfakedata_motioninput_pointer_invalid_argument_count",
{"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "1", "1", "1",
"1", "1", "1", "--pointer"},
"incorrect argument count, need 6 arguments for every --pointer\n"},
{"genfakedata_motioninput_invalid_area",
{"--genfakedata", "--motioninput", "0.1", "1", "1", "1", "1", "--pointer", "1", "1",
"1", "1", "1", "1"},
"failed to parse area as int: \"0.1\""},
{"genfakedata_motioninput_invalid_display",
{"--genfakedata", "--motioninput", "1", "0.1", "1", "1", "1", "--pointer", "1", "1",
"1", "1", "1", "1"},
"failed to parse display as int: \"0.1\""},
{"genfakedata_motioninput_invalid_inputtype",
{"--genfakedata", "--motioninput", "1", "1", "0.1", "1", "1", "--pointer", "1", "1",
"1", "1", "1", "1"},
"failed to parse inputType as int: \"0.1\""},
{"genfakedata_motioninput_invalid_action",
{"--genfakedata", "--motioninput", "1", "1", "1", "0.1", "1", "--pointer", "1", "1",
"1", "1", "1", "1"},
"failed to parse action as int: \"0.1\""},
{"genfakedata_motioninput_invalid_buttonstate",
{"--genfakedata", "--motioninput", "1", "1", "1", "1", "0.1", "--pointer", "1", "1",
"1.2", "1.2", "1.2", "1.2"},
"failed to parse buttonState as int: \"0.1\""},
{"genfakedata_motioninput_invalid_pointerid",
{"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "0.1", "1",
"1.2", "1", "1", "1"},
"failed to parse pointerId as int: \"0.1\""},
{"genfakedata_motioninput_invalid_tooltype",
{"--genfakedata", "--motioninput", "1", "1", "1", "1", "1", "--pointer", "1", "0.1",
"1.2", "1", "1", "1"},
"failed to parse toolType as int: \"0.1\""}};
}
TEST_P(FakeVehicleHardwareOptionsTest, testInvalidOptions) {
@ -1965,6 +2019,78 @@ TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataKeyPress) {
EXPECT_EQ(2, events[1].value.int32Values[2]);
}
TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataKeyInputV2) {
std::vector<std::string> options = {"--genfakedata", "--keyinputv2", "1", "2", "3", "4", "5"};
DumpResult result = getHardware()->dump(options);
ASSERT_FALSE(result.callerShouldDumpState);
ASSERT_THAT(result.buffer, HasSubstr("successfully"));
auto events = getChangedProperties();
ASSERT_EQ(1u, events.size());
EXPECT_EQ(toInt(VehicleProperty::HW_KEY_INPUT_V2), events[0].prop);
ASSERT_EQ(4u, events[0].value.int32Values.size());
EXPECT_EQ(2, events[0].value.int32Values[0]);
EXPECT_EQ(3, events[0].value.int32Values[1]);
EXPECT_EQ(4, events[0].value.int32Values[2]);
EXPECT_EQ(5, events[0].value.int32Values[3]);
ASSERT_EQ(1u, events[0].value.int64Values.size());
}
TEST_F(FakeVehicleHardwareTest, testDebugGenFakeDataMotionInput) {
std::vector<std::string> options = {"--genfakedata",
"--motioninput",
"1",
"2",
"3",
"4",
"5",
"--pointer",
"11",
"22",
"33.3",
"44.4",
"55.5",
"66.6",
"--pointer",
"21",
"32",
"43.3",
"54.4",
"65.5",
"76.6"};
DumpResult result = getHardware()->dump(options);
ASSERT_FALSE(result.callerShouldDumpState);
ASSERT_THAT(result.buffer, HasSubstr("successfully"));
auto events = getChangedProperties();
ASSERT_EQ(1u, events.size());
EXPECT_EQ(toInt(VehicleProperty::HW_MOTION_INPUT), events[0].prop);
ASSERT_EQ(9u, events[0].value.int32Values.size());
EXPECT_EQ(2, events[0].value.int32Values[0]);
EXPECT_EQ(3, events[0].value.int32Values[1]);
EXPECT_EQ(4, events[0].value.int32Values[2]);
EXPECT_EQ(5, events[0].value.int32Values[3]);
EXPECT_EQ(2, events[0].value.int32Values[4]);
EXPECT_EQ(11, events[0].value.int32Values[5]);
EXPECT_EQ(21, events[0].value.int32Values[6]);
EXPECT_EQ(22, events[0].value.int32Values[7]);
EXPECT_EQ(32, events[0].value.int32Values[8]);
ASSERT_EQ(8u, events[0].value.floatValues.size());
EXPECT_FLOAT_EQ(33.3, events[0].value.floatValues[0]);
EXPECT_FLOAT_EQ(43.3, events[0].value.floatValues[1]);
EXPECT_FLOAT_EQ(44.4, events[0].value.floatValues[2]);
EXPECT_FLOAT_EQ(54.4, events[0].value.floatValues[3]);
EXPECT_FLOAT_EQ(55.5, events[0].value.floatValues[4]);
EXPECT_FLOAT_EQ(65.5, events[0].value.floatValues[5]);
EXPECT_FLOAT_EQ(66.6, events[0].value.floatValues[6]);
EXPECT_FLOAT_EQ(76.6, events[0].value.floatValues[7]);
ASSERT_EQ(1u, events[0].value.int64Values.size());
}
TEST_F(FakeVehicleHardwareTest, testGetEchoReverseBytes) {
ASSERT_EQ(setValue(VehiclePropValue{
.prop = ECHO_REVERSE_BYTES,