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

Commit 8e6ce224 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Fix input injection with zero coords

In the native MotionEvent class, setting an axis value to 0 is
equivalent to removing the axis from the bitfield of valid axes. This is
because getting an axis value that is not set in the bitfield will
return 0 by default.

This means that we cannot rely on the bitfield of valid axes to know
exactly which axes are valid, since all axes are always valid with a
default value of 0.

Rather than transforming only the axies that are set in the bitfield, we
add a helper function to MotionEvent to transform the entire
PointerCoords.

Bug: 219711163
Test: manual, see bug: adb shell input draganddrop 665 531 0 531 1000
Change-Id: I335beebf8263a38f180f2f4c6a788fbd69d15a6f
Merged-In: I335beebf8263a38f180f2f4c6a788fbd69d15a6f
(cherry picked from commit 890532e4)
parent e73b8065
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -814,6 +814,8 @@ public:
    static vec2 calculateTransformedXY(uint32_t source, const ui::Transform&, const vec2& xy);
    static float calculateTransformedAxisValue(int32_t axis, uint32_t source, const ui::Transform&,
                                               const PointerCoords&);
    static PointerCoords calculateTransformedCoords(uint32_t source, const ui::Transform&,
                                                    const PointerCoords&);

protected:
    int32_t mAction;
+29 −0
Original line number Diff line number Diff line
@@ -846,6 +846,7 @@ vec2 MotionEvent::calculateTransformedXY(uint32_t source, const ui::Transform& t
    return calculateTransformedXYUnchecked(source, transform, xy);
}

// Keep in sync with calculateTransformedCoords.
float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
                                                 const ui::Transform& transform,
                                                 const PointerCoords& coords) {
@@ -874,6 +875,34 @@ float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
    return coords.getAxisValue(axis);
}

// Keep in sync with calculateTransformedAxisValue. This is an optimization of
// calculateTransformedAxisValue for all PointerCoords axes.
PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source,
                                                      const ui::Transform& transform,
                                                      const PointerCoords& coords) {
    if (shouldDisregardTransformation(source)) {
        return coords;
    }
    PointerCoords out = coords;

    const vec2 xy = calculateTransformedXYUnchecked(source, transform, coords.getXYValue());
    out.setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
    out.setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);

    const vec2 relativeXy =
            transformWithoutTranslation(transform,
                                        {coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
                                         coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
    out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, relativeXy.x);
    out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, relativeXy.y);

    out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
                     transformAngle(transform,
                                    coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION)));

    return out;
}

// --- FocusEvent ---

void FocusEvent::initialize(int32_t id, bool hasFocus) {
+3 −13
Original line number Diff line number Diff line
@@ -4426,19 +4426,9 @@ void InputDispatcher::transformMotionEntryForInjectionLocked(
    const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;

    for (uint32_t i = 0; i < entry.pointerCount; i++) {
        PointerCoords& pc = entry.pointerCoords[i];
        // Make a copy of the injected coords. We cannot change them in place because some of them
        // are interdependent (for example, X coordinate might depend on the Y coordinate).
        PointerCoords injectedCoords = entry.pointerCoords[i];

        BitSet64 bits(injectedCoords.bits);
        while (!bits.isEmpty()) {
            const auto axis = static_cast<int32_t>(bits.clearFirstMarkedBit());
            const float value =
                    MotionEvent::calculateTransformedAxisValue(axis, entry.source,
                                                               transformToDisplay, injectedCoords);
            pc.setAxisValue(axis, value);
        }
        entry.pointerCoords[i] =
                MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay,
                                                        entry.pointerCoords[i]);
    }
}