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

Commit 3a4fb1c9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Prevent IME from targeting home when closing app is still animating" into pi-dev

parents cbcbf66f 5e004f27
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -800,6 +800,20 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
        }
    }

    /**
     * See {@link DisplayWindowController#deferUpdateImeTarget()}
     */
    public void deferUpdateImeTarget() {
        mWindowContainerController.deferUpdateImeTarget();
    }

    /**
     * See {@link DisplayWindowController#deferUpdateImeTarget()}
     */
    public void continueUpdateImeTarget() {
        mWindowContainerController.continueUpdateImeTarget();
    }

    public void dump(PrintWriter pw, String prefix) {
        pw.println(prefix + "displayId=" + mDisplayId + " stacks=" + mStacks.size());
        final String myPrefix = prefix + " ";
+46 −34
Original line number Diff line number Diff line
@@ -4592,6 +4592,12 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            }
        }

        try {
            // Defer updating the IME target since the new IME target will try to get computed
            // before updating all closing and opening apps, which can cause the ime target to
            // get calculated incorrectly.
            getDisplay().deferUpdateImeTarget();

            // Shift all activities with this task up to the top
            // of the stack, keeping them in the same internal order.
            insertTaskAtTop(tr, null);
@@ -4620,8 +4626,11 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            } else {
                updateTransitLocked(TRANSIT_TASK_TO_FRONT, options);
            }
        // If a new task is moved to the front, then mark the existing top activity as supporting
        // picture-in-picture while paused only if the task would not be considered an oerlay on top
            // If a new task is moved to the front, then mark the existing top activity as
            // supporting

            // picture-in-picture while paused only if the task would not be considered an oerlay
            // on top
            // of the current activity (eg. not fullscreen, or the assistant)
            if (canEnterPipOnTaskSwitch(topActivity, tr, null /* toFrontActivity */,
                    options)) {
@@ -4632,6 +4641,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
            EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);

            mService.mTaskChangeNotificationController.notifyTaskMovedToFront(tr.taskId);
        } finally {
            getDisplay().continueUpdateImeTarget();
        }
    }

    /**
+46 −9
Original line number Diff line number Diff line
@@ -390,6 +390,11 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     */
    int mLayoutSeq = 0;

    /**
     * Specifies the count to determine whether to defer updating the IME target until ready.
     */
    private int mDeferUpdateImeTargetCount;

    /** Temporary float array to retrieve 3x3 matrix values. */
    private final float[] mTmpFloats = new float[9];

@@ -2454,6 +2459,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            return null;
        }

        final WindowState curTarget = mService.mInputMethodTarget;
        if (!canUpdateImeTarget()) {
            if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Defer updating IME target");
            return curTarget;
        }

        // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
        // same display. Or even when the current IME/target are not on the same screen as the next
        // IME/target. For now only look for input windows on the main screen.
@@ -2477,16 +2488,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        if (DEBUG_INPUT_METHOD && updateImeTarget) Slog.v(TAG_WM,
                "Proposed new IME target: " + target);

        // Now, a special case -- if the last target's window is in the process of exiting, and is
        // above the new target, keep on the last target to avoid flicker. Consider for example a
        // Dialog with the IME shown: when the Dialog is dismissed, we want to keep the IME above it
        // until it is completely gone so it doesn't drop behind the dialog or its full-screen
        // scrim.
        final WindowState curTarget = mService.mInputMethodTarget;
        // Now, a special case -- if the last target's window is in the process of exiting, and the
        // new target is home, keep on the last target to avoid flicker. Home is a special case
        // since its above other stacks in the ordering list, but layed out below the others.
        if (curTarget != null && curTarget.isDisplayedLw() && curTarget.isClosing()
                && (target == null
                    || curTarget.mWinAnimator.mAnimLayer > target.mWinAnimator.mAnimLayer)) {
            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "Current target higher, not changing");
                && (target == null || target.isActivityTypeHome())) {
            if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, "New target is home while current target is"
                    + "closing, not changing");
            return curTarget;
        }

@@ -3958,4 +3966,33 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    void assignStackOrdering() {
        mTaskStackContainers.assignStackOrdering(getPendingTransaction());
    }

    /**
     * Increment the deferral count to determine whether to update the IME target.
     */
    void deferUpdateImeTarget() {
        mDeferUpdateImeTargetCount++;
    }

    /**
     * Decrement the deferral count to determine whether to update the IME target. If the count
     * reaches 0, a new ime target will get computed.
     */
    void continueUpdateImeTarget() {
        if (mDeferUpdateImeTargetCount == 0) {
            return;
        }

        mDeferUpdateImeTargetCount--;
        if (mDeferUpdateImeTargetCount == 0) {
            computeImeTarget(true /* updateImeTarget */);
        }
    }

    /**
     * @return Whether a new IME target should be computed.
     */
    private boolean canUpdateImeTarget() {
        return mDeferUpdateImeTargetCount == 0;
    }
}
+25 −0
Original line number Diff line number Diff line
@@ -94,6 +94,31 @@ public class DisplayWindowController
        }
    }

    /**
     * Starts deferring the ability to update the IME target. This is needed when a call will
     * attempt to update the IME target before all information about the Windows have been updated.
     */
    public void deferUpdateImeTarget() {
        synchronized (mWindowMap) {
            final DisplayContent dc = mRoot.getDisplayContent(mDisplayId);
            if (dc != null) {
                dc.deferUpdateImeTarget();
            }
        }
    }

    /**
     * Resumes updating the IME target after deferring. See {@link #deferUpdateImeTarget()}
     */
    public void continueUpdateImeTarget() {
        synchronized (mWindowMap) {
            final DisplayContent dc = mRoot.getDisplayContent(mDisplayId);
            if (dc != null) {
                dc.continueUpdateImeTarget();
            }
        }
    }

    @Override
    public String toString() {
        return "{DisplayWindowController displayId=" + mDisplayId + "}";
+1 −1
Original line number Diff line number Diff line
@@ -2726,7 +2726,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    }

    boolean isClosing() {
        return mAnimatingExit || (mService.mClosingApps.contains(mAppToken));
        return mAnimatingExit || (mAppToken.isAnimating() && mAppToken.hiddenRequested);
    }

    void addWinAnimatorToList(ArrayList<WindowStateAnimator> animators) {