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

Commit 6db481e0 authored by shawnlin's avatar shawnlin
Browse files

Fixed cts failure of WindowInsetsControllerTests

If the device is a tablet, the navigation bar will be taskbar, and it
will draw fake rounded corners above itself when it's shown and
unstashed. When apps request to hide taskbar from such state, it will
cause an extra window insets change from server side.

Move the calculation of rounded corner inset to client side so that we
can make the window insets change come only once.

Bug: 229825307
Test: atest WindowInsetsControllerTests ActivityRecordTests
Change-Id: I081142facbe0fe676b89c8883fa690ba5ae13d79
parent 5c554e28
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ public class InsetsSource implements Parcelable {
    private final Rect mFrame;
    private @Nullable Rect mVisibleFrame;
    private boolean mVisible;
    private boolean mInsetsRoundedCornerFrame;

    private final Rect mTmpFrame = new Rect();

@@ -63,6 +64,7 @@ public class InsetsSource implements Parcelable {
        mVisibleFrame = other.mVisibleFrame != null
                ? new Rect(other.mVisibleFrame)
                : null;
        mInsetsRoundedCornerFrame = other.mInsetsRoundedCornerFrame;
    }

    public void set(InsetsSource other) {
@@ -71,6 +73,7 @@ public class InsetsSource implements Parcelable {
        mVisibleFrame = other.mVisibleFrame != null
                ? new Rect(other.mVisibleFrame)
                : null;
        mInsetsRoundedCornerFrame = other.mInsetsRoundedCornerFrame;
    }

    public void setFrame(int left, int top, int right, int bottom) {
@@ -110,6 +113,14 @@ public class InsetsSource implements Parcelable {
        return mVisibleFrame == null || !mVisibleFrame.isEmpty();
    }

    public boolean getInsetsRoundedCornerFrame() {
        return mInsetsRoundedCornerFrame;
    }

    public void setInsetsRoundedCornerFrame(boolean insetsRoundedCornerFrame) {
        mInsetsRoundedCornerFrame = insetsRoundedCornerFrame;
    }

    /**
     * Calculates the insets this source will cause to a client window.
     *
@@ -225,6 +236,7 @@ public class InsetsSource implements Parcelable {
            pw.print(" visibleFrame="); pw.print(mVisibleFrame.toShortString());
        }
        pw.print(" visible="); pw.print(mVisible);
        pw.print(" insetsRoundedCornerFrame="); pw.print(mInsetsRoundedCornerFrame);
        pw.println();
    }

@@ -247,6 +259,7 @@ public class InsetsSource implements Parcelable {
        if (mVisible != that.mVisible) return false;
        if (excludeInvisibleImeFrames && !mVisible && mType == ITYPE_IME) return true;
        if (!Objects.equals(mVisibleFrame, that.mVisibleFrame)) return false;
        if (mInsetsRoundedCornerFrame != that.mInsetsRoundedCornerFrame) return false;
        return mFrame.equals(that.mFrame);
    }

@@ -256,6 +269,7 @@ public class InsetsSource implements Parcelable {
        result = 31 * result + mFrame.hashCode();
        result = 31 * result + (mVisibleFrame != null ? mVisibleFrame.hashCode() : 0);
        result = 31 * result + (mVisible ? 1 : 0);
        result = 31 * result + (mInsetsRoundedCornerFrame ? 1 : 0);
        return result;
    }

@@ -268,6 +282,7 @@ public class InsetsSource implements Parcelable {
            mVisibleFrame = null;
        }
        mVisible = in.readBoolean();
        mInsetsRoundedCornerFrame = in.readBoolean();
    }

    @Override
@@ -286,6 +301,7 @@ public class InsetsSource implements Parcelable {
            dest.writeInt(0);
        }
        dest.writeBoolean(mVisible);
        dest.writeBoolean(mInsetsRoundedCornerFrame);
    }

    @Override
@@ -294,6 +310,7 @@ public class InsetsSource implements Parcelable {
                + "mType=" + InsetsState.typeToString(mType)
                + ", mFrame=" + mFrame.toShortString()
                + ", mVisible=" + mVisible
                + ", mInsetsRoundedCornerFrame=" + mInsetsRoundedCornerFrame
                + "}";
    }

+10 −3
Original line number Diff line number Diff line
@@ -294,9 +294,16 @@ public class InsetsState implements Parcelable {
            return RoundedCorners.NO_ROUNDED_CORNERS;
        }
        // If mRoundedCornerFrame is set, we should calculate the new RoundedCorners based on this
        // frame. It's used for split-screen mode and devices with a task bar.
        if (!mRoundedCornerFrame.isEmpty() && !mRoundedCornerFrame.equals(mDisplayFrame)) {
            return mRoundedCorners.insetWithFrame(frame, mRoundedCornerFrame);
        // frame.
        final Rect roundedCornerFrame = new Rect(mRoundedCornerFrame);
        for (InsetsSource source : mSources) {
            if (source != null && source.getInsetsRoundedCornerFrame()) {
                final Insets insets = source.calculateInsets(roundedCornerFrame, false);
                roundedCornerFrame.inset(insets);
            }
        }
        if (!roundedCornerFrame.isEmpty() && !roundedCornerFrame.equals(mDisplayFrame)) {
            return mRoundedCorners.insetWithFrame(frame, roundedCornerFrame);
        }
        if (mDisplayFrame.equals(frame)) {
            return mRoundedCorners;
+4 −21
Original line number Diff line number Diff line
@@ -300,10 +300,6 @@ public class DisplayPolicy {
    // needs to be opaque.
    private WindowState mNavBarBackgroundWindow;

    // The window that draws fake rounded corners and should provide insets to calculate the correct
    // rounded corner insets.
    private WindowState mRoundedCornerWindow;

    /**
     * A collection of {@link AppearanceRegion} to indicate that which region of status bar applies
     * which appearance.
@@ -970,16 +966,10 @@ public class DisplayPolicy {
            mExtraNavBarAltPosition = getAltBarPosition(attrs);
        }

        if (attrs.insetsRoundedCornerFrame) {
            // Currently, only support one rounded corner window which is the TaskBar.
            if (mRoundedCornerWindow != null && mRoundedCornerWindow != win) {
                throw new IllegalArgumentException("Found multiple rounded corner window :"
                        + " current = " + mRoundedCornerWindow
                        + " new = " + win);
            }
            mRoundedCornerWindow = win;
        } else if (mRoundedCornerWindow == win) {
            mRoundedCornerWindow = null;
        final InsetsSourceProvider provider = win.getControllableInsetProvider();
        if (provider != null && provider.getSource().getInsetsRoundedCornerFrame()
                != attrs.insetsRoundedCornerFrame) {
            provider.getSource().setInsetsRoundedCornerFrame(attrs.insetsRoundedCornerFrame);
        }
    }

@@ -1326,9 +1316,6 @@ public class DisplayPolicy {
        if (mLastFocusedWindow == win) {
            mLastFocusedWindow = null;
        }
        if (mRoundedCornerWindow == win) {
            mRoundedCornerWindow = null;
        }

        mInsetsSourceWindowsExceptIme.remove(win);
    }
@@ -1360,10 +1347,6 @@ public class DisplayPolicy {
        return mNavigationBar != null ? mNavigationBar : mNavigationBarAlt;
    }

    WindowState getRoundedCornerWindow() {
        return mRoundedCornerWindow;
    }

    /**
     * Control the animation to run when a window's state changes.  Return a positive number to
     * force the animation to a specific resource ID, {@link #ANIMATION_STYLEABLE} to use the
+2 −15
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.app.StatusBarManager;
import android.app.WindowConfiguration;
import android.graphics.Insets;
import android.graphics.Rect;
import android.util.ArrayMap;
import android.util.IntArray;
@@ -461,22 +460,10 @@ class InsetsPolicy {

    private InsetsState adjustInsetsForRoundedCorners(WindowState w, InsetsState originalState,
            boolean copyState) {
        final WindowState roundedCornerWindow = mPolicy.getRoundedCornerWindow();
        final Task task = w.getTask();
        if (task != null && !task.getWindowConfiguration().tasksAreFloating()
                && (roundedCornerWindow != null || task.inSplitScreen())) {
            // Instead of using display frame to calculating rounded corner, for the fake rounded
            // corners drawn by divider bar or task bar, we need to re-calculate rounded corners
            // based on task bounds and if the task bounds is intersected with task bar, we should
            // exclude the intersected part.
        if (task != null && !task.getWindowConfiguration().tasksAreFloating()) {
            // Use task bounds to calculating rounded corners if the task is not floating.
            final Rect roundedCornerFrame = new Rect(task.getBounds());
            if (roundedCornerWindow != null
                    && roundedCornerWindow.getControllableInsetProvider() != null) {
                final InsetsSource source =
                        roundedCornerWindow.getControllableInsetProvider().getSource();
                final Insets insets = source.calculateInsets(roundedCornerFrame, false);
                roundedCornerFrame.inset(insets);
            }
            final InsetsState state = copyState ? new InsetsState(originalState) : originalState;
            state.setRoundedCornerFrame(roundedCornerFrame);
            return state;
+1 −0
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ abstract class InsetsSourceProvider {
        if (windowContainer == null) {
            setServerVisible(false);
            mSource.setVisibleFrame(null);
            mSource.setInsetsRoundedCornerFrame(false);
            mSourceFrame.setEmpty();
        } else {
            mWindowContainer.getProvidedInsetsSources().put(mSource.getType(), mSource);
Loading