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

Commit 2c0e01b2 authored by jorgegil@google.com's avatar jorgegil@google.com
Browse files

Don't save the default size as reentry state

Fixes issue where the "default" bounds of PIP can be calculated
differently even though the PIP has never been resized. This is
caused by a combination of changing the aspect ratio of PIP and
trying to restore the "reentry" state that is just the default
state.

Instead, we'll only calculate the PIP bounds using the reentry
size if the size was actually changed by the user, otherwise
we'll always calculate using the default size.

Bug: 169379707
Test: atest com.android.wm.shell.pip
Change-Id: I724b167870407f7f37eb9c8a587a98c7972441a4
parent 7344dac2
Loading
Loading
Loading
Loading
+31 −18
Original line number Diff line number Diff line
@@ -125,15 +125,16 @@ public class PipBoundsAlgorithm {
    /** Returns the destination bounds to place the PIP window on entry. */
    public Rect getEntryDestinationBounds() {
        final PipBoundsState.PipReentryState reentryState = mPipBoundsState.getReentryState();
        final boolean shouldRestoreReentryBounds = reentryState != null;

        final Rect destinationBounds = shouldRestoreReentryBounds
        final Rect destinationBounds = reentryState != null
                ? getDefaultBounds(reentryState.getSnapFraction(), reentryState.getSize())
                : getDefaultBounds();

        return transformBoundsToAspectRatioIfValid(destinationBounds,
        final boolean useCurrentSize = reentryState != null && reentryState.getSize() != null;
        final Rect r = transformBoundsToAspectRatioIfValid(destinationBounds,
                mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */,
                shouldRestoreReentryBounds);
                useCurrentSize);
        return r;
    }

    /** Returns the current bounds adjusted to the new aspect ratio, if valid. */
@@ -223,14 +224,18 @@ public class PipBoundsAlgorithm {
    private Rect getDefaultBounds(float snapFraction, Size size) {
        final Rect defaultBounds = new Rect();
        if (snapFraction != INVALID_SNAP_FRACTION && size != null) {
            // The default bounds are the given size positioned at the given snap fraction.
            defaultBounds.set(0, 0, size.getWidth(), size.getHeight());
            final Rect movementBounds = getMovementBounds(defaultBounds);
            mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction);
        } else {
            return defaultBounds;
        }

        // Calculate the default size.
        final Size defaultSize;
        final Rect insetBounds = new Rect();
        getInsetBounds(insetBounds);
        final DisplayInfo displayInfo = mPipBoundsState.getDisplayInfo();
            final Size defaultSize;
        final Size overrideMinSize = mPipBoundsState.getOverrideMinSize();
        if (overrideMinSize != null) {
            // The override minimal size is set, use that as the default size making sure it's
@@ -241,6 +246,14 @@ public class PipBoundsAlgorithm {
            defaultSize = getSizeForAspectRatio(mDefaultAspectRatio,
                    mDefaultMinSize, displayInfo.logicalWidth, displayInfo.logicalHeight);
        }

        // Now that we have the default size, apply the snap fraction if valid or position the
        // bounds using the default gravity.
        if (snapFraction != INVALID_SNAP_FRACTION) {
            defaultBounds.set(0, 0, defaultSize.getWidth(), defaultSize.getHeight());
            final Rect movementBounds = getMovementBounds(defaultBounds);
            mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction);
        } else {
            Gravity.apply(mDefaultStackGravity, defaultSize.getWidth(), defaultSize.getHeight(),
                    insetBounds, 0, Math.max(
                            mPipBoundsState.isImeShowing() ? mPipBoundsState.getImeHeight() : 0,
+18 −5
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ public final class PipBoundsState {
    private int mImeHeight;
    private boolean mIsShelfShowing;
    private int mShelfHeight;
    /** Whether the user has resized the PIP manually. */
    private boolean mHasUserResizedPip;

    private @Nullable Runnable mOnMinimalSizeChangeCallback;
    private @Nullable BiConsumer<Boolean, Integer> mOnShelfVisibilityChangeCallback;
@@ -189,8 +191,8 @@ public final class PipBoundsState {
    }

    /** Save the reentry state to restore to when re-entering PIP mode. */
    public void saveReentryState(@NonNull Rect bounds, float fraction) {
        mPipReentryState = new PipReentryState(new Size(bounds.width(), bounds.height()), fraction);
    public void saveReentryState(Size size, float fraction) {
        mPipReentryState = new PipReentryState(size, fraction);
    }

    /** Returns the saved reentry state. */
@@ -205,6 +207,7 @@ public final class PipBoundsState {
        mLastPipComponentName = lastPipComponentName;
        if (changed) {
            clearReentryState();
            setHasUserResizedPip(false);
        }
    }

@@ -329,6 +332,16 @@ public final class PipBoundsState {
        return mShelfHeight;
    }

    /** Returns whether the user has resized the PIP. */
    public boolean hasUserResizedPip() {
        return mHasUserResizedPip;
    }

    /** Set whether the user has resized the PIP. */
    public void setHasUserResizedPip(boolean hasUserResizedPip) {
        mHasUserResizedPip = hasUserResizedPip;
    }

    /**
     * Registers a callback when the minimal size of PIP that is set by the app changes.
     */
@@ -397,15 +410,15 @@ public final class PipBoundsState {
    static final class PipReentryState {
        private static final String TAG = PipReentryState.class.getSimpleName();

        private final @NonNull Size mSize;
        private final @Nullable Size mSize;
        private final float mSnapFraction;

        PipReentryState(@NonNull Size size, float snapFraction) {
        PipReentryState(@Nullable Size size, float snapFraction) {
            mSize = size;
            mSnapFraction = snapFraction;
        }

        @NonNull
        @Nullable
        Size getSize() {
            return mSize;
        }
+13 −13
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.WindowManagerGlobal;
@@ -85,7 +86,6 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac

    private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();
    private final Rect mTmpInsetBounds = new Rect();
    protected final Rect mReentryBounds = new Rect();

    private boolean mIsInFixedRotation;
    private Consumer<Boolean> mPinnedStackAnimationRecentsCallback;
@@ -437,10 +437,8 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
    @Override
    public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) {
        if (isOutPipDirection(direction)) {
            // Exiting PIP, save the reentry bounds to restore to when re-entering.
            updateReentryBounds(pipBounds);
            final float snapFraction = mPipBoundsAlgorithm.getSnapFraction(mReentryBounds);
            mPipBoundsState.saveReentryState(mReentryBounds, snapFraction);
            // Exiting PIP, save the reentry state to restore to when re-entering.
            saveReentryState(pipBounds);
        }
        // Disable touches while the animation is running
        mTouchHandler.setTouchEnabled(false);
@@ -449,14 +447,16 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
        }
    }

    /**
     * Update the bounds used to save the re-entry size and snap fraction when exiting PIP.
     */
    public void updateReentryBounds(Rect bounds) {
    /** Save the state to restore to on re-entry. */
    public void saveReentryState(Rect pipBounds) {
        float snapFraction = mPipBoundsAlgorithm.getSnapFraction(pipBounds);
        if (mPipBoundsState.hasUserResizedPip()) {
            final Rect reentryBounds = mTouchHandler.getUserResizeBounds();
        float snapFraction = mPipBoundsAlgorithm.getSnapFraction(bounds);
        mPipBoundsAlgorithm.applySnapFraction(reentryBounds, snapFraction);
        mReentryBounds.set(reentryBounds);
            final Size reentrySize = new Size(reentryBounds.width(), reentryBounds.height());
            mPipBoundsState.saveReentryState(reentrySize, snapFraction);
        } else {
            mPipBoundsState.saveReentryState(null /* bounds */, snapFraction);
        }
    }

    /**
+2 −0
Original line number Diff line number Diff line
@@ -409,6 +409,7 @@ public class PipResizeGestureHandler {

                mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
                        null);
                mPipBoundsState.setHasUserResizedPip(true);
            }
        }
    }
@@ -461,6 +462,7 @@ public class PipResizeGestureHandler {
                                true /* useCurrentSize */);
                        mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
                                null);
                        mPipBoundsState.setHasUserResizedPip(true);
                    }
                    break;
                case MotionEvent.ACTION_UP:
+4 −2
Original line number Diff line number Diff line
@@ -337,7 +337,8 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
        reentryBounds.scale(1.25f);
        final float reentrySnapFraction = mPipBoundsAlgorithm.getSnapFraction(reentryBounds);

        mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction);
        mPipBoundsState.saveReentryState(
                new Size(reentryBounds.width(), reentryBounds.height()), reentrySnapFraction);
        final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();

        assertEquals(reentryBounds.width(), destinationBounds.width());
@@ -351,7 +352,8 @@ public class PipBoundsAlgorithmTest extends ShellTestCase {
        reentryBounds.offset(0, -100);
        final float reentrySnapFraction = mPipBoundsAlgorithm.getSnapFraction(reentryBounds);

        mPipBoundsState.saveReentryState(reentryBounds, reentrySnapFraction);
        mPipBoundsState.saveReentryState(
                new Size(reentryBounds.width(), reentryBounds.height()), reentrySnapFraction);

        final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds();

Loading