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

Commit 746ea4a5 authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Android (Google) Code Review
Browse files

Merge "MotionEvent: Differentiate directional support for AXIS_ORIENTATION" into main

parents 38735c19 9a53b55a
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -99,6 +99,18 @@ enum {

    /* Motion event is inconsistent with previously sent motion events. */
    AMOTION_EVENT_FLAG_TAINTED = android::os::IInputConstants::INPUT_EVENT_FLAG_TAINTED,

    /** Private flag, not used in Java. */
    AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION =
            android::os::IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION,

    /** Private flag, not used in Java. */
    AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = android::os::IInputConstants::
            MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION,

    /** Mask for all private flags that are not used in Java. */
    AMOTION_EVENT_PRIVATE_FLAG_MASK = AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
            AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION,
};

/**
@@ -209,8 +221,12 @@ vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy)
 * Transform an angle on the x-y plane. An angle of 0 radians corresponds to "north" or
 * pointing upwards in the negative Y direction, a positive angle points towards the right, and a
 * negative angle points towards the left.
 *
 * If the angle represents a direction that needs to be preserved, set isDirectional to true to get
 * an output range of [-pi, pi]. If the angle's direction does not need to be preserved, set
 * isDirectional to false to get an output range of [-pi/2, pi/2].
 */
float transformAngle(const ui::Transform& transform, float angleRadians);
float transformAngle(const ui::Transform& transform, float angleRadians, bool isDirectional);

