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

Commit a55a6493 authored by Chris Li's avatar Chris Li
Browse files

Fix IME layer

Before, when the app is animating, we have the IME window parent to
assign layer based on the order of the window children. However, the IME
surface parent can be different from the window parent. In such case,
the layer can be wrong.

Before ag/12218308, the IME window parent DA contains IME container and
TDA, so the layer it assigned to IME is always 1. Now, IME window parent
has only one child, so the layer it assigned is always 0. It was a false
positive scenario before.

Fix: 173618785
Bug: 156355859
Test: manual: reproduce steps in bug
Test: atest WmTests:ZOrderingTests
Change-Id: I6f5d741acbd298a22dcbf92336b423579fd1678e
parent 649ed103
Loading
Loading
Loading
Loading
+26 −12
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
@@ -73,8 +75,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.window.DisplayAreaOrganizer.FEATURE_ROOT;
@@ -93,7 +93,6 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_C
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
import static com.android.server.wm.DisplayContentProto.IME_POLICY;
import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
import static com.android.server.wm.DisplayContentProto.CURRENT_FOCUS;
import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
@@ -105,6 +104,7 @@ import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
import static com.android.server.wm.DisplayContentProto.ID;
import static com.android.server.wm.DisplayContentProto.IME_INSETS_SOURCE_PROVIDER;
import static com.android.server.wm.DisplayContentProto.IME_POLICY;
import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_CONTROL_TARGET;
import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_INPUT_TARGET;
import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_TARGET;
@@ -559,6 +559,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     */
    InsetsControlTarget mInputMethodControlTarget;

    /** The surface parent of the IME container. */
    private SurfaceControl mInputMethodSurfaceParent;

    /** If true hold off on modifying the animation layer of mInputMethodTarget */
    boolean mInputMethodTargetWaitingAnim;

@@ -3610,7 +3613,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        ProtoLog.i(WM_DEBUG_IME, "setInputMethodTarget %s", target);
        mInputMethodTarget = target;
        mInputMethodTargetWaitingAnim = targetWaitingAnim;
        assignWindowLayers(true /* setLayoutNeeded */);

        // 1. Reparent the IME container window to the target root DA to get the correct bounds and
        // config. (Only happens when the target window is in a different root DA)
        if (target != null) {
            RootDisplayArea targetRoot = target.getRootDisplayArea();
            if (targetRoot != null) {
@@ -3619,7 +3624,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                targetRoot.placeImeContainer(mImeWindowsContainers);
            }
        }
        // 2. Reparent the IME container surface to either the input target app, or the IME window
        // parent.
        updateImeParent();
        // 3. Assign window layers based on the IME surface parent to make sure it is on top of the
        // app.
        assignWindowLayers(true /* setLayoutNeeded */);
        // 4. Update the IME control target to apply any inset change and animation.
        updateImeControlTarget();
    }

@@ -3649,7 +3660,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    void updateImeParent() {
        final SurfaceControl newParent = computeImeParent();
        if (newParent != null) {
        if (newParent != null && newParent != mInputMethodSurfaceParent) {
            mInputMethodSurfaceParent = newParent;
            getPendingTransaction().reparent(mImeWindowsContainers.mSurfaceControl, newParent);
            scheduleAnimation();
        }
@@ -4426,18 +4438,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        //
        // In the case of split-screen windowing mode, we need to elevate the IME above the
        // docked divider while keeping the app itself below the docked divider, so instead
        // we use relative layering of the IME targets child windows, and place the IME in
        // the non-app layer (see {@link AboveAppWindowContainers#assignChildLayers}).
        // we will put the docked divider below the IME. @see #assignRelativeLayerForImeTargetChild
        //
        // In the case the IME target is animating, the animation Z order may be different
        // than the WindowContainer Z order, so it's difficult to be sure we have the correct
        // IME target. In this case we just layer the IME over all transitions by placing it
        // in the above applications layer.
        // IME target. In this case we just layer the IME over its parent surface.
        //
        // In the case where we have no IME target we assign it where its base layer would
        // place it in the AboveAppWindowContainers.
        // In the case where we have no IME target we let its window parent to place it.
        //
        // Keep IME window in mAboveAppWindowsContainers as long as app's starting window
        // 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()) && (
@@ -4448,6 +4457,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                    // 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);
        } else 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.
            mImeWindowsContainers.assignRelativeLayer(t, mInputMethodSurfaceParent, 1);
        }
        super.assignChildLayers(t);
    }