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

Commit 43a268fb authored by Tiger Huang's avatar Tiger Huang Committed by Android (Google) Code Review
Browse files

Merge "Add PRIVATE_FLAG_CONSUME_IME_INSETS" into main

parents bdd1caeb f6f102cc
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -3250,6 +3250,13 @@ public interface WindowManager extends ViewManager {
         */
        public static final int PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC = 1 << 24;

        /**
         * Flag to indicate that the window consumes the insets of {@link Type#ime()}. This makes
         * windows below this window unable to receive visible IME insets.
         * @hide
         */
        public static final int PRIVATE_FLAG_CONSUME_IME_INSETS = 1 << 25;

        /**
         * Flag to indicate that the window is controlling the appearance of system bars. So we
         * don't need to adjust it by reading its system UI flags for compatibility.
@@ -3334,6 +3341,7 @@ public interface WindowManager extends ViewManager {
                PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION,
                PRIVATE_FLAG_NOT_MAGNIFIABLE,
                PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
                PRIVATE_FLAG_CONSUME_IME_INSETS,
                PRIVATE_FLAG_APPEARANCE_CONTROLLED,
                PRIVATE_FLAG_BEHAVIOR_CONTROLLED,
                PRIVATE_FLAG_FIT_INSETS_CONTROLLED,
@@ -3431,6 +3439,10 @@ public interface WindowManager extends ViewManager {
                        mask = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
                        equals = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
                        name = "COLOR_SPACE_AGNOSTIC"),
                @ViewDebug.FlagToString(
                        mask = PRIVATE_FLAG_CONSUME_IME_INSETS,
                        equals = PRIVATE_FLAG_CONSUME_IME_INSETS,
                        name = "CONSUME_IME_INSETS"),
                @ViewDebug.FlagToString(
                        mask = PRIVATE_FLAG_APPEARANCE_CONTROLLED,
                        equals = PRIVATE_FLAG_APPEARANCE_CONTROLLED,
@@ -3458,7 +3470,7 @@ public interface WindowManager extends ViewManager {
                @ViewDebug.FlagToString(
                        mask = PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY,
                        equals = PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY,
                        name = "PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY")
                        name = "SYSTEM_APPLICATION_OVERLAY")
        })
        @PrivateFlags
        @TestApi
+16 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCRE
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_CONSUME_IME_INSETS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IMMERSIVE_CONFIRMATION_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
@@ -272,6 +273,8 @@ public class DisplayPolicy {

    private @InsetsType int mForciblyShownTypes;

    private boolean mImeInsetsConsumed;

    private boolean mIsImmersiveMode;

    // The windows we were told about in focusChanged.
@@ -1420,6 +1423,7 @@ public class DisplayPolicy {
        mShowingDream = false;
        mIsFreeformWindowOverlappingWithNavBar = false;
        mForciblyShownTypes = 0;
        mImeInsetsConsumed = false;
    }

    /**
@@ -1481,6 +1485,17 @@ public class DisplayPolicy {
            mForciblyShownTypes |= win.mAttrs.forciblyShownTypes;
        }

        if (win.mImeInsetsConsumed != mImeInsetsConsumed) {
            win.mImeInsetsConsumed = mImeInsetsConsumed;
            final WindowState imeWin = mDisplayContent.mInputMethodWindow;
            if (win.isReadyToDispatchInsetsState() && imeWin != null && imeWin.isVisible()) {
                win.notifyInsetsChanged();
            }
        }
        if ((attrs.privateFlags & PRIVATE_FLAG_CONSUME_IME_INSETS) != 0 && win.isVisible()) {
            mImeInsetsConsumed = true;
        }

        if (!affectsSystemUi) {
            return;
        }
@@ -2828,6 +2843,7 @@ public class DisplayPolicy {
            }
        }
        pw.print(prefix); pw.print("mTopIsFullscreen="); pw.println(mTopIsFullscreen);
        pw.print(prefix); pw.print("mImeInsetsConsumed="); pw.println(mImeInsetsConsumed);
        pw.print(prefix); pw.print("mForceShowNavigationBarEnabled=");
        pw.print(mForceShowNavigationBarEnabled);
        pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn);
+14 −1
Original line number Diff line number Diff line
@@ -391,13 +391,26 @@ class InsetsPolicy {

            if (originalImeSource != null) {
                final boolean imeVisibility = w.isRequestedVisible(Type.ime());
                final InsetsState state = copyState ? new InsetsState(originalState)
                final InsetsState state = copyState
                        ? new InsetsState(originalState)
                        : originalState;
                final InsetsSource imeSource = new InsetsSource(originalImeSource);
                imeSource.setVisible(imeVisibility);
                state.addSource(imeSource);
                return state;
            }
        } else if (w.mImeInsetsConsumed) {
            // Set the IME source (if there is one) to be invisible if it has been consumed.
            final InsetsSource originalImeSource = originalState.peekSource(ID_IME);
            if (originalImeSource != null && originalImeSource.isVisible()) {
                final InsetsState state = copyState
                        ? new InsetsState(originalState)
                        : originalState;
                final InsetsSource imeSource = new InsetsSource(originalImeSource);
                imeSource.setVisible(false);
                state.addSource(imeSource);
                return state;
            }
        }
        return originalState;
    }
+21 −7
Original line number Diff line number Diff line
@@ -667,6 +667,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
     */
    boolean mSeamlesslyRotated = false;

    /**
     * Whether the IME insets have been consumed. If {@code true}, this window won't be able to
     * receive visible IME insets; {@code false}, otherwise.
     */
    boolean mImeInsetsConsumed = false;

    /**
     * The insets state of sources provided by windows above the current window.
     */
@@ -1487,7 +1493,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP

            if (insetsChanged) {
                mWindowFrames.setInsetsChanged(false);
                if (mWmService.mWindowsInsetsChanged > 0) {
                    mWmService.mWindowsInsetsChanged--;
                }
                if (mWmService.mWindowsInsetsChanged == 0) {
                    mWmService.mH.removeMessages(WindowManagerService.H.INSETS_CHANGED);
                }
@@ -3796,6 +3804,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
     */
    void notifyInsetsChanged() {
        ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "notifyInsetsChanged for %s ", this);
        if (!mWindowFrames.hasInsetsChanged()) {
            mWindowFrames.setInsetsChanged(true);

            // If the new InsetsState won't be dispatched before releasing WM lock, the following
@@ -3803,6 +3812,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
            mWmService.mWindowsInsetsChanged++;
            mWmService.mH.removeMessages(WindowManagerService.H.INSETS_CHANGED);
            mWmService.mH.sendEmptyMessage(WindowManagerService.H.INSETS_CHANGED);
        }

        final WindowContainer p = getParent();
        if (p != null) {
@@ -4192,6 +4202,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        } else {
            pw.print("null");
        }
        pw.println();

        if (mXOffset != 0 || mYOffset != 0) {
            pw.println(prefix + "mXOffset=" + mXOffset + " mYOffset=" + mYOffset);
@@ -4225,6 +4236,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
        if (computeDragResizing()) {
            pw.println(prefix + "computeDragResizing=" + computeDragResizing());
        }
        if (mImeInsetsConsumed) {
            pw.println(prefix + "mImeInsetsConsumed=true");
        }
        pw.println(prefix + "isOnScreen=" + isOnScreen());
        pw.println(prefix + "isVisible=" + isVisible());
        pw.println(prefix + "keepClearAreas: restricted=" + mKeepClearAreas
+53 −0
Original line number Diff line number Diff line
@@ -19,10 +19,13 @@ package com.android.server.wm;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.view.InsetsSource.ID_IME;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_CONSUME_IME_INSETS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
@@ -432,6 +435,56 @@ public class InsetsPolicyTest extends WindowTestsBase {

    }

    @SetupWindows(addWindows = W_INPUT_METHOD)
    @Test
    public void testConsumeImeInsets() {
        final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
        final InsetsSource imeSource = new InsetsSource(ID_IME, ime());
        imeSource.setVisible(true);
        mImeWindow.mHasSurface = true;

        final WindowState win1 = addWindow(TYPE_APPLICATION, "win1");
        final WindowState win2 = addWindow(TYPE_APPLICATION, "win2");

        win1.mAboveInsetsState.addSource(imeSource);
        win1.mHasSurface = true;
        win2.mAboveInsetsState.addSource(imeSource);
        win2.mHasSurface = true;

        assertTrue(mImeWindow.isVisible());
        assertTrue(win1.isVisible());
        assertTrue(win2.isVisible());

        // Make sure both windows have visible IME insets.
        assertTrue(win1.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue(win2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));

        win2.mAttrs.privateFlags |= PRIVATE_FLAG_CONSUME_IME_INSETS;

        displayPolicy.beginPostLayoutPolicyLw();
        displayPolicy.applyPostLayoutPolicyLw(win2, win2.mAttrs, null, null);
        displayPolicy.applyPostLayoutPolicyLw(win1, win1.mAttrs, null, null);
        displayPolicy.finishPostLayoutPolicyLw();

        // Make sure win2 doesn't have visible IME insets, but win1 still does.
        assertTrue(win2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertFalse(win1.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue(win1.getWindowFrames().hasInsetsChanged());

        win2.mAttrs.privateFlags &= ~PRIVATE_FLAG_CONSUME_IME_INSETS;
        win2.getWindowFrames().setInsetsChanged(false);

        displayPolicy.beginPostLayoutPolicyLw();
        displayPolicy.applyPostLayoutPolicyLw(win2, win2.mAttrs, null, null);
        displayPolicy.applyPostLayoutPolicyLw(win1, win1.mAttrs, null, null);
        displayPolicy.finishPostLayoutPolicyLw();

        // Make sure both windows have visible IME insets.
        assertTrue(win1.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue(win2.getInsetsState().isSourceOrDefaultVisible(ID_IME, ime()));
        assertTrue(win1.getWindowFrames().hasInsetsChanged());
    }

    private WindowState addNavigationBar() {
        final Binder owner = new Binder();
        final WindowState win = createWindow(null, TYPE_NAVIGATION_BAR, "navBar");