/**
 * The type of the InputEvent.
@@ -472,7 +488,7 @@ struct PointerCoords {
    // axes, however the window scaling will not.
    void scale(float globalScale, float windowXScale, float windowYScale);

    void transform(const ui::Transform& transform);
    void transform(const ui::Transform& transform, int32_t motionEventFlags);

    inline float getX() const {
        return getAxisValue(AMOTION_EVENT_AXIS_X);
@@ -940,10 +956,10 @@ public:
    // 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, const ui::Transform&,
                                               const PointerCoords&);
    static PointerCoords calculateTransformedCoords(uint32_t source, const ui::Transform&,
                                                    const PointerCoords&);
    static float calculateTransformedAxisValue(int32_t axis, uint32_t source, int32_t flags,
                                               const ui::Transform&, const PointerCoords&);
    static PointerCoords calculateTransformedCoords(uint32_t source, int32_t flags,
                                                    const ui::Transform&, const PointerCoords&);
    // The rounding precision for transformed motion events.
    static constexpr float ROUNDING_PRECISION = 0.001f;

+30 −13
Original line number Diff line number Diff line
@@ -96,6 +96,19 @@ int32_t resolveActionForSplitMotionEvent(
    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) {
        return 0;
    }

    const bool isDirectionalAngle =
            (motionEventFlags & AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION) != 0;

    return transformAngle(transform, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
                          isDirectionalAngle);
}

} // namespace

const char* motionClassificationToString(MotionClassification classification) {
@@ -187,7 +200,7 @@ vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy)
    return roundTransformedCoords(transformedXy - transformedOrigin);
}

float transformAngle(const ui::Transform& transform, float angleRadians) {
float transformAngle(const ui::Transform& transform, float angleRadians, bool isDirectional) {
    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
    // Coordinate system: down is increasing Y, right is increasing X.
    float x = sinf(angleRadians);
@@ -201,6 +214,11 @@ float transformAngle(const ui::Transform& transform, float angleRadians) {
    transformedPoint.x -= origin.x;
    transformedPoint.y -= origin.y;

    if (!isDirectional && transformedPoint.y > 0) {
        // Limit the range of atan2f to [-pi/2, pi/2] by reversing the direction of the vector.
        transformedPoint *= -1;
    }

    // Derive the transformed vector's clockwise angle from vertical.
    // The return value of atan2f is in range [-pi, pi] which conforms to the orientation API.
    return atan2f(transformedPoint.x, -transformedPoint.y);
@@ -530,7 +548,7 @@ bool PointerCoords::operator==(const PointerCoords& other) const {
    return true;
}

void PointerCoords::transform(const ui::Transform& transform) {
void PointerCoords::transform(const ui::Transform& transform, int32_t motionEventFlags) {
    const vec2 xy = transform.transform(getXYValue());
    setAxisValue(AMOTION_EVENT_AXIS_X, xy.x);
    setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y);
@@ -544,9 +562,9 @@ void PointerCoords::transform(const ui::Transform& transform) {
        setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, relativeXy.y);
    }

    if (BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_ORIENTATION)) {
        const float val = getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
        setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(transform, val));
    if ((motionEventFlags & AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION) != 0) {
        setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION,
                     transformOrientation(transform, *this, motionEventFlags));
    }
}

@@ -723,13 +741,13 @@ const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
                                             size_t historicalIndex) const {
    const PointerCoords& coords = *getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
    return calculateTransformedAxisValue(axis, mSource, mRawTransform, coords);
    return calculateTransformedAxisValue(axis, mSource, mFlags, mRawTransform, coords);
}

float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
                                          size_t historicalIndex) const {
    const PointerCoords& coords = *getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
    return calculateTransformedAxisValue(axis, mSource, mTransform, coords);
    return calculateTransformedAxisValue(axis, mSource, mFlags, mTransform, coords);
}

ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
@@ -787,7 +805,7 @@ void MotionEvent::applyTransform(const std::array<float, 9>& matrix) {

    // Apply the transformation to all samples.
    std::for_each(mSamplePointerCoords.begin(), mSamplePointerCoords.end(),
                  [&transform](PointerCoords& c) { c.transform(transform); });
                  [&](PointerCoords& c) { c.transform(transform, mFlags); });

    if (mRawXCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
        mRawYCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
@@ -1059,7 +1077,7 @@ vec2 MotionEvent::calculateTransformedXY(uint32_t source, const ui::Transform& t
}

// Keep in sync with calculateTransformedCoords.
float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source, int32_t flags,
                                                 const ui::Transform& transform,
                                                 const PointerCoords& coords) {
    if (shouldDisregardTransformation(source)) {
@@ -1081,7 +1099,7 @@ float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,
    }

    if (axis == AMOTION_EVENT_AXIS_ORIENTATION) {
        return transformAngle(transform, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
        return transformOrientation(transform, coords, flags);
    }

    return coords.getAxisValue(axis);
@@ -1089,7 +1107,7 @@ float MotionEvent::calculateTransformedAxisValue(int32_t axis, uint32_t source,

// Keep in sync with calculateTransformedAxisValue. This is an optimization of
// calculateTransformedAxisValue for all PointerCoords axes.
PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source,
PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source, int32_t flags,
                                                      const ui::Transform& transform,
                                                      const PointerCoords& coords) {
    if (shouldDisregardTransformation(source)) {
@@ -1109,8 +1127,7 @@ PointerCoords MotionEvent::calculateTransformedCoords(uint32_t source,
    out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, relativeXy.y);

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

    return out;
}
+25 −0
Original line number Diff line number Diff line
@@ -115,6 +115,31 @@ interface IInputConstants
     */
    const int MOTION_EVENT_FLAG_NO_FOCUS_CHANGE = 0x40;

    /**
     * This flag indicates that the event has a valid value for AXIS_ORIENTATION.
     *
     * This is a private flag that is not used in Java.
     * @hide
     */
    const int MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION = 0x80;

    /**
     * This flag indicates that the pointers' AXIS_ORIENTATION can be used to precisely determine
     * the direction in which the tool is pointing. The value of the orientation axis will be in
     * the range [-pi, pi], which represents a full circle. This is usually supported by devices
     * like styluses.
     *
     * Conversely, AXIS_ORIENTATION cannot be used to tell which direction the tool is pointing
     * when this flag is not set. In this case, the axis value will have a range of [-pi/2, pi/2],
     * which represents half a circle. This is usually the case for devices like touchscreens and
     * touchpads, for which it is difficult to tell which direction along the major axis of the
     * touch ellipse the finger is pointing.
     *
     * This is a private flag that is not used in Java.
     * @hide
     */
    const int MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = 0x100;

    /**
     * The input event was generated or modified by accessibility service.
     * Shared by both KeyEvent and MotionEvent flags, so this value should not overlap with either
+125 −14
Original line number Diff line number Diff line
@@ -26,23 +26,39 @@

namespace android {

namespace {

// Default display id.
static constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;

static constexpr float EPSILON = MotionEvent::ROUNDING_PRECISION;
constexpr float EPSILON = MotionEvent::ROUNDING_PRECISION;

static constexpr auto POINTER_0_DOWN =
constexpr auto POINTER_0_DOWN =
        AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);

static constexpr auto POINTER_1_DOWN =
constexpr auto POINTER_1_DOWN =
        AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);

static constexpr auto POINTER_0_UP =
constexpr auto POINTER_0_UP =
        AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);

static constexpr auto POINTER_1_UP =
constexpr auto POINTER_1_UP =
        AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);

std::array<float, 9> asFloat9(const ui::Transform& t) {
    std::array<float, 9> mat{};
    mat[0] = t[0][0];
    mat[1] = t[1][0];
    mat[2] = t[2][0];
    mat[3] = t[0][1];
    mat[4] = t[1][1];
    mat[5] = t[2][1];
    mat[6] = t[0][2];
    mat[7] = t[1][2];
    mat[8] = t[2][2];
    return mat;
}

class BaseTest : public testing::Test {
protected:
    static constexpr std::array<uint8_t, 32> HMAC = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
@@ -50,6 +66,8 @@ protected:
                                                     22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
};

} // namespace

// --- PointerCoordsTest ---

class PointerCoordsTest : public BaseTest {
@@ -344,13 +362,15 @@ void MotionEventTest::SetUp() {
}

void MotionEventTest::initializeEventWithHistory(MotionEvent* event) {
    const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED |
            AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
            AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION;
    event->initialize(mId, 2, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, HMAC,
                      AMOTION_EVENT_ACTION_MOVE, 0, AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED,
                      AMOTION_EVENT_EDGE_FLAG_TOP, AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY,
                      MotionClassification::NONE, mTransform, 2.0f, 2.1f,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
                      mRawTransform, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2,
                      mPointerProperties, mSamples[0].pointerCoords);
                      AMOTION_EVENT_ACTION_MOVE, 0, flags, AMOTION_EVENT_EDGE_FLAG_TOP,
                      AMETA_ALT_ON, AMOTION_EVENT_BUTTON_PRIMARY, MotionClassification::NONE,
                      mTransform, 2.0f, 2.1f, AMOTION_EVENT_INVALID_CURSOR_POSITION,
                      AMOTION_EVENT_INVALID_CURSOR_POSITION, mRawTransform, ARBITRARY_DOWN_TIME,
                      ARBITRARY_EVENT_TIME, 2, mPointerProperties, mSamples[0].pointerCoords);
    event->addSample(ARBITRARY_EVENT_TIME + 1, mSamples[1].pointerCoords);
    event->addSample(ARBITRARY_EVENT_TIME + 2, mSamples[2].pointerCoords);
}
@@ -364,7 +384,10 @@ void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
    ASSERT_EQ(DISPLAY_ID, event->getDisplayId());
    EXPECT_EQ(HMAC, event->getHmac());
    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, event->getAction());
    ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED, event->getFlags());
    ASSERT_EQ(AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED |
                      AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
                      AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION,
              event->getFlags());
    ASSERT_EQ(AMOTION_EVENT_EDGE_FLAG_TOP, event->getEdgeFlags());
    ASSERT_EQ(AMETA_ALT_ON, event->getMetaState());
    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, event->getButtonState());
@@ -799,8 +822,10 @@ TEST_F(MotionEventTest, Transform) {
    }
    MotionEvent event;
    ui::Transform identityTransform;
    const int32_t flags = AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
            AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION;
    event.initialize(InputEvent::nextId(), /*deviceId=*/0, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID,
                     INVALID_HMAC, AMOTION_EVENT_ACTION_MOVE, /*actionButton=*/0, /*flags=*/0,
                     INVALID_HMAC, AMOTION_EVENT_ACTION_MOVE, /*actionButton=*/0, flags,
                     AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE, /*buttonState=*/0,
                     MotionClassification::NONE, identityTransform, /*xPrecision=*/0,
                     /*yPrecision=*/0, /*xCursorPosition=*/3 + RADIUS, /*yCursorPosition=*/2,
