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

Commit 1137b137 authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

Fix IME snapshot missing to remove by 2 consecutive creation calls

There is a timing could happen to create another new IME snapshot
before recents animation finish, so system lost the previous
one's reference and never remove it.

Ensure removing the obsoleted IME snapshot before we create a new one.

Fix: 224664116
Test: atest DisplayContentTests#\
    testShowImeScreenshot_removeCurSnapshotBeforeCreateNext
Change-Id: I3927557453317e9beaab0d5995d6d415d09bb05d
parent 44b2ae63
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4143,6 +4143,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        final SurfaceControl.Transaction t = getPendingTransaction();
        // Prepare IME screenshot for the target if it allows to attach into.
        if (mInputMethodWindow != null && mInputMethodWindow.isVisible()) {
            // Remove the obsoleted IME snapshot first in case the new snapshot happens to
            // override the current one before the transition finish and the surface never be
            // removed on the task.
            removeImeSurfaceImmediately();
            mImeScreenshot = new ImeScreenshot(
                    mWmService.mSurfaceControlFactory.apply(null), mImeLayeringTarget);
            mImeScreenshot.attachAndShow(t);
+26 −0
Original line number Diff line number Diff line
@@ -2023,6 +2023,32 @@ public class DisplayContentTests extends WindowTestsBase {
        verify(mDisplayContent, never()).showImeScreenshot();
    }

    @UseTestDisplay(addWindows = {W_INPUT_METHOD})
    @Test
    public void testShowImeScreenshot_removeCurSnapshotBeforeCreateNext() {
        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");

        mDisplayContent.setImeLayeringTarget(win);
        mDisplayContent.setImeInputTarget(win);
        spyOn(mDisplayContent);
        spyOn(mDisplayContent.mInputMethodWindow);
        doReturn(true).when(mDisplayContent.mInputMethodWindow).isVisible();
        mDisplayContent.getInsetsStateController().getImeSourceProvider().setImeShowing(true);

        // Verify when the timing of 2 showImeScreenshot invocations are very close, will first
        // detach the current snapshot then create the next one.
        mDisplayContent.showImeScreenshot();
        DisplayContent.ImeScreenshot curSnapshot = mDisplayContent.mImeScreenshot;
        spyOn(curSnapshot);
        mDisplayContent.showImeScreenshot();
        verify(curSnapshot).detach(any());
        assertNotNull(mDisplayContent.mImeScreenshot);
        assertNotEquals(curSnapshot, mDisplayContent.mImeScreenshot);
    }

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