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

Commit 6b0fd366 authored by Yunfan Chen's avatar Yunfan Chen
Browse files

Reland "Keep runtime insets types during layout"

This reverts commit 168bfd8e.

Suspicious regression is not reproducible. Will keep communicate with
the POC and try to resolve them later.

Test: Treehugger
Test: testHideIme_WMS
Bug: 161689946
Change-Id: I029f94efb6b7054215888c6491e0d72cccf2ce09
parent d1fdc4c4
Loading
Loading
Loading
Loading
+24 −9
Original line number Diff line number Diff line
@@ -106,7 +106,9 @@ public class InsetsState implements Parcelable {
    public static final int ITYPE_NAVIGATION_BAR = 1;
    public static final int ITYPE_CAPTION_BAR = 2;

    public static final int ITYPE_TOP_GESTURES = 3;
    // The always visible types are visible to all windows regardless of the z-order.
    public static final int FIRST_ALWAYS_VISIBLE_TYPE = 3;
    public static final int ITYPE_TOP_GESTURES = FIRST_ALWAYS_VISIBLE_TYPE;
    public static final int ITYPE_BOTTOM_GESTURES = 4;
    public static final int ITYPE_LEFT_GESTURES = 5;
    public static final int ITYPE_RIGHT_GESTURES = 6;
@@ -117,15 +119,16 @@ public class InsetsState implements Parcelable {
    public static final int ITYPE_LEFT_MANDATORY_GESTURES = 9;
    public static final int ITYPE_RIGHT_MANDATORY_GESTURES = 10;

    public static final int ITYPE_LEFT_TAPPABLE_ELEMENT = 11;
    public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 12;
    public static final int ITYPE_RIGHT_TAPPABLE_ELEMENT = 13;
    public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 14;
    public static final int ITYPE_LEFT_DISPLAY_CUTOUT = 11;
    public static final int ITYPE_TOP_DISPLAY_CUTOUT = 12;
    public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 13;
    public static final int ITYPE_BOTTOM_DISPLAY_CUTOUT = 14;
    public static final int LAST_ALWAYS_VISIBLE_TYPE = ITYPE_BOTTOM_DISPLAY_CUTOUT;

    public static final int ITYPE_LEFT_DISPLAY_CUTOUT = 15;
    public static final int ITYPE_TOP_DISPLAY_CUTOUT = 16;
    public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 17;
    public static final int ITYPE_BOTTOM_DISPLAY_CUTOUT = 18;
    public static final int ITYPE_LEFT_TAPPABLE_ELEMENT = 15;
    public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 16;
    public static final int ITYPE_RIGHT_TAPPABLE_ELEMENT = 17;
    public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 18;

    /** Input method window. */
    public static final int ITYPE_IME = 19;
@@ -181,6 +184,18 @@ public class InsetsState implements Parcelable {
        set(copy, copySources);
    }

    /**
     * Mirror the always visible sources from the other state. They will share the same object for
     * the always visible types.
     *
     * @param other the state to mirror the mirrored sources from.
     */
    public void mirrorAlwaysVisibleInsetsSources(InsetsState other) {
        for (int type = FIRST_ALWAYS_VISIBLE_TYPE; type <= LAST_ALWAYS_VISIBLE_TYPE; type++) {
            mSources[type] = other.mSources[type];
        }
    }

    /**
     * Calculates {@link WindowInsets} based on the current source configuration.
     *
+24 −15
Original line number Diff line number Diff line
@@ -670,8 +670,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    // Used in updating override configurations
    private final Configuration mTempConfig = new Configuration();

    // Used in performing layout
    private boolean mTmpWindowsBehindIme;
    // Used in performing layout, to record the insets provided by other windows above the current
    // window.
    private InsetsState mTmpAboveInsetsState = new InsetsState();

    /**
     * Used to prevent recursions when calling
@@ -770,18 +771,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                    + " parentHidden=" + w.isParentWindowHidden());
        }

        // Sets mBehindIme for each window. Windows behind IME can get IME insets.
        if (w.mBehindIme != mTmpWindowsBehindIme) {
            w.mBehindIme = mTmpWindowsBehindIme;
            if (getInsetsStateController().getRawInsetsState().getSourceOrDefaultVisibility(
                    ITYPE_IME)) {
                // If IME is invisible, behind IME or not doesn't make the insets different.
        // Sets mAboveInsets for each window. Windows behind the window providing the insets can
        // receive the insets.
        if (!w.mAboveInsetsState.equals(mTmpAboveInsetsState)) {
            w.mAboveInsetsState.set(mTmpAboveInsetsState);
            mWinInsetsChanged.add(w);
        }
        }
        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,
@@ -816,8 +811,16 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                    + " mContainingFrame=" + w.getContainingFrame()
                    + " mDisplayFrame=" + w.getDisplayFrame());
        }
        provideInsetsByWindow(w);
    };

    private void provideInsetsByWindow(WindowState w) {
        for (int i = 0; i < w.mProvidedInsetsSources.size(); i++) {
            final InsetsSource providedSource = w.mProvidedInsetsSources.valueAt(i);
            mTmpAboveInsetsState.addSource(providedSource);
        }
    }

    private final Consumer<WindowState> mPerformLayoutAttached = w -> {
        if (w.mLayoutAttached) {
            if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame
@@ -4283,14 +4286,20 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                    + " dh=" + mDisplayInfo.logicalHeight);
        }

        // Used to indicate that we have processed the insets windows. This needs to be after
        // beginLayoutLw to ensure the raw insets state display related info is initialized.
        final InsetsState rawInsetsState = getInsetsStateController().getRawInsetsState();
        mTmpAboveInsetsState = new InsetsState();
        mTmpAboveInsetsState.setDisplayFrame(rawInsetsState.getDisplayFrame());
        mTmpAboveInsetsState.setDisplayCutout(rawInsetsState.getDisplayCutout());
        mTmpAboveInsetsState.mirrorAlwaysVisibleInsetsSources(rawInsetsState);

        int seq = mLayoutSeq + 1;
        if (seq < 0) seq = 0;
        mLayoutSeq = seq;

        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 */);
+9 −5
Original line number Diff line number Diff line
@@ -151,6 +151,7 @@ class InsetsSourceProvider {
            // animate-out as new one animates-in.
            mWin.cancelAnimation();
            mWin.mPendingPositionChanged = null;
            mWin.mProvidedInsetsSources.remove(mSource.getType());
        }
        ProtoLog.d(WM_DEBUG_IME, "InsetsSource setWin %s", win);
        mWin = win;
@@ -160,7 +161,9 @@ class InsetsSourceProvider {
            setServerVisible(false);
            mSource.setFrame(new Rect());
            mSource.setVisibleFrame(null);
        } else if (mControllable) {
        } else {
            mWin.mProvidedInsetsSources.put(mSource.getType(), mSource);
            if (mControllable) {
                mWin.setControllableInsetProvider(this);
                if (mPendingControlTarget != null) {
                    updateControlForTarget(mPendingControlTarget, true /* force */);
@@ -168,6 +171,7 @@ class InsetsSourceProvider {
                }
            }
        }
    }

    /**
     * @return Whether there is a window which backs this source.
+13 −29
Original line number Diff line number Diff line
@@ -104,6 +104,8 @@ class InsetsStateController {
     * visible to the target. e.g., the source which represents the target window itself, and the
     * IME source when the target is above IME. We also need to exclude certain types of insets
     * source for client within specific windowing modes.
     * This is to get the insets for a window layout on the screen. If the window is not there, use
     * the {@link #getInsetsForWindowMetrics} to get insets instead.
     *
     * @param target The window associate with the perspective.
     * @return The state stripped of the necessary information.
@@ -117,8 +119,8 @@ class InsetsStateController {
        final @InternalInsetsType int type = provider != null
                ? provider.getSource().getType() : ITYPE_INVALID;
        return getInsetsForTarget(type, target.getWindowingMode(), target.isAlwaysOnTop(),
                isAboveIme(target),
                target.getFrozenInsetsState() != null ? target.getFrozenInsetsState() : mState);
                target.getFrozenInsetsState() != null ? target.getFrozenInsetsState() :
                target.mAboveInsetsState);
    }

    InsetsState getInsetsForWindowMetrics(@NonNull WindowManager.LayoutParams attrs) {
@@ -133,19 +135,7 @@ class InsetsStateController {
        final @WindowingMode int windowingMode = token != null
                ? token.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
        final boolean alwaysOnTop = token != null && token.isAlwaysOnTop();
        return getInsetsForTarget(type, windowingMode, alwaysOnTop, isAboveIme(token), mState);
    }

    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;
        return getInsetsForTarget(type, windowingMode, alwaysOnTop, mState);
    }

    private static @InternalInsetsType
@@ -181,10 +171,12 @@ class InsetsStateController {
     * @see #getInsetsForWindowMetrics
     */
    private InsetsState getInsetsForTarget(@InternalInsetsType int type,
            @WindowingMode int windowingMode, boolean isAlwaysOnTop, boolean aboveIme,
            @NonNull InsetsState state) {
            @WindowingMode int windowingMode, boolean isAlwaysOnTop, InsetsState state) {
        boolean stateCopied = false;

        if (type != ITYPE_INVALID) {
            state = new InsetsState(state);
            stateCopied = true;
            state.removeSource(type);

            // Navigation bar doesn't get influenced by anything else
@@ -219,23 +211,15 @@ class InsetsStateController {

        if (WindowConfiguration.isFloating(windowingMode)
                || (windowingMode == WINDOWING_MODE_MULTI_WINDOW && isAlwaysOnTop)) {
            if (!stateCopied) {
                state = new InsetsState(state);
                stateCopied = true;
            }
            state.removeSource(ITYPE_STATUS_BAR);
            state.removeSource(ITYPE_NAVIGATION_BAR);
            state.removeSource(ITYPE_EXTRA_NAVIGATION_BAR);
        }

        if (aboveIme) {
            InsetsSource imeSource = state.peekSource(ITYPE_IME);
            if (imeSource != null && imeSource.isVisible()) {
                imeSource = new InsetsSource(imeSource);
                imeSource.setVisible(false);
                imeSource.setFrame(0, 0, 0, 0);
                state = new InsetsState(state);
                state.addSource(imeSource);
            }
        }

        return state;
    }

+8 −2
Original line number Diff line number Diff line
@@ -212,6 +212,7 @@ import android.os.Trace;
import android.os.WorkSource;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
@@ -647,9 +648,14 @@ 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.
     * The insets state of sources provided by windows above the current window.
     */
    boolean mBehindIme = false;
    InsetsState mAboveInsetsState = new InsetsState();

    /**
     * The insets sources provided by this window.
     */
    ArrayMap<Integer, InsetsSource> mProvidedInsetsSources = new ArrayMap<>();

    /**
     * Surface insets from the previous call to relayout(), used to track
Loading