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

Commit 40c599f4 authored by Ming-Shin Lu's avatar Ming-Shin Lu
Browse files

Consolidate DisplayContent#assignRelativeLayerForIme

When the window focus or the ime target changes,
DC#assignRelativeLayerForIme will be called to set the
relative layering with IME when the imeTarget is the
non-child application window without in animating state.

Howerver, the animating state checking includes all types
of animation. And that makes when taping an
editor dialog fragment to show IME, then swiping up to
recents will see the IME will behind the dimming because
system thought the ime target is animated by recents animation
so the relative layering didn't be set.

As task switching by recents animation that we would like to keep
the current task window hierarchy and IME relative layer during
switching, modify the animating check with excluding recents
animation.

Bug: 201139555
Test: atest ZOrderingTests#\
       testAssignWindowLayers_ForImeOnAppWithRecentsAnimating
Test: manual as steps:
  1) Launch Settings with editor dialogs fragment
    (E.g. Network & Internet > Private DNS)
  2) Tap focus on Editor to show IME
  3) Tap and hold on navigation bar
  4) Expect IME layer isn't below dimming layer

Change-Id: I3024443c21cfb1c7971f3999640039caea10d0d5
parent 239b6b7f
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -117,6 +117,7 @@ import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA;
import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
@@ -4935,15 +4936,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        // Keep IME window in surface parent as long as app's starting window
        // exists so it get's layered above the starting window.
        if (imeTarget != null && !(imeTarget.mActivityRecord != null
                && imeTarget.mActivityRecord.hasStartingWindow()) && (
                !(imeTarget.inMultiWindowMode()
                        || imeTarget.mToken.isAppTransitioning()) && (
                        imeTarget.getSurfaceControl() != null))) {
                && imeTarget.mActivityRecord.hasStartingWindow())) {
            final boolean canImeTargetSetRelativeLayer = imeTarget.getSurfaceControl() != null
                    && !imeTarget.inMultiWindowMode()
                    && imeTarget.mToken.getActivity(app -> app.isAnimating(TRANSITION | PARENTS,
                            ANIMATION_TYPE_ALL & ~ANIMATION_TYPE_RECENTS)) == null;
            if (canImeTargetSetRelativeLayer) {
                mImeWindowsContainer.assignRelativeLayer(t, imeTarget.getSurfaceControl(),
                        // TODO: We need to use an extra level on the app surface to ensure
                        // this is always above SurfaceView but always below attached window.
                        1, forceUpdate);
        } else if (mInputMethodSurfaceParent != null) {
                return;
            }
        }
        if (mInputMethodSurfaceParent != null) {
            // The IME surface parent may not be its window parent's surface
            // (@see #computeImeParent), so set relative layer here instead of letting the window
            // parent to assign layer.
+27 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
@@ -39,10 +40,12 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
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.SurfaceAnimator.ANIMATION_TYPE_RECENTS;
import static com.android.server.wm.WindowStateAnimator.PRESERVED_SURFACE_LAYER;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@@ -400,6 +403,30 @@ public class ZOrderingTests extends WindowTestsBase {
        assertWindowHigher(statusBarSubPanel, statusBarPanel);
    }

    @Test
    public void testAssignWindowLayers_ForImeOnAppWithRecentsAnimating() {
        final WindowState imeAppTarget = createWindow(null, TYPE_APPLICATION,
                mAppWindow.mActivityRecord, "imeAppTarget");
        mDisplayContent.setImeInputTarget(imeAppTarget);
        mDisplayContent.setImeLayeringTarget(imeAppTarget);
        mDisplayContent.updateImeParent();

        // Simulate the ime layering target task is animating with recents animation.
        final Task imeAppTargetTask = imeAppTarget.getTask();
        final SurfaceAnimator imeTargetTaskAnimator = imeAppTargetTask.mSurfaceAnimator;
        spyOn(imeTargetTaskAnimator);
        doReturn(ANIMATION_TYPE_RECENTS).when(imeTargetTaskAnimator).getAnimationType();
        doReturn(true).when(imeTargetTaskAnimator).isAnimating();

        mDisplayContent.assignChildLayers(mTransaction);

        // Ime should on top of the application window when in recents animation and keep
        // attached on app.
        assertTrue(mDisplayContent.shouldImeAttachedToApp());
        assertWindowHigher(mImeWindow, imeAppTarget);
    }


    @Test
    public void testAssignWindowLayers_ForNegativelyZOrderedSubtype() {
        // TODO(b/70040778): We should aim to eliminate the last user of TYPE_APPLICATION_MEDIA