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

Commit 4f1647d0 authored by Louis Chang's avatar Louis Chang
Browse files

Skip handle pointer-down-outside-focus if input target changed

When TalkBack is enabled, the View#performClick is executed earlier
than the pointer-down-outside-focus event is handled. Therefore,
it is possible that the pointer-down-outside-focus is handled after
an Activity is already started, which unexpectedly changes the focus
again.

Bug: 381340445
Test: use Settings when Talkback is on
Flag: EXEMPT bugfix
Change-Id: Ib663e63b3c533b67f3d5a8cf51fe8cc5cb39f8e0
parent 2462b4d1
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -9010,16 +9010,19 @@ public class WindowManagerService extends IWindowManager.Stub

        clearPointerDownOutsideFocusRunnable();

        final InputTarget focusedInputTarget = mFocusedInputTarget;
        if (shouldDelayTouchOutside(t)) {
            mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
            mPointerDownOutsideFocusRunnable =
                    () -> handlePointerDownOutsideFocus(t, focusedInputTarget);
            mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS);
        } else if (!fromHandler) {
            // Still post the runnable to handler thread in case there is already a runnable
            // in execution, but still waiting to hold the wm lock.
            mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
            mPointerDownOutsideFocusRunnable =
                    () -> handlePointerDownOutsideFocus(t, focusedInputTarget);
            mH.post(mPointerDownOutsideFocusRunnable);
        } else {
            handlePointerDownOutsideFocus(t);
            handlePointerDownOutsideFocus(t, focusedInputTarget);
        }
    }

@@ -9051,8 +9054,15 @@ public class WindowManagerService extends IWindowManager.Stub
        return shouldDelayTouchForEmbeddedActivity || shouldDelayTouchForFreeform;
    }

    private void handlePointerDownOutsideFocus(InputTarget t) {
    private void handlePointerDownOutsideFocus(InputTarget t, InputTarget focusedInputTarget) {
        synchronized (mGlobalLock) {
            if (mFocusedInputTarget != focusedInputTarget) {
                // Skip if the mFocusedInputTarget is already changed. This is possible if the
                // pointer-down-outside-focus event is delayed to be handled.
                ProtoLog.i(WM_DEBUG_FOCUS_LIGHT,
                        "Skip onPointerDownOutsideFocusLocked due to input target changed %s", t);
                return;
            }
            if (mPointerDownOutsideFocusRunnable != null
                    && mH.hasCallbacks(mPointerDownOutsideFocusRunnable)) {
                // Skip if there's another pending pointer-down-outside-focus event.