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

Commit 2889b8f2 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

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
parent ea395bfb
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -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,14 +95,20 @@ 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);
            }
        }
    }
+90 −0
Original line number Diff line number Diff line
@@ -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