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

Commit 78ed9adf authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Convert motion flags to use ftl::Flags

This will help ensure correctness of the flags, and will allow us to
eventually move away from the raw flags.

It will also make it more clear that the Java-based intdefs (to be
defined in a separate CL) are related to these native flags.

Things like NotifyMotionArgs and all key-related objects are left
unconverted, as an exercise for the reader.

Bug: 245989146
Test: none
Flag: EXEMPT refactor
Change-Id: I1af7f43f19c22cefdd710b18bfa3938024832ae0
parent 602de16c
Loading
Loading
Loading
Loading
+55 −30
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <android/os/MotionEventFlag.h>
#endif
#include <android/os/PointerIconType.h>
#include <ftl/flags.h>
#include <math.h>
#include <stdint.h>
#include <ui/LogicalDisplayId.h>
@@ -57,6 +58,7 @@ enum {
    AKEY_EVENT_FLAG_TAINTED = android::os::IInputConstants::INPUT_EVENT_FLAG_TAINTED,
};

// TODO(b/245989146): Remove these definitions and use MotionFlag enum directly.
enum {
    // AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED is defined in include/android/input.h
    /**
@@ -128,20 +130,6 @@ enum {
            AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION,
};

/**
 * Allowed VerifiedKeyEvent flags. All other flags from KeyEvent do not get verified.
 * These values must be kept in sync with VerifiedKeyEvent.java
 */
constexpr int32_t VERIFIED_KEY_EVENT_FLAGS =
        AKEY_EVENT_FLAG_CANCELED | AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;

/**
 * Allowed VerifiedMotionEventFlags. All other flags from MotionEvent do not get verified.
 * These values must be kept in sync with VerifiedMotionEvent.java
 */
constexpr int32_t VERIFIED_MOTION_EVENT_FLAGS = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED |
        AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED | AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;

/**
 * This flag indicates that the point up event has been canceled.
 * Typically this is used for palm event when the user has accidental touches.
@@ -232,6 +220,39 @@ struct AInputDevice {

namespace android {

enum class MotionFlag : uint32_t {
    // clang-format off
    CANCELED = android::os::IInputConstants::INPUT_EVENT_FLAG_CANCELED,
    WINDOW_IS_OBSCURED = static_cast<uint32_t>(android::os::MotionEventFlag::WINDOW_IS_OBSCURED),
    WINDOW_IS_PARTIALLY_OBSCURED = static_cast<uint32_t>(android::os::MotionEventFlag::WINDOW_IS_PARTIALLY_OBSCURED),
    HOVER_EXIT_PENDING = static_cast<uint32_t>(android::os::MotionEventFlag::HOVER_EXIT_PENDING),
    IS_GENERATED_GESTURE = static_cast<uint32_t>(android::os::MotionEventFlag::IS_GENERATED_GESTURE),
    NO_FOCUS_CHANGE = static_cast<uint32_t>(android::os::MotionEventFlag::NO_FOCUS_CHANGE),
    IS_ACCESSIBILITY_EVENT = static_cast<uint32_t>(android::os::MotionEventFlag::IS_ACCESSIBILITY_EVENT),
    INJECTED_FROM_ACCESSIBILITY_TOOL = static_cast<uint32_t>(android::os::MotionEventFlag::INJECTED_FROM_ACCESSIBILITY_TOOL),
    TARGET_ACCESSIBILITY_FOCUS = static_cast<uint32_t>(android::os::MotionEventFlag::TARGET_ACCESSIBILITY_FOCUS),
    TAINTED = static_cast<uint32_t>(android::os::MotionEventFlag::TAINTED),
    SUPPORTS_ORIENTATION = static_cast<uint32_t>(android::os::MotionEventFlag::PRIVATE_FLAG_SUPPORTS_ORIENTATION),
    SUPPORTS_DIRECTIONAL_ORIENTATION = static_cast<uint32_t>(android::os::MotionEventFlag::PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION),
    // clang-format on
};

/**
 * Allowed VerifiedKeyEvent flags. All other flags from KeyEvent do not get verified.
 * These values must be kept in sync with VerifiedKeyEvent.java
 */
constexpr int32_t VERIFIED_KEY_EVENT_FLAGS =
        AKEY_EVENT_FLAG_CANCELED | AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;

/**
 * Allowed VerifiedMotionEventFlags. All other flags from MotionEvent do not get verified.
 * These values must be kept in sync with VerifiedMotionEvent.java
 */
constexpr ftl::Flags<MotionFlag>
        VERIFIED_MOTION_EVENT_FLAGS{MotionFlag::WINDOW_IS_OBSCURED,
                                    MotionFlag::WINDOW_IS_PARTIALLY_OBSCURED,
                                    MotionFlag::IS_ACCESSIBILITY_EVENT};

class Parcel;

/*
@@ -702,9 +723,9 @@ public:

    inline void setAction(int32_t action) { mAction = action; }

    inline int32_t getFlags() const { return mFlags; }
    inline ftl::Flags<MotionFlag> getFlags() const { return mFlags; }

    inline void setFlags(int32_t flags) { mFlags = flags; }
    inline void setFlags(ftl::Flags<MotionFlag> flags) { mFlags = flags; }

    inline int32_t getEdgeFlags() const { return mEdgeFlags; }

@@ -919,12 +940,13 @@ public:

    void initialize(int32_t id, DeviceId deviceId, uint32_t source, ui::LogicalDisplayId displayId,
                    std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton,
                    int32_t flags, int32_t edgeFlags, int32_t metaState, int32_t buttonState,
                    MotionClassification classification, const ui::Transform& transform,
                    float xPrecision, float yPrecision, float rawXCursorPosition,
                    float rawYCursorPosition, const ui::Transform& rawTransform, nsecs_t downTime,
                    nsecs_t eventTime, size_t pointerCount,
                    const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
                    ftl::Flags<MotionFlag> flags, int32_t edgeFlags, int32_t metaState,
                    int32_t buttonState, MotionClassification classification,
                    const ui::Transform& transform, float xPrecision, float yPrecision,
                    float rawXCursorPosition, float rawYCursorPosition,
                    const ui::Transform& rawTransform, nsecs_t downTime, nsecs_t eventTime,
                    size_t pointerCount, const PointerProperties* pointerProperties,
                    const PointerCoords* pointerCoords);

    void copyFrom(const MotionEvent* other, bool keepHistory);

@@ -986,19 +1008,22 @@ public:

    static std::tuple<int32_t /*action*/, std::vector<PointerProperties>,
                      std::vector<PointerCoords>>
    split(int32_t action, int32_t flags, int32_t historySize, const std::vector<PointerProperties>&,
          const std::vector<PointerCoords>&, std::bitset<MAX_POINTER_ID + 1> splitPointerIds);
    split(int32_t action, ftl::Flags<MotionFlag> flags, int32_t historySize,
          const std::vector<PointerProperties>&, const std::vector<PointerCoords>&,
          std::bitset<MAX_POINTER_ID + 1> splitPointerIds);

