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

Commit d1bd9998 authored by Ben Lin's avatar Ben Lin Committed by Android (Google) Code Review
Browse files

Merge "PiP: Consider stash state when calculating snap fraction."

parents eb98ccbe e2409781
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -256,7 +256,8 @@ public class PipBoundsHandler {

        // Calculate the snap fraction of the current stack along the old movement bounds
        final Rect postChangeStackBounds = new Rect(oldBounds);
        final float snapFraction = getSnapFraction(postChangeStackBounds);
        final float snapFraction = mSnapAlgorithm.getSnapFraction(postChangeStackBounds,
                getMovementBounds(postChangeStackBounds), mPipBoundsState.getStashedState());

        // Update the display layout
        mPipBoundsState.getDisplayLayout().rotateTo(context.getResources(), toRotation);
@@ -273,7 +274,8 @@ public class PipBoundsHandler {
        final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
                false /* adjustForIme */);
        mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
                snapFraction);
                snapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(),
                mPipBoundsState.getDisplayBounds());

        getInsetBounds(outInsetBounds);
        outBounds.set(postChangeStackBounds);
@@ -321,7 +323,7 @@ public class PipBoundsHandler {
            boolean useCurrentMinEdgeSize, boolean useCurrentSize) {
        // Save the snap fraction and adjust the size based on the new aspect ratio.
        final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
                getMovementBounds(stackBounds));
                getMovementBounds(stackBounds), mPipBoundsState.getStashedState());
        final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
        final Size size;
        if (useCurrentMinEdgeSize || useCurrentSize) {
+58 −6
Original line number Diff line number Diff line
@@ -16,34 +16,70 @@

package com.android.wm.shell.pip;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Rect;
import android.util.Size;
import android.view.DisplayInfo;

import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * Singleton source of truth for the current state of PIP bounds.
 */
public final class PipBoundsState {
    public static final int STASH_TYPE_NONE = 0;
    public static final int STASH_TYPE_LEFT = 1;
    public static final int STASH_TYPE_RIGHT = 2;

    @IntDef(prefix = { "STASH_TYPE_" }, value =  {
            STASH_TYPE_NONE,
            STASH_TYPE_LEFT,
            STASH_TYPE_RIGHT
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface StashType {}

    private static final String TAG = PipBoundsState.class.getSimpleName();

    private final @NonNull Rect mBounds = new Rect();
    private final Context mContext;
    private float mAspectRatio;
    private boolean mIsStashed;
    private int mStashedState = STASH_TYPE_NONE;
    private int mStashOffset;
    private PipReentryState mPipReentryState;
    private ComponentName mLastPipComponentName;
    private final DisplayInfo mDisplayInfo = new DisplayInfo();
    private final DisplayLayout mDisplayLayout = new DisplayLayout();
    private final @NonNull AnimatingBoundsState mAnimatingBoundsState = new AnimatingBoundsState();

    public PipBoundsState(Context context) {
        mContext = context;
        reloadResources();
    }

    /**
     * Reloads the resources.
     */
    public void onConfigurationChanged() {
        reloadResources();
    }

    private void reloadResources() {
        mStashOffset = mContext.getResources()
                .getDimensionPixelSize(R.dimen.pip_stash_offset);
    }

    /**
     * Set the current PIP bounds.
     */
@@ -57,17 +93,32 @@ public final class PipBoundsState {
    }

    /**
     * Dictate where PiP currently should be stashed or not.
     * Dictate where PiP currently should be stashed, if at all.
     */
    public void setStashed(boolean isStashed) {
        mIsStashed = isStashed;
    public void setStashed(@StashType int stashedState) {
        mStashedState = stashedState;
    }

    /**
     * Return where the PiP is stashed, if at all.
     * @return {@code STASH_NONE}, {@code STASH_LEFT} or {@code STASH_RIGHT}.
     */
    public @StashType int getStashedState() {
        return mStashedState;
    }

    /**
     * Whether PiP is stashed or not.
     */
    public boolean isStashed() {
        return mIsStashed;
        return mStashedState != STASH_TYPE_NONE;
    }

    /**
     * Returns the offset from the edge of the screen for PiP stash.
     */
    public int getStashOffset() {
        return mStashOffset;
    }

    public void setAspectRatio(float aspectRatio) {
@@ -245,7 +296,8 @@ public final class PipBoundsState {
        pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio);
        pw.println(innerPrefix + "mDisplayInfo=" + mDisplayInfo);
        pw.println(innerPrefix + "mDisplayLayout=" + mDisplayLayout);
        pw.println(innerPrefix + "mIsStashed=" + mIsStashed);
        pw.println(innerPrefix + "mStashedState=" + mStashedState);
        pw.println(innerPrefix + "mStashOffset=" + mStashOffset);
        if (mPipReentryState == null) {
            pw.println(innerPrefix + "mPipReentryState=null");
        } else {
+45 −6
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.wm.shell.pip;

import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_LEFT;
import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE;
import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.PointF;
@@ -41,10 +45,21 @@ public class PipSnapAlgorithm {
        mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
    }

    /**
     * Returns a fraction that describes where the PiP bounds is.
     * See {@link #getSnapFraction(Rect, Rect, int)}.
     */
    public float getSnapFraction(Rect stackBounds, Rect movementBounds) {
        return getSnapFraction(stackBounds, movementBounds, STASH_TYPE_NONE);
    }

    /**
     * @return returns a fraction that describes where along the {@param movementBounds} the
     *         {@param stackBounds} are. If the {@param stackBounds} are not currently on the
     *         {@param movementBounds} exactly, then they will be snapped to the movement bounds.
     *         stashType dictates whether the PiP is stashed (off-screen) or not. If
     *         that's the case, we will have to do some math to calculate the snap fraction
     *         correctly.
     *
     *         The fraction is defined in a clockwise fashion against the {@param movementBounds}:
     *
@@ -54,9 +69,10 @@ public class PipSnapAlgorithm {
     *          3 +---+ 2
     *            3   2
     */
    public float getSnapFraction(Rect stackBounds, Rect movementBounds) {
    public float getSnapFraction(Rect stackBounds, Rect movementBounds,
            @PipBoundsState.StashType int stashType) {
        final Rect tmpBounds = new Rect();
        snapRectToClosestEdge(stackBounds, movementBounds, tmpBounds);
        snapRectToClosestEdge(stackBounds, movementBounds, tmpBounds, stashType);
        final float widthFraction = (float) (tmpBounds.left - movementBounds.left) /
                movementBounds.width();
        final float heightFraction = (float) (tmpBounds.top - movementBounds.top) /
@@ -103,6 +119,22 @@ public class PipSnapAlgorithm {
        }
    }

    /**
     * Same as {@link #applySnapFraction(Rect, Rect, float)}, but take stash state into
     * consideration.
     */
    public void applySnapFraction(Rect stackBounds, Rect movementBounds, float snapFraction,
            @PipBoundsState.StashType int stashType, int stashOffset, Rect displayBounds) {
        applySnapFraction(stackBounds, movementBounds, snapFraction);

        if (stashType != STASH_TYPE_NONE) {
            stackBounds.offsetTo(stashType == STASH_TYPE_LEFT
                            ? stashOffset - stackBounds.width()
                            : displayBounds.right - stashOffset,
                    stackBounds.top);
        }
    }

    /**
     * Adjusts {@param movementBoundsOut} so that it is the movement bounds for the given
     * {@param stackBounds}.
@@ -178,17 +210,24 @@ public class PipSnapAlgorithm {
     * Snaps the {@param stackBounds} to the closest edge of the {@param movementBounds} and writes
     * the new bounds out to {@param boundsOut}.
     */
    public void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut) {
    public void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut,
            @PipBoundsState.StashType int stashType) {
        int leftEdge = stackBounds.left;
        if (stashType == STASH_TYPE_LEFT) {
            leftEdge = movementBounds.left;
        } else if (stashType == STASH_TYPE_RIGHT) {
            leftEdge = movementBounds.right;
        }
        final int boundedLeft = Math.max(movementBounds.left, Math.min(movementBounds.right,
                stackBounds.left));
                leftEdge));
        final int boundedTop = Math.max(movementBounds.top, Math.min(movementBounds.bottom,
                stackBounds.top));
        boundsOut.set(stackBounds);

        // Otherwise, just find the closest edge
        final int fromLeft = Math.abs(stackBounds.left - movementBounds.left);
        final int fromLeft = Math.abs(leftEdge - movementBounds.left);
        final int fromTop = Math.abs(stackBounds.top - movementBounds.top);
        final int fromRight = Math.abs(movementBounds.right - stackBounds.left);
        final int fromRight = Math.abs(movementBounds.right - leftEdge);
        final int fromBottom = Math.abs(movementBounds.bottom - stackBounds.top);
        final int shortest = Math.min(Math.min(fromLeft, fromRight), Math.min(fromTop, fromBottom));
        if (shortest == fromLeft) {
+1 −0
Original line number Diff line number Diff line
@@ -196,6 +196,7 @@ public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallbac
            mMainExecutor.execute(() -> {
                mPipBoundsHandler.onConfigurationChanged(mContext);
                mTouchHandler.onConfigurationChanged();
                mPipBoundsState.onConfigurationChanged();
            });
        }

+16 −16
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.wm.shell.pip.phone;

import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_LEFT;
import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -33,7 +36,6 @@ import androidx.dynamicanimation.animation.AnimationHandler;
import androidx.dynamicanimation.animation.AnimationHandler.FrameCallbackScheduler;
import androidx.dynamicanimation.animation.SpringForce;

import com.android.wm.shell.R;
import com.android.wm.shell.animation.FloatProperties;
import com.android.wm.shell.animation.PhysicsAnimator;
import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -79,8 +81,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
    /** The region that all of PIP must stay within. */
    private final Rect mFloatingAllowedArea = new Rect();

    private int mStashOffset = 0;

    /** Coordinator instance for resolving conflicts with other floating content. */
    private FloatingContentCoordinator mFloatingContentCoordinator;

@@ -179,8 +179,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        mTemporaryBoundsPhysicsAnimator.setCustomAnimationHandler(
                mSfAnimationHandlerThreadLocal.get());

        reloadResources();

        mResizePipUpdateListener = (target, values) -> {
            if (mPipBoundsState.getAnimatingBoundsState().isAnimating()) {
                mPipTaskOrganizer.scheduleUserResizePip(getBounds(),
@@ -189,11 +187,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        };
    }

    void reloadResources() {
        mStashOffset = mContext.getResources()
                .getDimensionPixelSize(R.dimen.pip_stash_offset);
    }

    @NonNull
    @Override
    public Rect getFloatingBoundsOnScreen() {
@@ -380,6 +373,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
     */
    void stashToEdge(
            float velocityX, float velocityY, @Nullable Runnable endAction) {
        mPipBoundsState.setStashed(velocityX < 0 ? STASH_TYPE_LEFT : STASH_TYPE_RIGHT);
        movetoTarget(velocityX, velocityY, endAction, true /* isStash */);
    }

@@ -399,9 +393,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
                        FloatProperties.RECT_Y, velocityY, mFlingConfigY, mSpringConfig)
                .withEndActions(endAction);

        final float leftEdge = isStash ? mStashOffset - mPipBoundsState.getBounds().width()
        final float leftEdge = isStash
                ? mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width()
                : mMovementBounds.left;
        final float rightEdge = isStash ?  mPipBoundsState.getDisplayBounds().right - mStashOffset
        final float rightEdge = isStash
                ?  mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset()
                : mMovementBounds.right;

        final float xEndValue = velocityX < 0 ? leftEdge : rightEdge;
@@ -471,9 +467,12 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        if (savedSnapFraction < 0f) {
            // If there are no saved snap fractions, then just use the current bounds
            savedSnapFraction = mSnapAlgorithm.getSnapFraction(new Rect(getBounds()),
                    currentMovementBounds);
                    currentMovementBounds, mPipBoundsState.getStashedState());
        }
        mSnapAlgorithm.applySnapFraction(normalBounds, normalMovementBounds, savedSnapFraction);

        mSnapAlgorithm.applySnapFraction(normalBounds, normalMovementBounds, savedSnapFraction,
                mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(),
                mPipBoundsState.getDisplayBounds());

        if (immediate) {
            movePip(normalBounds);
@@ -512,8 +511,9 @@ public class PipMotionHelper implements PipAppOpsListener.Callback,
        mFlingConfigY = new PhysicsAnimator.FlingConfig(
                DEFAULT_FRICTION, mMovementBounds.top, mMovementBounds.bottom);
        mStashConfigX = new PhysicsAnimator.FlingConfig(
                DEFAULT_FRICTION, mStashOffset - mPipBoundsState.getBounds().width(),
                mPipBoundsState.getDisplayBounds().right - mStashOffset);
                DEFAULT_FRICTION,
                mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width(),
                mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset());
    }

    /**
Loading