@@ -1087,4 +1112,90 @@ TEST_F(MotionEventTest, CoordinatesAreRoundedAppropriately) {
    ASSERT_EQ(EXPECTED.y, event.getYCursorPosition());
}

TEST_F(MotionEventTest, InvalidOrientationNotRotated) {
    // This touch event does not have a value for AXIS_ORIENTATION, and the flags are implicitly
    // set to 0. The transform is set to a 90-degree rotation.
    MotionEvent event = MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
                                .downTime(ARBITRARY_DOWN_TIME)
                                .pointer(PointerBuilder(/*id=*/4, ToolType::FINGER).x(4).y(4))
                                .transform(ui::Transform(ui::Transform::ROT_90, 100, 100))
                                .rawTransform(ui::Transform(ui::Transform::FLIP_H, 50, 50))
                                .build();
    ASSERT_EQ(event.getOrientation(/*pointerIndex=*/0), 0.f);
    event.transform(asFloat9(ui::Transform(ui::Transform::ROT_90, 100, 100)));
    ASSERT_EQ(event.getOrientation(/*pointerIndex=*/0), 0.f);
    event.transform(asFloat9(ui::Transform(ui::Transform::ROT_180, 100, 100)));
    ASSERT_EQ(event.getOrientation(/*pointerIndex=*/0), 0.f);
    event.applyTransform(asFloat9(ui::Transform(ui::Transform::ROT_270, 100, 100)));
    ASSERT_EQ(event.getOrientation(/*pointerIndex=*/0), 0.f);
}