    // MotionEvent will transform various axes in different ways, based on the source. For
    // example, the x and y axes will not have any offsets/translations applied if it comes from a
    // relative mouse device (since SOURCE_RELATIVE_MOUSE is a non-pointer source). These methods
    // are used to apply these transformations for different axes.
    static vec2 calculateTransformedXY(uint32_t source, const ui::Transform&, const vec2& xy);
    static float calculateTransformedAxisValue(int32_t axis, uint32_t source, int32_t flags,
                                               const ui::Transform&, const PointerCoords&);
    static float calculateTransformedAxisValue(int32_t axis, uint32_t source,
                                               ftl::Flags<MotionFlag> flags, const ui::Transform&,
                                               const PointerCoords&);
    static void calculateTransformedCoordsInPlace(PointerCoords& coords, uint32_t source,
                                                  int32_t flags, const ui::Transform&);
    static PointerCoords calculateTransformedCoords(uint32_t source, int32_t flags,
                                                  ftl::Flags<MotionFlag> flags,
                                                  const ui::Transform&);
    static PointerCoords calculateTransformedCoords(uint32_t source, ftl::Flags<MotionFlag> flags,
                                                    const ui::Transform&, const PointerCoords&);
    // The rounding precision for transformed motion events.
    static constexpr float ROUNDING_PRECISION = 0.001f;
@@ -1009,7 +1034,7 @@ public:
protected:
    int32_t mAction;
    int32_t mActionButton;
    int32_t mFlags;
    ftl::Flags<MotionFlag> mFlags;
    int32_t mEdgeFlags;
    int32_t mMetaState;
    int32_t mButtonState;
@@ -1158,7 +1183,7 @@ struct __attribute__((__packed__)) VerifiedMotionEvent : public VerifiedInputEve
    float rawX;
    float rawY;
    int32_t actionMasked;
    int32_t flags;
    ftl::Flags<MotionFlag> flags;
    nsecs_t downTimeNanos;
    int32_t metaState;
    int32_t buttonState;
+4 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <android/input.h>
#include <attestation/HmacKeyManager.h>
#include <ftl/flags.h>
#include <input/Input.h>
#include <input/InputTransport.h>
#include <ui/LogicalDisplayId.h>
@@ -251,7 +252,7 @@ public:
    MotionEventBuilder(int32_t action, int32_t source) {
        mAction = action;
        if (mAction == AMOTION_EVENT_ACTION_CANCEL) {
            mFlags |= AMOTION_EVENT_FLAG_CANCELED;
            mFlags |= MotionFlag::CANCELED;
        }
        mSource = source;
        mEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
@@ -303,7 +304,7 @@ public:
        return *this;
    }

