Skip to content

Commit 0952c30

Browse files
author
Jeff Brown
committed
Don't serialize motion events.
On reflection, only key events need to be serialized. This is part of a series of changes to improve input system pipelining. Bug: 5963420 Change-Id: I028b4eac97497d012036cb60ffbac4cb22d3966c
1 parent 2d34e0c commit 0952c30

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

services/input/InputDispatcher.cpp

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,8 +1041,7 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
10411041
}
10421042

10431043
// If the currently focused window is still working on previous events then keep waiting.
1044-
if (!isWindowReadyForMoreInputLocked(currentTime,
1045-
mFocusedWindowHandle, true /*focusedEvent*/)) {
1044+
if (!isWindowReadyForMoreInputLocked(currentTime, mFocusedWindowHandle, entry)) {
10461045
#if DEBUG_FOCUS
10471046
ALOGD("Waiting because focused window still processing previous input.");
10481047
#endif
@@ -1405,8 +1404,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
14051404
}
14061405

14071406
// If the touched window is still working on previous events then keep waiting.
1408-
if (!isWindowReadyForMoreInputLocked(currentTime,
1409-
touchedWindow.windowHandle, false /*focusedEvent*/)) {
1407+
if (!isWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry)) {
14101408
#if DEBUG_FOCUS
14111409
ALOGD("Waiting because touched window still processing previous input.");
14121410
#endif
@@ -1618,25 +1616,43 @@ bool InputDispatcher::isWindowObscuredAtPointLocked(
16181616
}
16191617

16201618
bool InputDispatcher::isWindowReadyForMoreInputLocked(nsecs_t currentTime,
1621-
const sp<InputWindowHandle>& windowHandle, bool focusedEvent) {
1619+
const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry) {
16221620
ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
16231621
if (connectionIndex >= 0) {
16241622
sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
16251623
if (connection->inputPublisherBlocked) {
16261624
return false;
16271625
}
1628-
if (focusedEvent) {
1629-
// If the event relies on input focus (such as a key event), then we must
1630-
// wait for all previous events to complete before delivering it because they
1631-
// may move focus elsewhere.
1626+
if (eventEntry->type == EventEntry::TYPE_KEY) {
1627+
// If the event is a key event, then we must wait for all previous events to
1628+
// complete before delivering it because previous events may have the
1629+
// side-effect of transferring focus to a different window and we want to
1630+
// ensure that the following keys are sent to the new window.
1631+
//
1632+
// Suppose the user touches a button in a window then immediately presses "A".
1633+
// If the button causes a pop-up window to appear then we want to ensure that
1634+
// the "A" key is delivered to the new pop-up window. This is because users
1635+
// often anticipate pending UI changes when typing on a keyboard.
1636+
// To obtain this behavior, we must serialize key events with respect to all
1637+
// prior input events.
16321638
return connection->outboundQueue.isEmpty()
16331639
&& connection->waitQueue.isEmpty();
16341640
}
1635-
// Touch events can always be sent to a window because the user intended to touch
1636-
// whatever was visible immediately. Even if focus changes or a new window appears,
1637-
// the touch event was meant for whatever happened to be on screen at the time.
1638-
// However, if the wait queue is piling up with lots of events, then hold up
1639-
// new events for awhile. This condition ensures that ANRs still work.
1641+
// Touch events can always be sent to a window immediately because the user intended
1642+
// to touch whatever was visible at the time. Even if focus changes or a new
1643+
// window appears moments later, the touch event was meant to be delivered to
1644+
// whatever window happened to be on screen at the time.
1645+
//
1646+
// Generic motion events, such as trackball or joystick events are a little trickier.
1647+
// Like key events, generic motion events are delivered to the focused window.
1648+
// Unlike key events, generic motion events don't tend to transfer focus to other
1649+
// windows and it is not important for them to be serialized. So we prefer to deliver
1650+
// generic motion events as soon as possible to improve efficiency and reduce lag
1651+
// through batching.
1652+
//
1653+
// The one case where we pause input event delivery is when the wait queue is piling
1654+
// up with lots of events because the application is not responding.
1655+
// This condition ensures that ANRs are detected reliably.
16401656
if (!connection->waitQueue.isEmpty()
16411657
&& currentTime >= connection->waitQueue.head->eventEntry->eventTime
16421658
+ STREAM_AHEAD_EVENT_TIMEOUT) {

services/input/InputDispatcher.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,7 @@ class InputDispatcher : public InputDispatcherInterface {
995995
bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
996996
int32_t x, int32_t y) const;
997997
bool isWindowReadyForMoreInputLocked(nsecs_t currentTime,
998-
const sp<InputWindowHandle>& windowHandle, bool focusedEvent);
998+
const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry);
999999
String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
10001000
const sp<InputWindowHandle>& windowHandle);
10011001

0 commit comments

Comments
 (0)