TEST_F(MotionEventTest, ValidZeroOrientationRotated) {
    // This touch events will implicitly have a value of 0 for its AXIS_ORIENTATION.
    auto builder = MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
                           .downTime(ARBITRARY_DOWN_TIME)
                           .pointer(PointerBuilder(/*id=*/4, ToolType::FINGER).x(4).y(4))
                           .transform(ui::Transform(ui::Transform::ROT_90, 100, 100))
                           .rawTransform(ui::Transform(ui::Transform::FLIP_H, 50, 50))
                           .addFlag(AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION);
    MotionEvent nonDirectionalEvent = builder.build();
    MotionEvent directionalEvent =
            builder.addFlag(AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION).build();

    // The angle is rotated by the initial transform, a 90-degree rotation.
    ASSERT_NEAR(fabs(nonDirectionalEvent.getOrientation(/*pointerIndex=*/0)), M_PI_2, EPSILON);
    ASSERT_NEAR(directionalEvent.getOrientation(/*pointerIndex=*/0), M_PI_2, EPSILON);

    nonDirectionalEvent.transform(asFloat9(ui::Transform(ui::Transform::ROT_90, 100, 100)));
    directionalEvent.transform(asFloat9(ui::Transform(ui::Transform::ROT_90, 100, 100)));
    ASSERT_NEAR(nonDirectionalEvent.getOrientation(/*pointerIndex=*/0), 0.f, EPSILON);
    ASSERT_NEAR(fabs(directionalEvent.getOrientation(/*pointerIndex=*/0)), M_PI, EPSILON);

    nonDirectionalEvent.transform(asFloat9(ui::Transform(ui::Transform::ROT_180, 100, 100)));
    directionalEvent.transform(asFloat9(ui::Transform(ui::Transform::ROT_180, 100, 100)));
    ASSERT_NEAR(nonDirectionalEvent.getOrientation(/*pointerIndex=*/0), 0.f, EPSILON);
    ASSERT_NEAR(directionalEvent.getOrientation(/*pointerIndex=*/0), 0.f, EPSILON);

    nonDirectionalEvent.applyTransform(asFloat9(ui::Transform(ui::Transform::ROT_270, 100, 100)));
    directionalEvent.applyTransform(asFloat9(ui::Transform(ui::Transform::ROT_270, 100, 100)));
    ASSERT_NEAR(fabs(nonDirectionalEvent.getOrientation(/*pointerIndex=*/0)), M_PI_2, EPSILON);
    ASSERT_NEAR(directionalEvent.getOrientation(/*pointerIndex=*/0), -M_PI_2, EPSILON);
}

