Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0952c30a authored by Jeff Brown's avatar Jeff Brown
Browse files

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
parent 2d34e0cf
Loading
Loading
Loading
Loading
+30 −14
Original line number Diff line number Diff line
@@ -1041,8 +1041,7 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
    }

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

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

bool InputDispatcher::isWindowReadyForMoreInputLocked(nsecs_t currentTime,
        const sp<InputWindowHandle>& windowHandle, bool focusedEvent) {
        const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry) {
    ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
    if (connectionIndex >= 0) {
        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
        if (connection->inputPublisherBlocked) {
            return false;
        }
        if (focusedEvent) {
            // If the event relies on input focus (such as a key event), then we must
            // wait for all previous events to complete before delivering it because they
            // may move focus elsewhere.
        if (eventEntry->type == EventEntry::TYPE_KEY) {
            // If the event is a key event, then we must wait for all previous events to
            // complete before delivering it because previous events may have the
            // side-effect of transferring focus to a different window and we want to
            // ensure that the following keys are sent to the new window.
            //
            // Suppose the user touches a button in a window then immediately presses "A".
            // If the button causes a pop-up window to appear then we want to ensure that
            // the "A" key is delivered to the new pop-up window.  This is because users
            // often anticipate pending UI changes when typing on a keyboard.
            // To obtain this behavior, we must serialize key events with respect to all
            // prior input events.
            return connection->outboundQueue.isEmpty()
                    && connection->waitQueue.isEmpty();
        }
        // Touch events can always be sent to a window because the user intended to touch
        // whatever was visible immediately.  Even if focus changes or a new window appears,
        // the touch event was meant for whatever happened to be on screen at the time.
        // However, if the wait queue is piling up with lots of events, then hold up
        // new events for awhile.  This condition ensures that ANRs still work.
        // Touch events can always be sent to a window immediately because the user intended
        // to touch whatever was visible at the time.  Even if focus changes or a new
        // window appears moments later, the touch event was meant to be delivered to
        // whatever window happened to be on screen at the time.
        //
        // Generic motion events, such as trackball or joystick events are a little trickier.
        // Like key events, generic motion events are delivered to the focused window.
        // Unlike key events, generic motion events don't tend to transfer focus to other
        // windows and it is not important for them to be serialized.  So we prefer to deliver
        // generic motion events as soon as possible to improve efficiency and reduce lag
        // through batching.
        //
        // The one case where we pause input event delivery is when the wait queue is piling
        // up with lots of events because the application is not responding.
        // This condition ensures that ANRs are detected reliably.
        if (!connection->waitQueue.isEmpty()
                && currentTime >= connection->waitQueue.head->eventEntry->eventTime
                        + STREAM_AHEAD_EVENT_TIMEOUT) {
+1 −1
Original line number Diff line number Diff line
@@ -995,7 +995,7 @@ private:
    bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
            int32_t x, int32_t y) const;
    bool isWindowReadyForMoreInputLocked(nsecs_t currentTime,
            const sp<InputWindowHandle>& windowHandle, bool focusedEvent);
            const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry);
    String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
            const sp<InputWindowHandle>& windowHandle);