summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2025-01-08 02:21:29 -0800
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2025-01-08 02:21:29 -0800
commit2439c80b710c955d9dba11c361b1c4049addd24d (patch)
tree79ff405a344baf48dc01a62d1762396aae69ec39
parent03c58c3e5479272fd53af52b9cdcf836f295940b (diff)
parent902c67a18017f9cf533a4f7d666598e1b44f3690 (diff)
Merge "Still send motion events to window which already be touched" into main am: 902c67a180
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/3431763 Change-Id: Ib7787bd849eea4e9e5a3b405ed33472b98f939c1 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp13
-rw-r--r--services/inputflinger/tests/InputDispatcher_test.cpp54
2 files changed, 67 insertions, 0 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 5db21fdfa5..56ab0dc6ec 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4899,6 +4899,19 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev
}
}
+ if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
+ // Set the flag anyway if we already have an ongoing motion gesture. That
+ // would allow us to complete the processing of the current stroke.
+ const auto touchStateIt = mTouchStatesByDisplay.find(displayId);
+ if (touchStateIt != mTouchStatesByDisplay.end()) {
+ const TouchState& touchState = touchStateIt->second;
+ if (touchState.hasTouchingPointers(resolvedDeviceId) ||
+ touchState.hasHoveringPointers(resolvedDeviceId)) {
+ policyFlags |= POLICY_FLAG_PASS_TO_USER;
+ }
+ }
+ }
+
const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
const size_t pointerCount = motionEvent.getPointerCount();
const std::vector<PointerProperties>
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 7b5c47b1ac..41131fc49b 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -1571,6 +1571,60 @@ TEST_F(InputDispatcherTest, HoverEventInconsistentPolicy) {
window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
}
+// Still send inject motion events to window which already be touched.
+TEST_F(InputDispatcherTest, AlwaysDispatchInjectMotionEventWhenAlreadyDownForWindow) {
+ std::shared_ptr<FakeApplicationHandle> application1 = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> window1 =
+ sp<FakeWindowHandle>::make(application1, mDispatcher, "window1",
+ ui::LogicalDisplayId::DEFAULT);
+ window1->setFrame(Rect(0, 0, 100, 100));
+ window1->setWatchOutsideTouch(false);
+
+ std::shared_ptr<FakeApplicationHandle> application2 = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> window2 =
+ sp<FakeWindowHandle>::make(application2, mDispatcher, "window2",
+ ui::LogicalDisplayId::DEFAULT);
+ window2->setFrame(Rect(50, 50, 100, 100));
+ window2->setWatchOutsideTouch(true);
+ mDispatcher->onWindowInfosChanged({{*window2->getInfo(), *window1->getInfo()}, {}, 0, 0});
+
+ std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT;
+ InputEventInjectionSync injectionMode = InputEventInjectionSync::WAIT_FOR_RESULT;
+ std::optional<gui::Uid> targetUid = {};
+ uint32_t policyFlags = DEFAULT_POLICY_FLAGS;
+
+ const MotionEvent eventDown1 = MotionEventBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1)
+ .build();
+ injectMotionEvent(*mDispatcher, eventDown1, injectionTimeout, injectionMode, targetUid,
+ policyFlags);
+ window2->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
+
+ const MotionEvent eventUp1 = MotionEventBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1)
+ .downTime(eventDown1.getDownTime()).build();
+ // Inject UP event, without the POLICY_FLAG_PASS_TO_USER (to simulate policy behaviour
+ // when screen is off).
+ injectMotionEvent(*mDispatcher, eventUp1, injectionTimeout, injectionMode, targetUid,
+ /*policyFlags=*/0);
+ window2->consumeMotionEvent(WithMotionAction(ACTION_UP));
+ const MotionEvent eventDown2 = MotionEventBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(40).y(40)).deviceId(-1)
+ .build();
+ injectMotionEvent(*mDispatcher, eventDown2, injectionTimeout, injectionMode, targetUid,
+ policyFlags);
+ window1->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
+ window2->consumeMotionEvent(WithMotionAction(ACTION_OUTSIDE));
+
+ const MotionEvent eventUp2 = MotionEventBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1)
+ .downTime(eventDown2.getDownTime()).build();
+ injectMotionEvent(*mDispatcher, eventUp2, injectionTimeout, injectionMode, targetUid,
+ /*policyFlags=*/0);
+ window1->consumeMotionEvent(WithMotionAction(ACTION_UP));
+ window2->assertNoEvents();
+}
+
/**
* Two windows: a window on the left and a window on the right.
* Mouse is hovered from the right window into the left window.