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 Original line 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_NAVIGATION_BAR = 1;
    public static final int ITYPE_CAPTION_BAR = 2;
    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_BOTTOM_GESTURES = 4;
    public static final int ITYPE_LEFT_GESTURES = 5;
    public static final int ITYPE_LEFT_GESTURES = 5;
    public static final int ITYPE_RIGHT_GESTURES = 6;
    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_LEFT_MANDATORY_GESTURES = 9;
    public static final int ITYPE_RIGHT_MANDATORY_GESTURES = 10;
    public static final int ITYPE_RIGHT_MANDATORY_GESTURES = 10;


    public static final int ITYPE_LEFT_TAPPABLE_ELEMENT = 11;
    public static final int ITYPE_LEFT_DISPLAY_CUTOUT = 11;
    public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 12;
    public static final int ITYPE_TOP_DISPLAY_CUTOUT = 12;
    public static final int ITYPE_RIGHT_TAPPABLE_ELEMENT = 13;
    public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 13;
    public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 14;
    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_LEFT_TAPPABLE_ELEMENT = 15;
    public static final int ITYPE_TOP_DISPLAY_CUTOUT = 16;
    public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 16;
    public static final int ITYPE_RIGHT_DISPLAY_CUTOUT = 17;
    public static final int ITYPE_RIGHT_TAPPABLE_ELEMENT = 17;
    public static final int ITYPE_BOTTOM_DISPLAY_CUTOUT = 18;
    public static final int ITYPE_BOTTOM_TAPPABLE_ELEMENT = 18;


    /** Input method window. */
    /** Input method window. */
    public static final int ITYPE_IME = 19;
    public static final int ITYPE_IME = 19;
@@ -181,6 +184,18 @@ public class InsetsState implements Parcelable {
        set(copy, copySources);
        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.
     * Calculates {@link WindowInsets} based on the current source configuration.
     *
     *
+24 −15
Original line number Original line Diff line number Diff line
@@ -670,8 +670,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    // Used in updating override configurations
    // Used in updating override configurations
    private final Configuration mTempConfig = new Configuration();
    private final Configuration mTempConfig = new Configuration();


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


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


        // Sets mBehindIme for each window. Windows behind IME can get IME insets.
        // Sets mAboveInsets for each window. Windows behind the window providing the insets can
        if (w.mBehindIme != mTmpWindowsBehindIme) {
        // receive the insets.
            w.mBehindIme = mTmpWindowsBehindIme;
        if (!w.mAboveInsetsState.equals(mTmpAboveInsetsState)) {
            if (getInsetsStateController().getRawInsetsState().getSourceOrDefaultVisibility(
            w.mAboveInsetsState.set(mTmpAboveInsetsState);
                    ITYPE_IME)) {
                // If IME is invisible, behind IME or not doesn't make the insets different.
            mWinInsetsChanged.add(w);
            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
        // 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,
        // 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()
                    + " mContainingFrame=" + w.getContainingFrame()
                    + " mDisplayFrame=" + w.getDisplayFrame());
                    + " 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 -> {
    private final Consumer<WindowState> mPerformLayoutAttached = w -> {
        if (w.mLayoutAttached) {
        if (w.mLayoutAttached) {
            if (DEBUG_LAYOUT) Slog.v(TAG, "2ND PASS " + w + " mHaveFrame=" + w.mHaveFrame
            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);
                    + " 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;
        int seq = mLayoutSeq + 1;
        if (seq < 0) seq = 0;
        if (seq < 0) seq = 0;
        mLayoutSeq = seq;
        mLayoutSeq = seq;


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


    /**
    /**
     * @return Whether there is a window which backs this source.
     * @return Whether there is a window which backs this source.
+13 −29
Original line number Original line 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
     * 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
     * IME source when the target is above IME. We also need to exclude certain types of insets
     * source for client within specific windowing modes.
     * 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.
     * @param target The window associate with the perspective.
     * @return The state stripped of the necessary information.
     * @return The state stripped of the necessary information.
@@ -117,8 +119,8 @@ class InsetsStateController {
        final @InternalInsetsType int type = provider != null
        final @InternalInsetsType int type = provider != null
                ? provider.getSource().getType() : ITYPE_INVALID;
                ? provider.getSource().getType() : ITYPE_INVALID;
        return getInsetsForTarget(type, target.getWindowingMode(), target.isAlwaysOnTop(),
        return getInsetsForTarget(type, target.getWindowingMode(), target.isAlwaysOnTop(),
                isAboveIme(target),
                target.getFrozenInsetsState() != null ? target.getFrozenInsetsState() :
                target.getFrozenInsetsState() != null ? target.getFrozenInsetsState() : mState);
                target.mAboveInsetsState);
    }
    }


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


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

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


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


        if (WindowConfiguration.isFloating(windowingMode)
        if (WindowConfiguration.isFloating(windowingMode)
                || (windowingMode == WINDOWING_MODE_MULTI_WINDOW && isAlwaysOnTop)) {
                || (windowingMode == WINDOWING_MODE_MULTI_WINDOW && isAlwaysOnTop)) {
            if (!stateCopied) {
                state = new InsetsState(state);
                state = new InsetsState(state);
                stateCopied = true;
            }
            state.removeSource(ITYPE_STATUS_BAR);
            state.removeSource(ITYPE_STATUS_BAR);
            state.removeSource(ITYPE_NAVIGATION_BAR);
            state.removeSource(ITYPE_NAVIGATION_BAR);
            state.removeSource(ITYPE_EXTRA_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;
        return state;
    }
    }


+8 −2
Original line number Original line Diff line number Diff line
@@ -212,6 +212,7 @@ import android.os.Trace;
import android.os.WorkSource;
import android.os.WorkSource;
import android.provider.Settings;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
import android.util.MergedConfiguration;
@@ -647,9 +648,14 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
    boolean mSeamlesslyRotated = false;
    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
     * Surface insets from the previous call to relayout(), used to track
Loading