summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Arthur Hung <arthurhung@google.com> 2022-11-15 03:30:48 +0000
committer Arthur Hung <arthurhung@google.com> 2022-11-17 02:45:00 +0000
commit96483740e8dae87400b3a28e073217403363aec0 (patch)
treed0c5dc9024a8f45c9b9d30d18db75092c8c4bc86
parent29bbbc408d35929203999ee431aeed48faaf0d12 (diff)
Fix ACTION_POINTER_DOWN reports wrong pointers
This fix the second pointer will use the identity transform because the returned touched windows should be refreshed after updating the new pointerIds to the temporary touch state. Bug: 258382964 Test: atest inputflinger_tests Change-Id: I96a738dcb01bf1c9e2792d3fee547c147dba33b5
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp25
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp37
2 files changed, 51 insertions, 11 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 7b7c42a211..ac08acc5c8 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2306,6 +2306,20 @@ std::vector<TouchedWindow> InputDispatcher::findTouchedWindowTargetsLocked(
entry.eventTime);
}
}
+
+ // Update the pointerIds for non-splittable when it received pointer down.
+ if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
+ // If no split, we suppose all touched windows should receive pointer down.
+ const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
+ for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
+ TouchedWindow& touchedWindow = tempTouchState.windows[i];
+ // Ignore drag window for it should just track one pointer.
+ if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
+ continue;
+ }
+ touchedWindow.pointerIds.markBit(entry.pointerProperties[pointerIndex].id);
+ }
+ }
}
// Update dispatching for hover enter and exit.
@@ -2480,17 +2494,6 @@ Failed:
}
i += 1;
}
- } else if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
- // If no split, we suppose all touched windows should receive pointer down.
- const int32_t pointerIndex = getMotionEventActionPointerIndex(action);
- for (size_t i = 0; i < tempTouchState.windows.size(); i++) {
- TouchedWindow& touchedWindow = tempTouchState.windows[i];
- // Ignore drag window for it should just track one pointer.
- if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
- continue;
- }
- touchedWindow.pointerIds.markBit(entry.pointerProperties[pointerIndex].id);
- }
}
// Save changes unless the action was scroll in which case the temporary touch
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index aaf50ce5ed..daa3afa708 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2400,6 +2400,43 @@ TEST_F(InputDispatcherTest, OnWindowInfosChanged_RemoveAllWindowsOnDisplay) {
window->assertNoEvents();
}
+TEST_F(InputDispatcherTest, NonSplitTouchableWindowReceivesMultiTouch) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher,
+ "Fake Window", ADISPLAY_ID_DEFAULT);
+ // Ensure window is non-split and have some transform.
+ window->setPreventSplitting(true);
+ window->setWindowOffset(20, 40);
+ mDispatcher->onWindowInfosChanged({*window->getInfo()}, {});
+
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
+ {50, 50}))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+ window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
+
+ const MotionEvent secondFingerDownEvent =
+ MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .displayId(ADISPLAY_ID_DEFAULT)
+ .eventTime(systemTime(SYSTEM_TIME_MONOTONIC))
+ .pointer(PointerBuilder(/* id */ 0, AMOTION_EVENT_TOOL_TYPE_FINGER).x(50).y(50))
+ .pointer(PointerBuilder(/* id */ 1, AMOTION_EVENT_TOOL_TYPE_FINGER)
+ .x(-30)
+ .y(-50))
+ .build();
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(mDispatcher, secondFingerDownEvent, INJECT_EVENT_TIMEOUT,
+ InputEventInjectionSync::WAIT_FOR_RESULT))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
+
+ const MotionEvent* event = window->consumeMotion();
+ EXPECT_EQ(POINTER_1_DOWN, event->getAction());
+ EXPECT_EQ(70, event->getX(0)); // 50 + 20
+ EXPECT_EQ(90, event->getY(0)); // 50 + 40
+ EXPECT_EQ(-10, event->getX(1)); // -30 + 20
+ EXPECT_EQ(-10, event->getY(1)); // -50 + 40
+}
+
/**
* Ensure the correct coordinate spaces are used by InputDispatcher.
*