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

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

Merge "Fix flickering when switched to the task without IME shown" into sc-dev am: 7f95e16a

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

Change-Id: I9b60ed3af8007142fe26dd16e72d1870149ad61d
parents ab38de65 7f95e16a
Loading
Loading
Loading
Loading
+36 −10
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_B
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION;

import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.StatusBarManager;
@@ -211,7 +215,7 @@ class InsetsPolicy {
    InsetsState getInsetsForWindow(WindowState target) {
        final InsetsState originalState = mStateController.getInsetsForWindow(target);
        final InsetsState state = adjustVisibilityForTransientTypes(originalState);
        return target.mIsImWindow ? adjustVisibilityForIme(state, state == originalState) : state;
        return adjustVisibilityForIme(target, state, state == originalState);
    }

    /**
@@ -241,17 +245,39 @@ class InsetsPolicy {
        return state;
    }

    // Navigation bar insets is always visible to IME.
    private static InsetsState adjustVisibilityForIme(InsetsState originalState,
    private InsetsState adjustVisibilityForIme(WindowState w, InsetsState originalState,
            boolean copyState) {
        if (w.mIsImWindow) {
            // Navigation bar insets is always visible to IME.
            final InsetsSource originalNavSource = originalState.peekSource(ITYPE_NAVIGATION_BAR);
            if (originalNavSource != null && !originalNavSource.isVisible()) {
            final InsetsState state = copyState ? new InsetsState(originalState) : originalState;
                final InsetsState state = copyState ? new InsetsState(originalState)
                        : originalState;
                final InsetsSource navSource = new InsetsSource(originalNavSource);
                navSource.setVisible(true);
                state.addSource(navSource);
                return state;
            }
        } else if (w.mActivityRecord != null && !w.mActivityRecord.mLastImeShown) {
            // During switching tasks with gestural navigation, if the IME is attached to
            // one app window on that time, even the next app window is behind the IME window,
            // conceptually the window should not receive the IME insets if the next window is
            // not eligible IME requester and ready to show IME on top of it.
            final boolean shouldImeAttachedToApp = mDisplayContent.shouldImeAttachedToApp();
            final InsetsSource originalImeSource = originalState.peekSource(ITYPE_IME);

            if (originalImeSource != null && shouldImeAttachedToApp
                    && (w.isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS)
                            || !w.getRequestedVisibility(ITYPE_IME))) {
                final InsetsState state = copyState ? new InsetsState(originalState)
                        : originalState;

                final InsetsSource imeSource = new InsetsSource(originalImeSource);
                imeSource.setVisible(false);
                state.addSource(imeSource);
                return state;
            }
        }
        return originalState;
    }

+33 −0
Original line number Diff line number Diff line
@@ -53,6 +53,9 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainer.SYNC_STATE_WAITING_FOR_DRAW;

import static com.google.common.truth.Truth.assertThat;
@@ -891,6 +894,36 @@ public class WindowStateTests extends WindowTestsBase {
        assertTrue(mAppWindow.getInsetsState().getSourceOrDefaultVisibility(ITYPE_NAVIGATION_BAR));
    }

    @UseTestDisplay(addWindows = W_INPUT_METHOD)
    @Test
    public void testAdjustImeInsetsVisibilityWhenTaskSwitchIsAnimating() {
        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
        final WindowState app2 = createWindow(null, TYPE_APPLICATION, "app2");
        final InsetsStateController controller = mDisplayContent.getInsetsStateController();
        controller.getImeSourceProvider().setWindow(mImeWindow, null, null);

        // Simulate app requests IME with updating all windows Insets State when IME is above app.
        mDisplayContent.setImeLayeringTarget(app);
        mDisplayContent.setImeInputTarget(app);
        assertTrue(mDisplayContent.shouldImeAttachedToApp());
        controller.getImeSourceProvider().scheduleShowImePostLayout(app);
        controller.getImeSourceProvider().getSource().setVisible(true);
        controller.updateAboveInsetsState(mImeWindow, false);

        // Simulate task switching animation happens when switching app to app2.
        spyOn(app);
        spyOn(app2);
        doReturn(true).when(app).isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS);
        doReturn(true).when(app2).isAnimating(PARENTS | TRANSITION, ANIMATION_TYPE_RECENTS);
        app.mActivityRecord.mLastImeShown = true;

        // Verify the IME insets is visible on app, but not for app2 during task animating.
        InsetsState stateApp = app.getInsetsState();
        InsetsState stateApp2 = app2.getInsetsState();
        assertTrue(stateApp.getSource(ITYPE_IME).isVisible());
        assertFalse(stateApp2.getSource(ITYPE_IME).isVisible());
    }

    @UseTestDisplay(addWindows = { W_ACTIVITY })
    @Test
    public void testUpdateImeControlTargetWhenLeavingMultiWindow() {