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

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

Merge "Only update mAboveInsetsState when necessary" into sc-dev

parents 0c89d4b8 c891f226
Loading
Loading
Loading
Loading
+39 −22
Original line number Diff line number Diff line
@@ -20,8 +20,6 @@ import static android.view.InsetsStateProto.DISPLAY_CUTOUT;
import static android.view.InsetsStateProto.DISPLAY_FRAME;
import static android.view.InsetsStateProto.SOURCES;
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.indexOf;
@@ -106,14 +104,11 @@ public class InsetsState implements Parcelable {
    public static final int ITYPE_NAVIGATION_BAR = 1;
    public static final int ITYPE_CAPTION_BAR = 2;

    // 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_TOP_GESTURES = 3;
    public static final int ITYPE_BOTTOM_GESTURES = 4;
    public static final int ITYPE_LEFT_GESTURES = 5;
    public static final int ITYPE_RIGHT_GESTURES = 6;

    /** Additional gesture inset types that map into {@link Type.MANDATORY_SYSTEM_GESTURES}. */
    public static final int ITYPE_TOP_MANDATORY_GESTURES = 7;
    public static final int ITYPE_BOTTOM_MANDATORY_GESTURES = 8;
    public static final int ITYPE_LEFT_MANDATORY_GESTURES = 9;
@@ -123,7 +118,6 @@ public class InsetsState implements Parcelable {
    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_TAPPABLE_ELEMENT = 15;
    public static final int ITYPE_TOP_TAPPABLE_ELEMENT = 16;
@@ -187,18 +181,6 @@ 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.
     *
@@ -380,14 +362,14 @@ public class InsetsState implements Parcelable {
        processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
                insets, type);

        if (type == MANDATORY_SYSTEM_GESTURES) {
        if (type == Type.MANDATORY_SYSTEM_GESTURES) {
            // Mandatory system gestures are also system gestures.
            // TODO: find a way to express this more generally. One option would be to define
            //       Type.systemGestureInsets() as NORMAL | MANDATORY, but then we lose the
            //       ability to set systemGestureInsets() independently from
            //       mandatorySystemGestureInsets() in the Builder.
            processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
                    insets, SYSTEM_GESTURES);
                    insets, Type.SYSTEM_GESTURES);
        }
    }

