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

Commit 12008465 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Fix IME flickering when playing Keyguard launching remote animation"...

Merge "Fix IME flickering when playing Keyguard launching remote animation" into sc-v2-dev am: 9ad299f2

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

Change-Id: Iff7cdd9923329ac4599f3f711833a11238f50934
parents dedbb668 9ad299f2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4140,6 +4140,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                target.mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
            }
            setImeInputTarget(target);
            mInsetsStateController.updateAboveInsetsState(mInputMethodWindow, mInsetsStateController
                    .getRawInsetsState().getSourceOrDefaultVisibility(ITYPE_IME));
            updateImeControlTarget();
        }
    }
+19 −12
Original line number Diff line number Diff line
@@ -4967,21 +4967,28 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

    private boolean applyImeWindowsIfNeeded(ToBooleanFunction<WindowState> callback,
            boolean traverseTopToBottom) {
        // If this window is the current IME target, so we need to process the IME windows
        // directly above it. The exception is if we are in split screen
        // in which case we process the IME at the DisplayContent level to
        // ensure it is above the docked divider.
        // (i.e. Like {@link DisplayContent.ImeContainer#skipImeWindowsDuringTraversal}, the IME
        // window will be ignored to traverse when the IME target is still in split-screen mode).
        if (isImeLayeringTarget()
                && (!mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()
                         || getTask() == null)) {
            if (mDisplayContent.forAllImeWindows(callback, traverseTopToBottom)) {
                return true;
        // No need to apply to IME window if the window is not the current IME layering target.
        if (!isImeLayeringTarget()) {
            return false;
        }
        // If we are in split screen which case we process the IME at the DisplayContent level to
        // ensure it is above the docked divider.
        // i.e. Like {@link DisplayContent.ImeContainer#skipImeWindowsDuringTraversal}, the IME
        // window will be ignored to traverse when the IME target is still in split-screen mode.
        if (mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()
                && getTask() != null) {
            return false;
        }
        // Note that we don't process IME window if the IME input target is not on the screen.
        // In case some unexpected IME visibility cases happen like starting the remote
        // animation on the keyguard but seeing the IME window that originally on the app
        // which behinds the keyguard.
        final WindowState imeInputTarget = getImeInputTarget();
        if (imeInputTarget != null && !(imeInputTarget.isDrawn() || imeInputTarget.isVisible())) {
            return false;
        }
        return mDisplayContent.forAllImeWindows(callback, traverseTopToBottom);
    }

    private boolean applyInOrderWithImeWindows(ToBooleanFunction<WindowState> callback,
            boolean traverseTopToBottom) {
+47 −0
Original line number Diff line number Diff line
@@ -36,12 +36,14 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.fail;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -699,6 +701,51 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
        }
    }

    @UseTestDisplay(addWindows = W_INPUT_METHOD)
    @Test
    public void testLaunchRemoteAnimationWithoutImeBehind() {
        final WindowState win1 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin1");
        final WindowState win2 = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin2");

        // Simulating win1 has shown IME and being IME layering/input target
        mDisplayContent.setImeLayeringTarget(win1);
        mDisplayContent.setImeInputTarget(win1);
        mImeWindow.mWinAnimator.mSurfaceController = mock(WindowSurfaceController.class);
        mImeWindow.mWinAnimator.hide(mDisplayContent.getPendingTransaction(), "test");
        spyOn(mDisplayContent);
        doReturn(true).when(mImeWindow.mWinAnimator.mSurfaceController).hasSurface();
        doReturn(true).when(mImeWindow.mWinAnimator.mSurfaceController)
                .prepareToShowInTransaction(any(), anyFloat());
        makeWindowVisibleAndDrawn(mImeWindow);
        assertTrue(mImeWindow.isOnScreen());
        assertFalse(mImeWindow.isParentWindowHidden());

        try {
            // Simulating now win1 is being covered by the lockscreen which has no surface,
            // and then launching an activity win2 with the remote animation
            win1.mHasSurface = false;
            mDisplayContent.mOpeningApps.add(win2.mActivityRecord);
            final AnimationAdapter adapter = mController.createRemoteAnimationRecord(
                    win2.mActivityRecord, new Point(50, 100), null,
                    new Rect(50, 100, 150, 150), null).mAdapter;
            adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION,
                    mFinishedCallback);

            mDisplayContent.applySurfaceChangesTransaction();
            mController.goodToGo(TRANSIT_OLD_TASK_OPEN);
            mWm.mAnimator.executeAfterPrepareSurfacesRunnables();

            verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_OPEN),
                    any(), any(), any(), any());
            // Verify the IME window won't apply surface change transaction with forAllImeWindows
            verify(mDisplayContent, never()).forAllImeWindows(any(), eq(true));
        } catch (Exception e) {
            // no-op
        } finally {
            mDisplayContent.mOpeningApps.clear();
        }
    }

    private AnimationAdapter setupForNonAppTargetNavBar(int transit, boolean shouldAttachNavBar) {
        final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
        mDisplayContent.mOpeningApps.add(win.mActivityRecord);