diff options
| author | 2025-01-28 03:49:54 +0000 | |
|---|---|---|
| committer | 2025-01-29 09:09:37 -0800 | |
| commit | 2889b8f2801e5cfc2b8d5cb491010e4d81673abc (patch) | |
| tree | 0e5b6454ef0836fd60f433ef668d64c764a32234 | |
| parent | ea395bfbeb4a53e3c9b7466b7031a8c8819d7659 (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.h | 28 | ||||
| -rw-r--r-- | services/inputflinger/tests/AndroidInputEventProtoConverter_test.cpp | 90 |
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 |