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

Commit 0730df73 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allow some app windows to display above the IME."

parents 0221d16c ca9e0612
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -141,8 +141,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * Utility class for keeping track of the WindowStates and other pertinent contents of a
@@ -2546,7 +2544,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
            if (!obscured) {
                final boolean isDisplayed = w.isDisplayedLw();

                if (isDisplayed && w.isObscuringFullscreen(mDisplayInfo)) {
                if (isDisplayed && w.isObscuringDisplay()) {
                    // This window completely covers everything behind it, so we want to leave all
                    // of them as undimmed (for performance reasons).
                    root.mObscuringWindow = w;
@@ -2945,7 +2943,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                    screenshotReady = true;
                }

                if (ws.isObscuringFullscreen(mDisplayInfo)){
                if (ws.isObscuringDisplay()){
                    break;
                }
            }
+24 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ class WindowLayersController {
    private boolean mAnyLayerChanged;
    private int mHighestLayerInImeTargetBaseLayer;
    private WindowState mImeTarget;
    private boolean mAboveImeTarget;
    private ArrayDeque<WindowState> mAboveImeTargetAppWindows = new ArrayDeque();

    final void assignWindowLayers(DisplayContent dc) {
        if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based",
@@ -143,6 +145,8 @@ class WindowLayersController {

        mImeTarget = mService.mInputMethodTarget;
        mHighestLayerInImeTargetBaseLayer = (mImeTarget != null) ? mImeTarget.mBaseLayer : 0;
        mAboveImeTarget = false;
        mAboveImeTargetAppWindows.clear();
    }

    private void collectSpecialWindows(WindowState w) {
@@ -157,6 +161,20 @@ class WindowLayersController {
            mInputMethodWindows.add(w);
            return;
        }
        if (mImeTarget != null) {
            if (w.getParentWindow() == mImeTarget && w.mSubLayer > 0) {
                // Child windows of the ime target with a positive sub-layer should be placed above
                // the IME.
                mAboveImeTargetAppWindows.add(w);
            } else if (mAboveImeTarget && w.mAppToken != null) {
                // windows of apps above the IME target should be placed above the IME.
                mAboveImeTargetAppWindows.add(w);
            }
            if (w == mImeTarget) {
                mAboveImeTarget = true;
            }
        }

        final Task task = w.getTask();
        if (task == null) {
            return;
@@ -211,6 +229,12 @@ class WindowLayersController {
            while (!mInputMethodWindows.isEmpty()) {
                layer = assignAndIncreaseLayerIfNeeded(mInputMethodWindows.remove(), layer);
            }

            // Adjust app windows the should be displayed above the IME since they are above the IME
            // target.
            while (!mAboveImeTargetAppWindows.isEmpty()) {
                layer = assignAndIncreaseLayerIfNeeded(mAboveImeTargetAppWindows.remove(), layer);
            }
        }

    }
+4 −9
Original line number Diff line number Diff line
@@ -60,8 +60,6 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import static android.app.ActivityManager.StackId;
@@ -91,7 +89,6 @@ import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
@@ -1654,18 +1651,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                && (!mIsChildWindow || !getParentWindow().hasMoved());
    }

    boolean isObscuringFullscreen(final DisplayInfo displayInfo) {
    boolean isObscuringDisplay() {
        Task task = getTask();
        if (task != null && task.mStack != null && !task.mStack.fillsParent()) {
            return false;
        }
        if (!isOpaqueDrawn() || !isFrameFullscreen(displayInfo)) {
            return false;
        }
        return true;
        return isOpaqueDrawn() && fillsDisplay();
    }

    boolean isFrameFullscreen(final DisplayInfo displayInfo) {
    boolean fillsDisplay() {
        final DisplayInfo displayInfo = getDisplayInfo();
        return mFrame.left <= 0 && mFrame.top <= 0
                && mFrame.right >= displayInfo.appWidth && mFrame.bottom >= displayInfo.appHeight;
    }
+3 −6
Original line number Diff line number Diff line
@@ -57,7 +57,6 @@ import android.os.Trace;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.MagnificationSpec;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
import android.view.WindowManager;
@@ -1108,10 +1107,9 @@ class WindowStateAnimator {

    /**
     * Calculate the window-space crop rect and fill clipRect.
     * @return true if clipRect has been filled otherwise, no window space
     * crop should be applied.
     * @return true if clipRect has been filled otherwise, no window space crop should be applied.
     */
    boolean calculateCrop(Rect clipRect) {
    private boolean calculateCrop(Rect clipRect) {
        final WindowState w = mWin;
        final DisplayContent displayContent = w.getDisplayContent();
        clipRect.setEmpty();
@@ -1130,7 +1128,6 @@ class WindowStateAnimator {
            return false;
        }

        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
        if (DEBUG_WINDOW_CROP) Slog.d(TAG,
                "Updating crop win=" + w + " mLastCrop=" + mLastClipRect);

@@ -1139,7 +1136,7 @@ class WindowStateAnimator {
        if (DEBUG_WINDOW_CROP) Slog.d(TAG, "Applying decor to crop win=" + w + " mDecorFrame="
                + w.mDecorFrame + " mSystemDecorRect=" + mSystemDecorRect);

        final boolean fullscreen = w.isFrameFullscreen(displayInfo);
        final boolean fullscreen = w.fillsDisplay();
        final boolean isFreeformResizing =
                w.isDragResizing() && w.getResizeMode() == DRAG_RESIZE_MODE_FREEFORM;

+57 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
@@ -120,6 +121,62 @@ public class WindowLayersControllerTests extends WindowTestsBase {
        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
    }

    @Test
    public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() throws Exception {
        final WindowState imeAppTarget =
                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
        final WindowState imeAppTargetChildAboveWindow = createWindow(imeAppTarget,
                TYPE_APPLICATION_ATTACHED_DIALOG, imeAppTarget.mToken,
                "imeAppTargetChildAboveWindow");
        final WindowState imeAppTargetChildBelowWindow = createWindow(imeAppTarget,
                TYPE_APPLICATION_MEDIA_OVERLAY, imeAppTarget.mToken,
                "imeAppTargetChildBelowWindow");

        sWm.mInputMethodTarget = imeAppTarget;
        sLayersController.assignWindowLayers(sDisplayContent);

        // Ime should be above all app windows except for child windows that are z-ordered above it
        // and below system windows if it is targeting an app window.
        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
        assertWindowLayerGreaterThan(imeAppTargetChildAboveWindow, sImeWindow);
        assertWindowLayerGreaterThan(sImeWindow, imeAppTargetChildBelowWindow);
        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);

        // And, IME dialogs should always have an higher layer than the IME.
        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
    }

    @Test
    public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() throws Exception {
        final WindowState appBelowImeTarget =
                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appBelowImeTarget");
        final WindowState imeAppTarget =
                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "imeAppTarget");
        final WindowState appAboveImeTarget =
                createWindow(null, TYPE_BASE_APPLICATION, sDisplayContent, "appAboveImeTarget");

        sWm.mInputMethodTarget = imeAppTarget;
        sLayersController.assignWindowLayers(sDisplayContent);

        // Ime should be above all app windows except for non-fullscreen app window above it and
        // below system windows if it is targeting an app window.
        assertWindowLayerGreaterThan(sImeWindow, imeAppTarget);
        assertWindowLayerGreaterThan(sImeWindow, appBelowImeTarget);
        assertWindowLayerGreaterThan(appAboveImeTarget, sImeWindow);
        assertWindowLayerGreaterThan(sImeWindow, sChildAppWindow);
        assertWindowLayerGreaterThan(sImeWindow, sAppWindow);
        assertWindowLayerGreaterThan(sImeWindow, sDockedDividerWindow);
        assertWindowLayerGreaterThan(sNavBarWindow, sImeWindow);
        assertWindowLayerGreaterThan(sStatusBarWindow, sImeWindow);

        // And, IME dialogs should always have an higher layer than the IME.
        assertWindowLayerGreaterThan(sImeDialogWindow, sImeWindow);
    }

    @Test
    public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
        final WindowState imeSystemOverlayTarget =