TEST_F(MotionEventTest, ValidNonZeroOrientationRotated) {
    const float initial = 1.f;
    auto builder = MotionEventBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN)
                           .downTime(ARBITRARY_DOWN_TIME)
                           .pointer(PointerBuilder(/*id=*/4, ToolType::FINGER)
                                            .x(4)
                                            .y(4)
                                            .axis(AMOTION_EVENT_AXIS_ORIENTATION, initial))
                           .transform(ui::Transform(ui::Transform::ROT_90, 100, 100))
                           .rawTransform(ui::Transform(ui::Transform::FLIP_H, 50, 50))
                           .addFlag(AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION);

    MotionEvent nonDirectionalEvent = builder.build();
    MotionEvent directionalEvent =
            builder.addFlag(AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION).build();

    // The angle is rotated by the initial transform, a 90-degree rotation.
    ASSERT_NEAR(nonDirectionalEvent.getOrientation(/*pointerIndex=*/0), initial - M_PI_2, EPSILON);
    ASSERT_NEAR(directionalEvent.getOrientation(/*pointerIndex=*/0), initial + M_PI_2, EPSILON);

    nonDirectionalEvent.transform(asFloat9(ui::Transform(ui::Transform::ROT_90, 100, 100)));
    directionalEvent.transform(asFloat9(ui::Transform(ui::Transform::ROT_90, 100, 100)));
    ASSERT_NEAR(nonDirectionalEvent.getOrientation(/*pointerIndex=*/0), initial, EPSILON);
    ASSERT_NEAR(directionalEvent.getOrientation(/*pointerIndex=*/0), initial - M_PI, EPSILON);

    nonDirectionalEvent.transform(asFloat9(ui::Transform(ui::Transform::ROT_180, 100, 100)));
    directionalEvent.transform(asFloat9(ui::Transform(ui::Transform::ROT_180, 100, 100)));
    ASSERT_NEAR(nonDirectionalEvent.getOrientation(/*pointerIndex=*/0), initial, EPSILON);
    ASSERT_NEAR(directionalEvent.getOrientation(/*pointerIndex=*/0), initial, EPSILON);

    nonDirectionalEvent.applyTransform(asFloat9(ui::Transform(ui::Transform::ROT_270, 100, 100)));
    directionalEvent.applyTransform(asFloat9(ui::Transform(ui::Transform::ROT_270, 100, 100)));
    ASSERT_NEAR(nonDirectionalEvent.getOrientation(/*pointerIndex=*/0), initial - M_PI_2, EPSILON);
    ASSERT_NEAR(directionalEvent.getOrientation(/*pointerIndex=*/0), initial - M_PI_2, EPSILON);
}

} // namespace android
+3 −1
Original line number Diff line number Diff line
@@ -96,7 +96,9 @@ PublishMotionArgs::PublishMotionArgs(int32_t inAction, nsecs_t inDownTime,
    hmac = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
            16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};

    flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
    flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED |
            AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
            AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION;
    if (action == AMOTION_EVENT_ACTION_CANCEL) {
        flags |= AMOTION_EVENT_FLAG_CANCELED;
    }
Loading