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

Commit 136b1f92 authored by Christopher Tate's avatar Christopher Tate
Browse files

Fix spurious ANRs involving window shuffling and non-fullscreen activities

Force the event-target bookkeeping to reset when an app explicitly
acknowledges event receipt.  Furthermore, notify the event dispatcher
whenever a new window is created, even if there is nominally an
existing event target window.

These changes in tandem address a subtle race bug in which the event
dispatcher believes that there is an event recipient that it is still
waiting for even when the event in question has been acknowledged;
this results in a spurious ANR.  There were checks in the existing code
that wound up doing the right thing in the case of windows becoming
hidden, but the case of non-fullscreen activities floating over them
[unavailable for input but still visible] exposed the race condition.

Bug: 2432828
Change-Id: I29fb741aace34736b029f9ba43f2c43184366258
parent 5a4b1d9e
Loading
Loading
Loading
Loading
+8 −12
Original line number Diff line number Diff line
@@ -5610,7 +5610,7 @@ public class WindowManagerService extends IWindowManager.Stub
                            // If an app switch key has been pressed, and we have
                            // waited too long for the current app to finish
                            // processing keys, then wait no more!
                            doFinishedKeyLocked(true);
                            doFinishedKeyLocked(false);
                            continue;
                        }
                        long switchTimeout = mTimeToSwitch - now;
@@ -6008,7 +6008,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        + ((mLastWin != null) ? mLastWin.mToken.paused : "null"));
                    if (mLastWin != null && (!mLastWin.mToken.paused || force
                            || !mEventDispatching)) {
                        doFinishedKeyLocked(false);
                        doFinishedKeyLocked(true);
                    } else {
                        // Make sure to wake up anyone currently waiting to
                        // dispatch a key, so they can re-evaluate their
@@ -6086,14 +6086,10 @@ public class WindowManagerService extends IWindowManager.Stub
                        // The new window is above the old; finish pending input to the last
                        // window and start directing it to the new one.
                        mLastWin.mToken.paused = false;
                        doFinishedKeyLocked(true);  // does a notifyAll()
                    }
                    // Either the new window is lower, so there is no need to wake key waiters,
                    // or we just finished key input to the previous window, which implicitly
                    // notified the key waiters.  In both cases, we don't need to issue the
                    // notification here.
                        doFinishedKeyLocked(false);  // does a notifyAll()
                        return;
                    }
                }

                // Now that we've put a new window state in place, make the event waiter
                // take notice and retarget its attentions.
@@ -6134,7 +6130,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        + token.paused);
                    token.paused = false;
                    if (mLastWin != null && mLastWin.mToken == token && mFinished) {
                        doFinishedKeyLocked(true);
                        doFinishedKeyLocked(false);
                    } else {
                        notifyAll();
                    }
@@ -6162,13 +6158,13 @@ public class WindowManagerService extends IWindowManager.Stub
            }
        }

        private final void doFinishedKeyLocked(boolean doRecycle) {
        private final void doFinishedKeyLocked(boolean force) {
            if (mLastWin != null) {
                releasePendingPointerLocked(mLastWin.mSession);
                releasePendingTrackballLocked(mLastWin.mSession);
            }

            if (mLastWin == null || !mLastWin.mToken.paused
            if (force || mLastWin == null || !mLastWin.mToken.paused
                    || !mLastWin.isVisibleLw()) {
                // If the current window has been paused, we aren't -really-
                // finished...  so let the waiters still wait.