    MotionEventBuilder& addFlag(uint32_t flags) {
    MotionEventBuilder& addFlag(ftl::Flags<MotionFlag> flags) {
        mFlags |= flags;
        return *this;
    }
@@ -354,7 +355,7 @@ private:
    ui::LogicalDisplayId mDisplayId{ui::LogicalDisplayId::DEFAULT};
    int32_t mActionButton{0};
    int32_t mButtonState{0};
    int32_t mFlags{0};
    ftl::Flags<MotionFlag> mFlags{};
    float mRawXCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
    float mRawYCursorPosition{AMOTION_EVENT_INVALID_CURSOR_POSITION};
    ui::Transform mTransform;
+7 −7
Original line number Diff line number Diff line
@@ -206,17 +206,17 @@ public:
        EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
        EXPECT_NEAR(x, mev->getX(0), EPSILON);
        EXPECT_NEAR(y, mev->getY(0), EPSILON);
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
        EXPECT_EQ(ftl::Flags<MotionFlag>{}, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);

        ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(InputEventType::MOTION, ev->getType());
        mev = static_cast<MotionEvent*>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
        EXPECT_EQ(ftl::Flags<MotionFlag>{}, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
    }

    void expectTapWithFlag(int x, int y, int32_t flags) {
    void expectTapWithFlag(int x, int y, ftl::Flags<MotionFlag> flags) {
        InputEvent* ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(InputEventType::MOTION, ev->getType());
@@ -243,14 +243,14 @@ public:
        const PointerCoords& coords = *mev->getRawPointerCoords(0 /*pointerIndex*/);
        EXPECT_NEAR(displayX, coords.getX(), EPSILON);
        EXPECT_NEAR(displayY, coords.getY(), EPSILON);
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
        EXPECT_EQ(ftl::Flags<MotionFlag>{}, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);

        ev = consumeEvent();
        ASSERT_NE(ev, nullptr);
        ASSERT_EQ(InputEventType::MOTION, ev->getType());
        mev = static_cast<MotionEvent*>(ev);
        EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
        EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
        EXPECT_EQ(ftl::Flags<MotionFlag>{}, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
    }

    void expectKey(int32_t keycode) {
@@ -863,7 +863,7 @@ TEST_F(InputSurfacesTest, touch_flag_obscured) {
    nonTouchableSurface->showAt(100, 100);

    injectTap(190, 199);
    surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED);
    surface->expectTapWithFlag(90, 99, MotionFlag::WINDOW_IS_OBSCURED);
}

TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
@@ -891,7 +891,7 @@ TEST_F(InputSurfacesTest, touch_flag_partially_obscured_with_crop) {
    });

    injectTap(190, 199);
    surface->expectTapWithFlag(90, 99, AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED);
    surface->expectTapWithFlag(90, 99, MotionFlag::WINDOW_IS_PARTIALLY_OBSCURED);
}

TEST_F(InputSurfacesTest, touch_not_obscured_with_crop) {
+21 −18
Original line number Diff line number Diff line
@@ -58,7 +58,8 @@ bool shouldDisregardOffset(uint32_t source) {
}

int32_t resolveActionForSplitMotionEvent(
        int32_t action, int32_t flags, const std::vector<PointerProperties>& pointerProperties,
        int32_t action, ftl::Flags<MotionFlag> flags,
        const std::vector<PointerProperties>& pointerProperties,
        const std::vector<PointerProperties>& splitPointerProperties) {
    LOG_ALWAYS_FATAL_IF(splitPointerProperties.empty());
    const auto maskedAction = MotionEvent::getActionMasked(action);
@@ -90,20 +91,20 @@ int32_t resolveActionForSplitMotionEvent(
    }

    if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
        return ((flags & AMOTION_EVENT_FLAG_CANCELED) != 0) ? AMOTION_EVENT_ACTION_CANCEL
        return flags.test(MotionFlag::CANCELED) ? AMOTION_EVENT_ACTION_CANCEL
                                                : AMOTION_EVENT_ACTION_UP;
    }
    return AMOTION_EVENT_ACTION_DOWN;
}

float transformOrientation(const ui::Transform& transform, const PointerCoords& coords,
                           int32_t motionEventFlags) {
    if ((motionEventFlags & AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION) == 0) {
                           ftl::Flags<MotionFlag> motionEventFlags) {
    if (!motionEventFlags.test(MotionFlag::SUPPORTS_ORIENTATION)) {
        return 0;
    }

    const bool isDirectionalAngle =
            (motionEventFlags & AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION) != 0;
            motionEventFlags.test(MotionFlag::SUPPORTS_DIRECTIONAL_ORIENTATION);

    return transformAngle(transform, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
                          isDirectionalAngle);
@@ -582,8 +583,8 @@ bool PointerCoords::operator==(const PointerCoords& other) const {

void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source,
                             ui::LogicalDisplayId displayId, std::array<uint8_t, 32> hmac,
                             int32_t action, int32_t actionButton, int32_t flags, int32_t edgeFlags,
                             int32_t metaState, int32_t buttonState,
                             int32_t action, int32_t actionButton, ftl::Flags<MotionFlag> flags,
                             int32_t edgeFlags, int32_t metaState, int32_t buttonState,
                             MotionClassification classification, const ui::Transform& transform,
                             float xPrecision, float yPrecision, float rawXCursorPosition,
                             float rawYCursorPosition, const ui::Transform& rawTransform,
@@ -871,7 +872,7 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) {
    std::move(hmac.begin(), hmac.begin() + hmac.size(), mHmac.begin());
    mAction = parcel->readInt32();
    mActionButton = parcel->readInt32();
    mFlags = parcel->readInt32();
    mFlags = ftl::Flags<MotionFlag>(parcel->readUint32());
    mEdgeFlags = parcel->readInt32();
    mMetaState = parcel->readInt32();
    mButtonState = parcel->readInt32();
@@ -935,7 +936,7 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const {
    parcel->writeByteVector(hmac);
    parcel->writeInt32(mAction);
    parcel->writeInt32(mActionButton);
    parcel->writeInt32(mFlags);
    parcel->writeUint32(mFlags.get());
    parcel->writeInt32(mEdgeFlags);
    parcel->writeInt32(mMetaState);
    parcel->writeInt32(mButtonState);
@@ -1034,7 +1035,7 @@ std::string MotionEvent::actionToString(int32_t action) {
}

std::tuple<int32_t, std::vector<PointerProperties>, std::vector<PointerCoords>> MotionEvent::split(
        int32_t action, int32_t flags, int32_t historySize,
        int32_t action, ftl::Flags<MotionFlag> flags, int32_t historySize,
        const std::vector<PointerProperties>& pointerProperties,
        const std::vector<PointerCoords>& pointerCoords,
        std::bitset<MAX_POINTER_ID + 1> splitPointerIds) {
@@ -1090,7 +1091,8 @@ vec2 MotionEvent::calculateTransformedXY(uint32_t source, const ui::Transform& t
}

// Keep in sync with calculateTransformedCoords.
float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source, int32_t flags,
float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
                                                 ftl::Flags<MotionFlag> flags,
                                                 const ui::Transform& transform,
                                                 const PointerCoords& coords) {
    if (shouldDisregardTransformation(source)) {
@@ -1121,7 +1123,8 @@ float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
// Keep in sync with calculateTransformedAxisValue. This is an optimization of
// calculateTransformedAxisValue for all PointerCoords axes.
void MotionEvent::calculateTransformedCoordsInPlace(PointerCoords& coords, uint32_t source,
                                                    int32_t flags, const ui::Transform& transform) {
                                                    ftl::Flags<MotionFlag> flags,
                                                    const ui::Transform& transform) {
    if (shouldDisregardTransformation(source)) {
        return;
    }
@@ -1141,7 +1144,7 @@ void MotionEvent::calculateTransformedCoordsInPlace(PointerCoords& coords, uint3
                        transformOrientation(transform, coords, flags));
}

PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source, int32_t flags,
PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source, ftl::Flags<MotionFlag> flags,
                                                      const ui::Transform& transform,
                                                      const PointerCoords& coords) {
    PointerCoords out = coords;
@@ -1193,8 +1196,8 @@ std::string MotionEvent::safeDump() const {
    if (mMetaState != 0) {
        out << ", mMetaState=" << mMetaState;
    }
    if (mFlags != 0) {
        out << ", mFlags=0x" << std::hex << mFlags << std::dec;
    if (mFlags.any()) {
        out << ", mFlags=" << mFlags.string();
    }
    if (mEdgeFlags != 0) {
        out << ", mEdgeFlags=" << mEdgeFlags;
@@ -1253,8 +1256,8 @@ std::ostream& operator<<(std::ostream& out, const MotionEvent& event) {
    if (event.getMetaState() != 0) {
        out << ", metaState=" << event.getMetaState();
    }
    if (event.getFlags() != 0) {
        out << ", flags=0x" << std::hex << event.getFlags() << std::dec;
    if (event.getFlags().any()) {
        out << ", flags=" << event.getFlags().string();
    }
    if (event.getEdgeFlags() != 0) {
        out << ", edgeFlags=" << event.getEdgeFlags();
+7 −7
Original line number Diff line number Diff line
@@ -118,13 +118,13 @@ void initializeMotionEvent(MotionEvent& event, const InputMessage& msg) {
                          0, 0, 1});
    event.initialize(msg.body.motion.eventId, msg.body.motion.deviceId, msg.body.motion.source,
                     ui::LogicalDisplayId{msg.body.motion.displayId}, msg.body.motion.hmac,
                     msg.body.motion.action, msg.body.motion.actionButton, msg.body.motion.flags,
                     msg.body.motion.edgeFlags, msg.body.motion.metaState,
                     msg.body.motion.buttonState, msg.body.motion.classification, transform,
                     msg.body.motion.xPrecision, msg.body.motion.yPrecision,
                     msg.body.motion.xCursorPosition, msg.body.motion.yCursorPosition,
                     displayTransform, msg.body.motion.downTime, msg.body.motion.eventTime,
                     pointerCount, pointerProperties, pointerCoords);
                     msg.body.motion.action, msg.body.motion.actionButton,
                     ftl::Flags<MotionFlag>(msg.body.motion.flags), msg.body.motion.edgeFlags,
                     msg.body.motion.metaState, msg.body.motion.buttonState,
                     msg.body.motion.classification, transform, msg.body.motion.xPrecision,
                     msg.body.motion.yPrecision, msg.body.motion.xCursorPosition,
                     msg.body.motion.yCursorPosition, displayTransform, msg.body.motion.downTime,
                     msg.body.motion.eventTime, pointerCount, pointerProperties, pointerCoords);
}

void addSample(MotionEvent& event, const InputMessage& msg) {
Loading