diff options
author | 2025-01-08 02:57:16 -0800 | |
---|---|---|
committer | 2025-01-08 02:57:16 -0800 | |
commit | d77e9131dbeac269f1f35524c8aceaff2bc4e087 (patch) | |
tree | 598f56424596fb40c8481ff9882fe53fd3927735 | |
parent | dfc9f679f4e2cc358465a35ff6a1a298a9d2571c (diff) | |
parent | 2439c80b710c955d9dba11c361b1c4049addd24d (diff) |
Merge "Still send motion events to window which already be touched" into main am: 902c67a180 am: 2439c80b71
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/3431763
Change-Id: I92f616a262ba81731f4bdc8ca838cd78d97804d3
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 13 | ||||
-rw-r--r-- | services/inputflinger/tests/InputDispatcher_test.cpp | 54 |
2 files changed, 67 insertions, 0 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 15043db7fb..fcd784d38a 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -4878,6 +4878,19 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev return InputEventInjectionResult::FAILED; } + 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 6ec08892c0..685645cfbb 100644 --- a/services/inputflinger/tests/InputDispatcher_test.cpp +++ b/services/inputflinger/tests/InputDispatcher_test.cpp @@ -1570,6 +1570,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. |