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

Commit f4a80b81 authored by yunho.shin's avatar yunho.shin Committed by chaviw
Browse files

Use identity transform for Joystick MotionEvent

The SyntheticJoystickHandler makes key events
according to the axis values of MotionEvent.

If there is a Window which has transformed,
the axis values are going to be bigger or smaller than
SyntheticJoystickHandler's threshold and the generating
events never stop because JoystickHandler thinks that
the user is controlling Joystick continuously.

This makes Joystick's MotionEvent has identity transform
so that its aix values are not depending on the window but
display.

Test: atest inputflinger_tests:InputDispatcherTest\
        #NonPointerMotionEvent_JoystickNotTransformed
Bug: 158802274
Change-Id: Ib1c12c773a604c74807033819b8d1e1032913c98
parent da207843
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -321,6 +321,17 @@ static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
                                                          std::shared_ptr<EventEntry> eventEntry,
                                                          int32_t inputTargetFlags) {
    if (eventEntry->type == EventEntry::Type::MOTION) {
        const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
        if (motionEntry.source & AINPUT_SOURCE_CLASS_JOYSTICK) {
            const ui::Transform identityTransform;
            // Use identity transform for joystick events events because they don't depend on
            // the window info
            return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, identityTransform,
                                                   1.0f /*globalScaleFactor*/);
        }
    }

    if (inputTarget.useDefaultPointerTransform()) {
        const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
        return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
+46 −0
Original line number Diff line number Diff line
@@ -862,6 +862,8 @@ public:

    void setWindowScale(float xScale, float yScale) { setWindowTransform(xScale, 0, 0, yScale); }

    void setWindowOffset(float offsetX, float offsetY) { mInfo.transform.set(offsetX, offsetY); }

    void consumeKeyDown(int32_t expectedDisplayId, int32_t expectedFlags = 0) {
        consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_DOWN, expectedDisplayId,
                     expectedFlags);
@@ -2051,6 +2053,50 @@ TEST_F(InputDispatcherTest, VerifyInputEvent_MotionEvent) {
    EXPECT_EQ(motionArgs.buttonState, verifiedMotion.buttonState);
}

TEST_F(InputDispatcherTest, NonPointerMotionEvent_JoystickNotTransformed) {
    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
    sp<FakeWindowHandle> window =
            new FakeWindowHandle(application, mDispatcher, "Test window", ADISPLAY_ID_DEFAULT);
    const std::string name = window->getName();

    // Window gets transformed by offset values.
    window->setWindowOffset(500.0f, 500.0f);

    mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
    window->setFocusable(true);

    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});

    // First, we set focused window so that focusedWindowHandle is not null.
    setFocusedWindow(window);

    // Second, we consume focus event if it is right or wrong according to onFocusChangedLocked.
    window->consumeFocusEvent(true);

    NotifyMotionArgs motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_MOVE,
                                                     AINPUT_SOURCE_JOYSTICK, ADISPLAY_ID_DEFAULT);
    mDispatcher->notifyMotion(&motionArgs);

    // Third, we consume motion event.
    InputEvent* event = window->consume();
    ASSERT_NE(event, nullptr);
    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
            << name.c_str() << "expected " << inputEventTypeToString(AINPUT_EVENT_TYPE_MOTION)
            << " event, got " << inputEventTypeToString(event->getType()) << " event";

    const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
    EXPECT_EQ(AINPUT_EVENT_TYPE_MOTION, motionEvent.getAction());

    float expectedX = motionArgs.pointerCoords[0].getX();
    float expectedY = motionArgs.pointerCoords[0].getY();

    // Finally we test if the axis values from the final motion event are not transformed
    EXPECT_EQ(expectedX, motionEvent.getX(0)) << "expected " << expectedX << " for x coord of "
                                              << name.c_str() << ", got " << motionEvent.getX(0);
    EXPECT_EQ(expectedY, motionEvent.getY(0)) << "expected " << expectedY << " for y coord of "
                                              << name.c_str() << ", got " << motionEvent.getY(0);
}

/**
 * Ensure that separate calls to sign the same data are generating the same key.
 * We avoid asserting against INVALID_HMAC. Since the key is random, there is a non-zero chance