@@ -493,9 +475,14 @@ public class InsetsState implements Parcelable {
     * to the client.
     *
     * @param type The {@link InternalInsetsType} of the source to remove
     * @return {@code true} if this InsetsState was modified; {@code false} otherwise.
     */
    public void removeSource(@InternalInsetsType int type) {
    public boolean removeSource(@InternalInsetsType int type) {
        if (mSources[type] == null) {
            return false;
        }
        mSources[type] = null;
        return true;
    }

    /**
@@ -552,6 +539,24 @@ public class InsetsState implements Parcelable {
        }
    }

    /**
     * Sets the values from the other InsetsState. But for sources, only specific types of source
     * would be set.
     *
     * @param other the other InsetsState.
     * @param types the only types of sources would be set.
     */
    public void set(InsetsState other, @InsetsType int types) {
        mDisplayFrame.set(other.mDisplayFrame);
        mDisplayCutout.set(other.mDisplayCutout);
        mRoundedCorners = other.getRoundedCorners();
        final ArraySet<Integer> t = toInternalType(types);
        for (int i = t.size() - 1; i >= 0; i--) {
            final int type = t.valueAt(i);
            mSources[type] = other.mSources[type];
        }
    }

    public void addSource(InsetsSource source) {
        mSources[source.getType()] = source;
    }
@@ -575,6 +580,18 @@ public class InsetsState implements Parcelable {
        if ((types & Type.CAPTION_BAR) != 0) {
            result.add(ITYPE_CAPTION_BAR);
        }
        if ((types & Type.SYSTEM_GESTURES) != 0) {
            result.add(ITYPE_LEFT_GESTURES);
            result.add(ITYPE_TOP_GESTURES);
            result.add(ITYPE_RIGHT_GESTURES);
            result.add(ITYPE_BOTTOM_GESTURES);
        }
        if ((types & Type.MANDATORY_SYSTEM_GESTURES) != 0) {
            result.add(ITYPE_LEFT_MANDATORY_GESTURES);
            result.add(ITYPE_TOP_MANDATORY_GESTURES);
            result.add(ITYPE_RIGHT_MANDATORY_GESTURES);
            result.add(ITYPE_BOTTOM_MANDATORY_GESTURES);
        }
        if ((types & Type.DISPLAY_CUTOUT) != 0) {
            result.add(ITYPE_LEFT_DISPLAY_CUTOUT);
            result.add(ITYPE_TOP_DISPLAY_CUTOUT);
+1 −1
Original line number Diff line number Diff line
@@ -335,7 +335,7 @@ public class RoundedCorners implements Parcelable {
        }
        if (o instanceof RoundedCorners) {
            RoundedCorners r = (RoundedCorners) o;
            return Arrays.deepEquals(mRoundedCorners, ((RoundedCorners) o).mRoundedCorners);
            return Arrays.deepEquals(mRoundedCorners, r.mRoundedCorners);
        }
        return false;
    }
+12 −31
Original line number Diff line number Diff line
@@ -673,10 +673,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    // Used in updating override configurations
    private final Configuration mTempConfig = new Configuration();

    // 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
     * {@link #ensureActivitiesVisible(ActivityRecord, int, boolean, boolean)}
@@ -778,13 +774,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                    + " parentHidden=" + w.isParentWindowHidden());
        }

        // 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 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").
@@ -818,16 +807,8 @@ 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
@@ -2511,8 +2492,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp

    void onDisplayInfoChanged() {
        final DisplayInfo info = mDisplayInfo;
        mDisplayFrames.onDisplayInfoUpdated(info, calculateDisplayCutoutForRotation(info.rotation),
                calculateRoundedCornersForRotation(info.rotation));
        if (mDisplayFrames.onDisplayInfoUpdated(info,
                calculateDisplayCutoutForRotation(info.rotation),
                calculateRoundedCornersForRotation(info.rotation))) {
            // TODO(b/161810301): Set notifyInsetsChange to true while the server no longer performs
            //                    layout.
            mInsetsStateController.onDisplayInfoUpdated(false /* notifyInsetsChange */);
        }
        mInputMonitor.layoutInputConsumers(info.logicalWidth, info.logicalHeight);
        mDisplayPolicy.onDisplayInfoChanged(info);
    }
@@ -3767,8 +3753,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        // 2. Assign window layers based on the IME surface parent to make sure it is on top of the
        // app.
        assignWindowLayers(true /* setLayoutNeeded */);
        // 3. Update the IME control target to apply any inset change and animation.
        // 4. Reparent the IME container surface to either the input target app, or the IME window
        // 3. The z-order of IME might have been changed. Update the above insets state.
        mInsetsStateController.updateAboveInsetsState(
                mInputMethodWindow, true /* notifyInsetsChange */);
        // 4. Update the IME control target to apply any inset change and animation.
        // 5. Reparent the IME container surface to either the input target app, or the IME window
        // parent.
        updateImeControlTarget();
    }
@@ -4341,14 +4330,6 @@ 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;
+15 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static android.view.InsetsState.ITYPE_LEFT_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_RIGHT_DISPLAY_CUTOUT;
import static android.view.InsetsState.ITYPE_TOP_DISPLAY_CUTOUT;

import android.annotation.NonNull;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayCutout;
@@ -70,25 +71,28 @@ public class DisplayFrames {
     * @param info the updated {@link DisplayInfo}.
     * @param displayCutout the updated {@link DisplayCutout}.
     * @param roundedCorners the updated {@link RoundedCorners}.
     * @return {@code true} if the insets state has been changed; {@code false} otherwise.
     */
    public void onDisplayInfoUpdated(DisplayInfo info, WmDisplayCutout displayCutout,
            RoundedCorners roundedCorners) {
        mDisplayWidth = info.logicalWidth;
        mDisplayHeight = info.logicalHeight;
    public boolean onDisplayInfoUpdated(DisplayInfo info, @NonNull WmDisplayCutout displayCutout,
            @NonNull RoundedCorners roundedCorners) {
        mRotation = info.rotation;
        final WmDisplayCutout wmDisplayCutout =
                displayCutout != null ? displayCutout : WmDisplayCutout.NO_CUTOUT;

        final InsetsState state = mInsetsState;
        final Rect unrestricted = mUnrestricted;
        final Rect safe = mDisplayCutoutSafe;
        final DisplayCutout cutout = wmDisplayCutout.getDisplayCutout();
        final DisplayCutout cutout = displayCutout.getDisplayCutout();
        if (mDisplayWidth == info.logicalWidth && mDisplayHeight == info.logicalHeight
                && state.getDisplayCutout().equals(cutout)
                && state.getRoundedCorners().equals(roundedCorners)) {
            return false;
        }
        mDisplayWidth = info.logicalWidth;
        mDisplayHeight = info.logicalHeight;
        final Rect unrestricted = mUnrestricted;
        unrestricted.set(0, 0, mDisplayWidth, mDisplayHeight);
        safe.set(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
        state.setDisplayFrame(unrestricted);
        state.setDisplayCutout(cutout);
        state.setRoundedCorners(roundedCorners != null ? roundedCorners
                : RoundedCorners.NO_ROUNDED_CORNERS);
        state.setRoundedCorners(roundedCorners);
        if (!cutout.isEmpty()) {
            if (cutout.getSafeInsetLeft() > 0) {
                safe.left = unrestricted.left + cutout.getSafeInsetLeft();
@@ -116,6 +120,7 @@ public class DisplayFrames {
            state.removeSource(ITYPE_RIGHT_DISPLAY_CUTOUT);
            state.removeSource(ITYPE_BOTTOM_DISPLAY_CUTOUT);
        }
        return true;
    }

    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
+73 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.ITYPE_INVALID;
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.mandatorySystemGestures;
import static android.view.WindowInsets.Type.systemGestures;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
@@ -293,6 +296,76 @@ class InsetsStateController {
        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
    }

    /**
     * Updates {@link WindowState#mAboveInsetsState} for all windows in the display while the
     * z-order of a window is changed.
     *
     * @param win The window whose z-order has changed.
     * @param notifyInsetsChange {@code true} if the clients should be notified about the change.
     */
    void updateAboveInsetsState(WindowState win, boolean notifyInsetsChange) {
        if (win == null || win.getDisplayContent() != mDisplayContent) {
            return;
        }
        final boolean[] aboveWin = { true };
        final InsetsState aboveInsetsState = new InsetsState();
        aboveInsetsState.set(mState,
                displayCutout() | systemGestures() | mandatorySystemGestures());
        final SparseArray<InsetsSource> winProvidedSources = win.mProvidedInsetsSources;
        final ArrayList<WindowState> insetsChangedWindows = new ArrayList<>();
        mDisplayContent.forAllWindows(w -> {
            if (aboveWin[0]) {
                if (w == win) {
                    aboveWin[0] = false;
                    if (!win.mAboveInsetsState.equals(aboveInsetsState)) {
                        win.mAboveInsetsState.set(aboveInsetsState);
                        insetsChangedWindows.add(win);
                    }
                    return winProvidedSources.size() == 0;
                } else {
                    final SparseArray<InsetsSource> providedSources = w.mProvidedInsetsSources;
                    for (int i = providedSources.size() - 1; i >= 0; i--) {
                        aboveInsetsState.addSource(providedSources.valueAt(i));
                    }
                    if (winProvidedSources.size() == 0) {
                        return false;
                    }
                    boolean changed = false;
                    for (int i = winProvidedSources.size() - 1; i >= 0; i--) {
                        changed |= w.mAboveInsetsState.removeSource(winProvidedSources.keyAt(i));
                    }
                    if (changed) {
                        insetsChangedWindows.add(w);
                    }
                }
            } else {
                for (int i = winProvidedSources.size() - 1; i >= 0; i--) {
                    w.mAboveInsetsState.addSource(winProvidedSources.valueAt(i));
                }
                insetsChangedWindows.add(w);
            }
            return false;
        }, true /* traverseTopToBottom */);
        if (notifyInsetsChange) {
            for (int i = insetsChangedWindows.size() - 1; i >= 0; i--) {
                mDispatchInsetsChanged.accept(insetsChangedWindows.get(i));
            }
        }
    }

    void onDisplayInfoUpdated(boolean notifyInsetsChange) {
        final ArrayList<WindowState> insetsChangedWindows = new ArrayList<>();
        mDisplayContent.forAllWindows(w -> {
            w.mAboveInsetsState.set(mState, displayCutout());
            insetsChangedWindows.add(w);
        }, true /* traverseTopToBottom */);
        if (notifyInsetsChange) {
            for (int i = insetsChangedWindows.size() - 1; i >= 0; i--) {
                mDispatchInsetsChanged.accept(insetsChangedWindows.get(i));
            }
        }
    }

    void onInsetsModified(InsetsControlTarget caller) {
        boolean changed = false;
        for (int i = mProviders.size() - 1; i >= 0; i--) {
Loading