summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Prabir Pradhan <prabirmsp@google.com> 2025-01-28 03:49:54 +0000
committer Prabir Pradhan <prabirmsp@google.com> 2025-01-29 09:09:37 -0800
commit2889b8f2801e5cfc2b8d5cb491010e4d81673abc (patch)
tree0e5b6454ef0836fd60f433ef668d64c764a32234
parentea395bfbeb4a53e3c9b7466b7031a8c8819d7659 (diff)
InputTracer: Ensure 0 coordinate values are traced, with unit test
The axis bits in PointerCoords are not set when the value is 0, since that's the default value. Make sure the coordinate values are always traced for pointer events, and add unit tests. Bug: 245989146 Flag: EXEMPT tracing only Test: Presubmit Change-Id: I7c291ef56e025e771c382354e10d6b7dda7a8fa4
-rw-r--r--services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h28
-rw-r--r--services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp90
2 files changed, 112 insertions, 6 deletions
diff --git a/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h b/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h
index eb33e2b894..c19d278370 100644
--- a/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h
+++ b/services/inputflinger/dispatcher/trace/AndroidInputEventProtoConverter.h
@@ -41,6 +41,16 @@ const impl::TraceConfig CONFIG_TRACE_ALL{
.matchImeConnectionActive = {}}},
};
+template <typename Pointer>
+void writeAxisValue(Pointer* pointer, int32_t axis, float value, bool isRedacted) {
+ auto* axisEntry = pointer->add_axis_value();
+ axisEntry->set_axis(axis);
+
+ if (!isRedacted) {
+ axisEntry->set_value(value);
+ }
+}
+
} // namespace internal
/**
@@ -85,15 +95,21 @@ public:
const auto& coords = event.pointerCoords[i];
auto bits = BitSet64(coords.bits);
- for (int32_t axisIndex = 0; !bits.isEmpty(); axisIndex++) {
- const auto axis = bits.clearFirstMarkedBit();
- auto axisEntry = pointer->add_axis_value();
- axisEntry->set_axis(axis);
- if (!isRedacted) {
- axisEntry->set_value(coords.values[axisIndex]);
+ if (isFromSource(event.source, AINPUT_SOURCE_CLASS_POINTER)) {
+ // Always include the X and Y axes for pointer events, since the
+ // bits will not be marked if the value is 0.
+ for (const auto axis : {AMOTION_EVENT_AXIS_X, AMOTION_EVENT_AXIS_Y}) {
+ if (!bits.hasBit(axis)) {
+ internal::writeAxisValue(pointer, axis, 0.0f, isRedacted);
+ }
}
}
+
+ for (int32_t axisIndex = 0; !bits.isEmpty(); axisIndex++) {
+ const auto axis = bits.clearFirstMarkedBit();
+ internal::writeAxisValue(pointer, axis, coords.values[axisIndex], isRedacted);
+ }
}
}
diff --git a/services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp b/services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp
index 414da66cd2..1b10ece0a2 100644
--- a/services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp
+++ b/services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp
@@ -256,6 +256,96 @@ TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent_Redacted) {
TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/true);
}
+// Test any special handling for zero values for pointer events.
+TEST(AndroidInputEventProtoConverterTest, ToProtoMotionEvent_ZeroValues) {
+ TracedMotionEvent event{};
+ event.id = 0;
+ event.eventTime = 0;
+ event.downTime = 0;
+ event.source = AINPUT_SOURCE_MOUSE;
+ event.action = AMOTION_EVENT_ACTION_BUTTON_PRESS;
+ event.deviceId = 0;
+ event.displayId = ui::LogicalDisplayId(0);
+ event.classification = {};
+ event.flags = 0;
+ event.policyFlags = 0;
+ event.buttonState = 0;
+ event.actionButton = 0;
+ event.xCursorPosition = 0.0f;
+ event.yCursorPosition = 0.0f;
+ event.metaState = 0;
+ event.xPrecision = 0.0f;
+ event.yPrecision = 0.0f;
+ event.pointerProperties.emplace_back(PointerProperties{
+ .id = 0,
+ .toolType = ToolType::MOUSE,
+ });
+ event.pointerProperties.emplace_back(PointerProperties{
+ .id = 1,
+ .toolType = ToolType::FINGER,
+ });
+ // Zero values for x and y axes are always traced for pointer events.
+ // However, zero values for other axes may not necessarily be traced.
+ event.pointerCoords.emplace_back();
+ event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 0.0f);
+ event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 1.0f);
+ event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f);
+ event.pointerCoords.emplace_back();
+ event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_X, 0.0f);
+ event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_Y, 0.0f);
+ event.pointerCoords.back().setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 0.0f);
+
+ testing::StrictMock<MockProtoMotion> proto;
+ testing::StrictMock<MockProtoPointer> pointer1;
+ testing::StrictMock<MockProtoPointer> pointer2;
+ testing::StrictMock<MockProtoAxisValue> axisValue1;
+ testing::StrictMock<MockProtoAxisValue> axisValue2;
+ testing::StrictMock<MockProtoAxisValue> axisValue3;
+ testing::StrictMock<MockProtoAxisValue> axisValue4;
+
+ EXPECT_CALL(proto, set_event_id(0));
+ EXPECT_CALL(proto, set_event_time_nanos(0));
+ EXPECT_CALL(proto, set_down_time_nanos(0));
+ EXPECT_CALL(proto, set_source(AINPUT_SOURCE_MOUSE));
+ EXPECT_CALL(proto, set_action(AMOTION_EVENT_ACTION_BUTTON_PRESS));
+ EXPECT_CALL(proto, set_device_id(0));
+ EXPECT_CALL(proto, set_display_id(0));
+ EXPECT_CALL(proto, set_classification(0));
+ EXPECT_CALL(proto, set_flags(0));
+ EXPECT_CALL(proto, set_policy_flags(0));
+ EXPECT_CALL(proto, set_button_state(0));
+ EXPECT_CALL(proto, set_action_button(0));
+ EXPECT_CALL(proto, set_cursor_position_x(0.0f));
+ EXPECT_CALL(proto, set_cursor_position_y(0.0f));
+ EXPECT_CALL(proto, set_meta_state(0));
+ EXPECT_CALL(proto, set_precision_x(0.0f));
+ EXPECT_CALL(proto, set_precision_y(0.0f));
+
+ EXPECT_CALL(proto, add_pointer()).WillOnce(Return(&pointer1)).WillOnce(Return(&pointer2));
+
+ EXPECT_CALL(pointer1, set_pointer_id(0));
+ EXPECT_CALL(pointer1, set_tool_type(AMOTION_EVENT_TOOL_TYPE_MOUSE));
+ EXPECT_CALL(pointer1, add_axis_value())
+ .WillOnce(Return(&axisValue1))
+ .WillOnce(Return(&axisValue2));
+ EXPECT_CALL(axisValue1, set_axis(AMOTION_EVENT_AXIS_X));
+ EXPECT_CALL(axisValue1, set_value(0.0f));
+ EXPECT_CALL(axisValue2, set_axis(AMOTION_EVENT_AXIS_Y));
+ EXPECT_CALL(axisValue2, set_value(1.0f));
+
+ EXPECT_CALL(pointer2, set_pointer_id(1));
+ EXPECT_CALL(pointer2, set_tool_type(AMOTION_EVENT_TOOL_TYPE_FINGER));
+ EXPECT_CALL(pointer2, add_axis_value())
+ .WillOnce(Return(&axisValue3))
+ .WillOnce(Return(&axisValue4));
+ EXPECT_CALL(axisValue3, set_axis(AMOTION_EVENT_AXIS_X));
+ EXPECT_CALL(axisValue3, set_value(0.0f));
+ EXPECT_CALL(axisValue4, set_axis(AMOTION_EVENT_AXIS_Y));
+ EXPECT_CALL(axisValue4, set_value(0.0f));
+
+ TestProtoConverter::toProtoMotionEvent(event, proto, /*isRedacted=*/false);
+}
+
} // namespace
} // namespace android::inputdispatcher::trace