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

Commit 4053c927 authored by Ming-Shin Lu's avatar Ming-Shin Lu Committed by Automerger Merge Worker
Browse files

Merge "Fix IME snapshot missing to remove by defered IME target computation"...

Merge "Fix IME snapshot missing to remove by defered IME target computation" into tm-qpr-dev am: 7fdf1045

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19320254



Change-Id: Iebb5d674fc4cfa616acdeaef8089d9d9ae08aaab
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents da7e649e 7fdf1045
Loading
Loading
Loading
Loading
+29 −12
Original line number Diff line number Diff line
@@ -4252,6 +4252,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        void detach(Transaction t) {
            removeImeSurface(t);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(64);
            sb.append("ImeScreenshot{");
            sb.append(Integer.toHexString(System.identityHashCode(this)));
            sb.append(" imeTarget=" + mImeTarget);
            sb.append(" surface=" + mImeSurface);
            sb.append('}');
            return sb.toString();
        }
    }

    private void attachAndShowImeScreenshotOnTarget() {
@@ -4284,15 +4295,23 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    /**
     * Removes the IME screenshot when necessary.
     *
     * Used when app transition animation finished or obsoleted screenshot surface like size
     * changed by rotation.
     * Removes the IME screenshot when the caller is a part of the attached target window.
     */
    void removeImeScreenshotIfPossible() {
        if (mImeLayeringTarget == null
                || mImeLayeringTarget.mAttrs.type != TYPE_APPLICATION_STARTING
                && !mImeLayeringTarget.inTransitionSelfOrParent()) {
    void removeImeSurfaceByTarget(WindowContainer win) {
        if (mImeScreenshot == null || win == null) {
            return;
        }
        // The starting window shouldn't be the input target to attach the IME screenshot during
        // transitioning.
        if (win.asWindowState() != null
                && win.asWindowState().mAttrs.type == TYPE_APPLICATION_STARTING) {
            return;
        }

        final WindowState screenshotTarget = mImeScreenshot.getImeTarget();
        final boolean winIsOrContainsScreenshotTarget = (win == screenshotTarget
                || win.getWindow(w -> w == screenshotTarget) != null);
        if (winIsOrContainsScreenshotTarget) {
            removeImeSurfaceImmediately();
        }
    }
@@ -4640,10 +4659,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                    wc, SurfaceAnimator.animationTypeToString(type), mImeScreenshot,
                    mImeScreenshot.getImeTarget());
        }
        if (mImeScreenshot != null && (wc == mImeScreenshot.getImeTarget()
                || wc.getWindow(w -> w == mImeScreenshot.getImeTarget()) != null)
                && (type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
            removeImeSurfaceImmediately();
        if ((type & WindowState.EXIT_ANIMATING_TYPES) != 0) {
            removeImeSurfaceByTarget(wc);
        }
    }

+3 −2
Original line number Diff line number Diff line
@@ -2449,8 +2449,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

        final DisplayContent dc = getDisplayContent();
        if (isImeLayeringTarget()) {
            // Remove the IME screenshot surface if the layering target is not animating.
            dc.removeImeScreenshotIfPossible();
            // Remove the attached IME screenshot surface.
            dc.removeImeSurfaceByTarget(this);
            // Make sure to set mImeLayeringTarget as null when the removed window is the
            // IME target, in case computeImeTarget may use the outdated target.
            dc.setImeLayeringTarget(null);
@@ -3584,6 +3584,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        } else {
            logExclusionRestrictions(EXCLUSION_LEFT);
            logExclusionRestrictions(EXCLUSION_RIGHT);
            getDisplayContent().removeImeSurfaceByTarget(this);
        }
        // Exclude toast because legacy apps may show toast window by themselves, so the misused
        // apps won't always be considered as foreground state.
+46 −0
Original line number Diff line number Diff line
@@ -2207,6 +2207,52 @@ public class DisplayContentTests extends WindowTestsBase {
        assertNotEquals(curSnapshot, mDisplayContent.mImeScreenshot);
    }

    @UseTestDisplay(addWindows = {W_INPUT_METHOD})
    @Test
    public void testRemoveImeScreenshot_whenTargetSurfaceWasInvisible() {
        final Task rootTask = createTask(mDisplayContent);
        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
        win.onSurfaceShownChanged(true);
        makeWindowVisible(win, mDisplayContent.mInputMethodWindow);
        task.getDisplayContent().prepareAppTransition(TRANSIT_CLOSE);
        doReturn(true).when(task).okToAnimate();
        ArrayList<WindowContainer> sources = new ArrayList<>();
        sources.add(activity);

        mDisplayContent.setImeLayeringTarget(win);
        mDisplayContent.setImeInputTarget(win);
        mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);
        task.applyAnimation(null, TRANSIT_OLD_TASK_CLOSE, false /* enter */,
                false /* isVoiceInteraction */, sources);
        assertNotNull(mDisplayContent.mImeScreenshot);

        win.onSurfaceShownChanged(false);
        assertNull(mDisplayContent.mImeScreenshot);
    }

    @UseTestDisplay(addWindows = {W_INPUT_METHOD})
    @Test
    public void testRemoveImeScreenshot_whenWindowRemoveImmediately() {
        final Task rootTask = createTask(mDisplayContent);
        final Task task = createTaskInRootTask(rootTask, 0 /* userId */);
        final ActivityRecord activity = createActivityRecord(mDisplayContent, task);
        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, activity, "win");
        makeWindowVisible(mDisplayContent.mInputMethodWindow);

        mDisplayContent.setImeLayeringTarget(win);
        mDisplayContent.setImeInputTarget(win);
        mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);
        mDisplayContent.showImeScreenshot();
        assertNotNull(mDisplayContent.mImeScreenshot);

        // Expect IME snapshot will be removed when the win is IME layering target and invoked
        // removeImeSurfaceByTarget.
        win.removeImmediately();
        assertNull(mDisplayContent.mImeScreenshot);
    }

    @Test
    public void testRotateBounds_keepSamePhysicalPosition() {
        final DisplayContent dc =