Skip to content

Commit 40ab0ce

Browse files
Bin Zhaimediatek-chuanghuazhao
authored andcommitted
Still send motion events to window which already be touched
Make screen off during injecting swipe events(cmd: adb shell swipe 50 0 50 500 5000) in a window which can watch ouside events. Then UP event can not send to window due to policyFlags is not include POLICY_FLAG_PASS_TO_USER when screen off. InputDispatcher can not clear TouchState. Inputdispatcher will crash when inject down event which outside the window after screen on. So still send motion events to window which already be touched. Bug: 384456309 Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST --gtest_filter="*AlwaysDispatchInjectMotionEventWhenAlreadyDownForWindow" Change-Id: I0d5c3d4f3f26c4a550e37f96bac23c342d4cddcb
1 parent e963fbd commit 40ab0ce

2 files changed

Lines changed: 67 additions & 0 deletions

File tree

services/inputflinger/dispatcher/InputDispatcher.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4899,6 +4899,19 @@ InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* ev
48994899
}
49004900
}
49014901

4902+
if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4903+
// Set the flag anyway if we already have an ongoing motion gesture. That
4904+
// would allow us to complete the processing of the current stroke.
4905+
const auto touchStateIt = mTouchStatesByDisplay.find(displayId);
4906+
if (touchStateIt != mTouchStatesByDisplay.end()) {
4907+
const TouchState& touchState = touchStateIt->second;
4908+
if (touchState.hasTouchingPointers(resolvedDeviceId) ||
4909+
touchState.hasHoveringPointers(resolvedDeviceId)) {
4910+
policyFlags |= POLICY_FLAG_PASS_TO_USER;
4911+
}
4912+
}
4913+
}
4914+
49024915
const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
49034916
const size_t pointerCount = motionEvent.getPointerCount();
49044917
const std::vector<PointerProperties>

services/inputflinger/tests/InputDispatcher_test.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,60 @@ TEST_F(InputDispatcherTest, HoverEventInconsistentPolicy) {
15711571
window->consumeMotionEvent(WithMotionAction(ACTION_HOVER_EXIT));
15721572
}
15731573

1574+
// Still send inject motion events to window which already be touched.
1575+
TEST_F(InputDispatcherTest, AlwaysDispatchInjectMotionEventWhenAlreadyDownForWindow) {
1576+
std::shared_ptr<FakeApplicationHandle> application1 = std::make_shared<FakeApplicationHandle>();
1577+
sp<FakeWindowHandle> window1 =
1578+
sp<FakeWindowHandle>::make(application1, mDispatcher, "window1",
1579+
ui::LogicalDisplayId::DEFAULT);
1580+
window1->setFrame(Rect(0, 0, 100, 100));
1581+
window1->setWatchOutsideTouch(false);
1582+
1583+
std::shared_ptr<FakeApplicationHandle> application2 = std::make_shared<FakeApplicationHandle>();
1584+
sp<FakeWindowHandle> window2 =
1585+
sp<FakeWindowHandle>::make(application2, mDispatcher, "window2",
1586+
ui::LogicalDisplayId::DEFAULT);
1587+
window2->setFrame(Rect(50, 50, 100, 100));
1588+
window2->setWatchOutsideTouch(true);
1589+
mDispatcher->onWindowInfosChanged({{*window2->getInfo(), *window1->getInfo()}, {}, 0, 0});
1590+
1591+
std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT;
1592+
InputEventInjectionSync injectionMode = InputEventInjectionSync::WAIT_FOR_RESULT;
1593+
std::optional<gui::Uid> targetUid = {};
1594+
uint32_t policyFlags = DEFAULT_POLICY_FLAGS;
1595+
1596+
const MotionEvent eventDown1 = MotionEventBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
1597+
.pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1)
1598+
.build();
1599+
injectMotionEvent(*mDispatcher, eventDown1, injectionTimeout, injectionMode, targetUid,
1600+
policyFlags);
1601+
window2->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
1602+
1603+
const MotionEvent eventUp1 = MotionEventBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
1604+
.pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1)
1605+
.downTime(eventDown1.getDownTime()).build();
1606+
// Inject UP event, without the POLICY_FLAG_PASS_TO_USER (to simulate policy behaviour
1607+
// when screen is off).
1608+
injectMotionEvent(*mDispatcher, eventUp1, injectionTimeout, injectionMode, targetUid,
1609+
/*policyFlags=*/0);
1610+
window2->consumeMotionEvent(WithMotionAction(ACTION_UP));
1611+
const MotionEvent eventDown2 = MotionEventBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
1612+
.pointer(PointerBuilder(0, ToolType::FINGER).x(40).y(40)).deviceId(-1)
1613+
.build();
1614+
injectMotionEvent(*mDispatcher, eventDown2, injectionTimeout, injectionMode, targetUid,
1615+
policyFlags);
1616+
window1->consumeMotionEvent(WithMotionAction(ACTION_DOWN));
1617+
window2->consumeMotionEvent(WithMotionAction(ACTION_OUTSIDE));
1618+
1619+
const MotionEvent eventUp2 = MotionEventBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
1620+
.pointer(PointerBuilder(0, ToolType::FINGER).x(60).y(60)).deviceId(-1)
1621+
.downTime(eventDown2.getDownTime()).build();
1622+
injectMotionEvent(*mDispatcher, eventUp2, injectionTimeout, injectionMode, targetUid,
1623+
/*policyFlags=*/0);
1624+
window1->consumeMotionEvent(WithMotionAction(ACTION_UP));
1625+
window2->assertNoEvents();
1626+
}
1627+
15741628
/**
15751629
* Two windows: a window on the left and a window on the right.
15761630
* Mouse is hovered from the right window into the left window.

0 commit comments

Comments
 (0)