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

Commit 92ecc32d authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Merge "Don't dispatch IME insets if the target is above IME" into...

Merge "Merge "Don't dispatch IME insets if the target is above IME" into rvc-dev am: 0e503e5e am: 4520d480" into rvc-d1-dev-plus-aosp am: 1466cb45 am: 62c4eea4

Change-Id: I0b120439ffebb31c9a72d5814514bf0d5df0614a
parents 90c63610 62c4eea4
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -659,6 +659,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    // When non-null, new tasks get put into this root task.
    Task mLaunchRootTask = null;

    // Used in performing layout
    private boolean mTmpWindowsBehindIme;

    private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
        WindowStateAnimator winAnimator = w.mWinAnimator;
        final ActivityRecord activity = w.mActivityRecord;
@@ -750,6 +753,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
                    + " parentHidden=" + w.isParentWindowHidden());
        }

        // Sets mBehindIme for each window. Windows behind IME can get IME insets.
        w.mBehindIme = mTmpWindowsBehindIme;
        if (w == mInputMethodWindow) {
            mTmpWindowsBehindIme = true;
        }

        // If this view is GONE, then skip it -- keep the current frame, and let the caller know
        // so they can ignore it if they want.  (We do the normal layout for INVISIBLE windows,
        // since that means "perform layout as normal, just don't display").
@@ -4016,6 +4025,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
        mTmpWindow = null;
        mTmpInitial = initial;

        // Used to indicate that we have processed the IME window.
        mTmpWindowsBehindIme = false;

        // First perform layout of any root windows (not attached to another window).
        forAllWindows(mPerformLayout, true /* traverseTopToBottom */);

+2 −9
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import static android.view.InsetsState.ITYPE_BOTTOM_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
import static android.view.InsetsState.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static android.view.InsetsState.ITYPE_CAPTION_BAR;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
@@ -1493,14 +1492,8 @@ public class DisplayPolicy {
     */
    public void beginLayoutLw(DisplayFrames displayFrames, int uiMode) {
        displayFrames.onBeginLayout();
        final InsetsState insetsState =
                mDisplayContent.getInsetsStateController().getRawInsetsState();

        // Reset the frame of IME so that the layout of windows above IME won't get influenced.
        // Once we layout the IME, frames will be set again on the source.
        insetsState.getSource(ITYPE_IME).setFrame(0, 0, 0, 0);

        updateInsetsStateForDisplayCutout(displayFrames, insetsState);
        updateInsetsStateForDisplayCutout(displayFrames,
                mDisplayContent.getInsetsStateController().getRawInsetsState());
        mSystemGestures.screenWidth = displayFrames.mUnrestricted.width();
        mSystemGestures.screenHeight = displayFrames.mUnrestricted.height();

+24 −8
Original line number Diff line number Diff line
@@ -88,8 +88,8 @@ class InsetsStateController {
        final InsetsSourceProvider provider = target.getControllableInsetProvider();
        final @InternalInsetsType int type = provider != null
                ? provider.getSource().getType() : ITYPE_INVALID;
        return getInsetsForTypeAndWindowingMode(type, target.getWindowingMode(),
                target.isAlwaysOnTop());
        return getInsetsForDispatchInner(type, target.getWindowingMode(), target.isAlwaysOnTop(),
                isAboveIme(target));
    }

    InsetsState getInsetsForWindowMetrics(@NonNull WindowManager.LayoutParams attrs) {
@@ -97,9 +97,20 @@ class InsetsStateController {
        final WindowToken token = mDisplayContent.getWindowToken(attrs.token);
        final @WindowingMode int windowingMode = token != null
                ? token.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
        final boolean alwaysOnTop = token != null
                ? token.isAlwaysOnTop() : false;
        return getInsetsForTypeAndWindowingMode(type, windowingMode, alwaysOnTop);
        final boolean alwaysOnTop = token != null && token.isAlwaysOnTop();
        return getInsetsForDispatchInner(type, windowingMode, alwaysOnTop, isAboveIme(token));
    }

    private boolean isAboveIme(WindowContainer target) {
        final WindowState imeWindow = mDisplayContent.mInputMethodWindow;
        if (target == null || imeWindow == null) {
            return false;
        }
        if (target instanceof WindowState) {
            final WindowState win = (WindowState) target;
            return win.needsRelativeLayeringToIme() || !win.mBehindIme;
        }
        return false;
    }

    private static @InternalInsetsType int getInsetsTypeForWindowType(int type) {
@@ -116,8 +127,8 @@ class InsetsStateController {
    }

    /** @see #getInsetsForDispatch */
    private InsetsState getInsetsForTypeAndWindowingMode(@InternalInsetsType int type,
            @WindowingMode int windowingMode, boolean isAlwaysOnTop) {
    private InsetsState getInsetsForDispatchInner(@InternalInsetsType int type,
            @WindowingMode int windowingMode, boolean isAlwaysOnTop, boolean aboveIme) {
        InsetsState state = mState;

        if (type != ITYPE_INVALID) {
@@ -158,6 +169,11 @@ class InsetsStateController {
            state.removeSource(ITYPE_NAVIGATION_BAR);
        }

        if (aboveIme) {
            state = new InsetsState(state);
            state.removeSource(ITYPE_IME);
        }

        return state;
    }

+5 −0
Original line number Diff line number Diff line
@@ -608,6 +608,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
     */
    boolean mSeamlesslyRotated = false;

    /**
     * Indicates if this window is behind IME. Only windows behind IME can get insets from IME.
     */
    boolean mBehindIme = false;

    /**
     * Surface insets from the previous call to relayout(), used to track
     * if we are changing the Surface insets.
+57 −0
Original line number Diff line number Diff line
@@ -19,10 +19,12 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
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.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;

@@ -146,6 +148,61 @@ public class InsetsStateControllerTest extends WindowTestsBase {
        assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_NAVIGATION_BAR));
    }

    @Test
    public void testStripForDispatch_belowIme() {
        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
        final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");

        getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null);

        assertNotNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_IME));
    }

    @Test
    public void testStripForDispatch_aboveIme() {
        final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");
        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");

        getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null);

        assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_IME));
    }

    @Test
    public void testStripForDispatch_childWindow_altFocusable() {
        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");

        final WindowState child = createWindow(app, TYPE_APPLICATION, "child");
        child.mAttrs.flags |= FLAG_ALT_FOCUSABLE_IM;

        final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");

        // IME cannot be the IME target.
        ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;

        getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null);

        assertNull(getController().getInsetsForDispatch(child).peekSource(ITYPE_IME));
    }

    @Test
    public void testStripForDispatch_childWindow_splitScreen() {
        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");

        final WindowState child = createWindow(app, TYPE_APPLICATION, "child");
        child.mAttrs.flags |= FLAG_NOT_FOCUSABLE;
        child.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);

        final WindowState ime = createWindow(null, TYPE_APPLICATION, "ime");

        // IME cannot be the IME target.
        ime.mAttrs.flags |= FLAG_NOT_FOCUSABLE;

        getController().getSourceProvider(ITYPE_IME).setWindow(ime, null, null);

        assertNull(getController().getInsetsForDispatch(child).peekSource(ITYPE_IME));
    }

    @Test
    public void testImeForDispatch() {
        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");