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

Commit d5a01599 authored by Winson Chung's avatar Winson Chung
Browse files

Fixing issue where PIP did not stay minimized after rotation.

- Ensure that we reapply the minimized offset after applying the snap
  fraction to the rotated bounds
- Fixing small issue where we weren't bottom aligning the PIP when the
  visible IME changes size (but is not made invisible)
- Also fixing an issue where the touch gesture continually allowed
  swiping offscreen even after dragging the PIP a distance. Now, if no
  gesture handles the drag, then the default gesture will disallow
  offscreen dragging once it handles the move.
- Shrinking PIP slightly to fit proportions of screen.

Test: Enable minimization in SysUI tuner, put PIP into minimized state,
      rotate the screen.  This is not final UX and the CTS tests will
      be updated to reflect this behavior once it is final.

Change-Id: I15c851a0bcf5f867289bc5ad50d298f82a103308
parent a4438c49
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -41,8 +41,12 @@ public class PipSnapAlgorithm {
    // Allows snapping to anywhere along the edge of the screen
    private static final int SNAP_MODE_EDGE = 2;

    // The friction multiplier to control how slippery the PIP is when flung
    private static final float SCROLL_FRICTION_MULTIPLIER = 8f;

    // The fraction of the stack width to show when minimized
    private static final float MINIMIZED_VISIBLE_FRACTION = 0.25f;

    private final Context mContext;

    private final ArrayList<Integer> mSnapGravities = new ArrayList<>();
@@ -121,6 +125,18 @@ public class PipSnapAlgorithm {
        return newBounds;
    }

    /**
     * Applies the offset to the {@param stackBounds} to adjust it to a minimized state.
     */
    public void applyMinimizedOffset(Rect stackBounds, Rect movementBounds, Point displaySize) {
        int visibleWidth = (int) (MINIMIZED_VISIBLE_FRACTION * stackBounds.width());
        if (stackBounds.left <= movementBounds.centerX()) {
            stackBounds.offsetTo(-stackBounds.width() + visibleWidth, stackBounds.top);
        } else {
            stackBounds.offsetTo(displaySize.x - visibleWidth, stackBounds.top);
        }
    }

    /**
     * @return returns a fraction that describes where along the {@param movementBounds} the
     *         {@param stackBounds} are. If the {@param stackBounds} are not currently on the
+2 −2
Original line number Diff line number Diff line
@@ -2492,11 +2492,11 @@

    <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
         These values are in DPs and will be converted to pixel sizes internally. -->
    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">10x10</string>
    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">8x8</string>

    <!-- Max default size [WIDTHxHEIGHT] on screen for picture-in-picture windows to fit inside.
         These values are in DPs and will be converted to pixel sizes internally. -->
    <string translatable="false" name="config_defaultPictureInPictureSize">216x135</string>
    <string translatable="false" name="config_defaultPictureInPictureSize">192x120</string>

    <!-- The default gravity for the picture-in-picture window.
         Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
+13 −12
Original line number Diff line number Diff line
@@ -71,8 +71,6 @@ public class PipTouchHandler implements TunerService.Tunable {
    private static final int EXPAND_STACK_DURATION = 225;
    private static final int MINIMIZE_STACK_MAX_DURATION = 200;

    // The fraction of the stack width to show when minimized
    private static final float MINIMIZED_VISIBLE_FRACTION = 0.25f;
    // The fraction of the stack width that the user has to drag offscreen to minimize the PIP
    private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.15f;
    // The fraction of the stack width that the user has to move when flinging to dismiss the PIP
@@ -396,6 +394,8 @@ public class PipTouchHandler implements TunerService.Tunable {
     * Flings the minimized PIP to the closest minimized snap target.
     */
    private void flingToMinimizedSnapTarget(float velocityY) {
        // We currently only allow flinging the minimized stack up and down, so just lock the
        // movement bounds to the current stack bounds horizontally
        Rect movementBounds = new Rect(mPinnedStackBounds.left, mBoundedPinnedStackBounds.top,
                mPinnedStackBounds.left, mBoundedPinnedStackBounds.bottom);
        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(movementBounds, mPinnedStackBounds,
@@ -414,16 +414,11 @@ public class PipTouchHandler implements TunerService.Tunable {
     * Animates the PIP to the minimized state, slightly offscreen.
     */
    private void animateToClosestMinimizedTarget() {
        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(mBoundedPinnedStackBounds,
                mPinnedStackBounds);
        Point displaySize = new Point();
        mContext.getDisplay().getRealSize(displaySize);
        int visibleWidth = (int) (MINIMIZED_VISIBLE_FRACTION * mPinnedStackBounds.width());
        if (mPinnedStackBounds.left < 0) {
            toBounds.offsetTo(-toBounds.width() + visibleWidth, toBounds.top);
        } else if (mPinnedStackBounds.right > displaySize.x) {
            toBounds.offsetTo(displaySize.x - visibleWidth, toBounds.top);
        }
        Rect toBounds = mSnapAlgorithm.findClosestSnapBounds(mBoundedPinnedStackBounds,
                mPinnedStackBounds);
        mSnapAlgorithm.applyMinimizedOffset(toBounds, mBoundedPinnedStackBounds, displaySize);
        mPinnedStackBoundsAnimator = mMotionHelper.createAnimationToBounds(mPinnedStackBounds,
                toBounds, MINIMIZE_STACK_MAX_DURATION, LINEAR_OUT_SLOW_IN,
                mUpdatePinnedStackBoundsListener);
@@ -635,7 +630,7 @@ public class PipTouchHandler implements TunerService.Tunable {
                    setMinimizedState(false);
                }

                if (isDraggingOffscreen) {
                if (touchState.allowDraggingOffscreen() && isDraggingOffscreen) {
                    // Move the pinned stack, but ignore the vertical movement
                    float left = mPinnedStackBounds.left + touchState.getLastTouchDelta().x;
                    mTmpBounds.set(mPinnedStackBounds);
@@ -685,7 +680,7 @@ public class PipTouchHandler implements TunerService.Tunable {
                    setMinimizedState(false);
                }

                if (isDraggingOffscreen) {
                if (touchState.allowDraggingOffscreen() && isDraggingOffscreen) {
                    // Move the pinned stack, but ignore the vertical movement
                    float left = mPinnedStackBounds.left + touchState.getLastTouchDelta().x;
                    mTmpBounds.set(mPinnedStackBounds);
@@ -769,6 +764,12 @@ public class PipTouchHandler implements TunerService.Tunable {
    private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() {
        @Override
        boolean onMove(PipTouchState touchState) {
            if (touchState.startedDragging()) {
                // For now, once the user has started a drag that the other gestures have not
                // intercepted, disallow those gestures from intercepting again to drag offscreen
                touchState.setDisallowDraggingOffscreen();
            }

            if (touchState.isDragging()) {
                // Move the pinned stack freely
                PointF lastDelta = touchState.getLastTouchDelta();
+16 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ public class PipTouchState {
    private final PointF mVelocity = new PointF();
    private boolean mIsDragging = false;
    private boolean mStartedDragging = false;
    private boolean mAllowDraggingOffscreen = false;
    private int mActivePointerId;

    public PipTouchState(ViewConfiguration viewConfig) {
@@ -59,6 +60,7 @@ public class PipTouchState {
                mDownTouch.set(mLastTouch);
                mIsDragging = false;
                mStartedDragging = false;
                mAllowDraggingOffscreen = true;
                break;
            }
            case MotionEvent.ACTION_MOVE: {
@@ -159,6 +161,20 @@ public class PipTouchState {
        return mStartedDragging;
    }

    /**
     * Disallows dragging offscreen for the duration of the current gesture.
     */
    public void setDisallowDraggingOffscreen() {
        mAllowDraggingOffscreen = false;
    }

    /**
     * @return whether dragging offscreen is allowed during this gesture.
     */
    public boolean allowDraggingOffscreen() {
        return mAllowDraggingOffscreen;
    }

    private void initOrResetVelocityTracker() {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
+12 −1
Original line number Diff line number Diff line
@@ -256,6 +256,12 @@ class PinnedStackController {
                    false /* adjustForIme */);
            mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
                    snapFraction);
            if (mIsMinimized) {
                final Point displaySize = new Point(mDisplayInfo.logicalWidth,
                        mDisplayInfo.logicalHeight);
                mSnapAlgorithm.applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds,
                        displaySize);
            }
        }
        return postChangeStackBounds;
    }
@@ -285,7 +291,12 @@ class PinnedStackController {
            final Rect toBounds = new Rect(stackBounds);
            if (adjustedForIme) {
                // IME visible
                if (stackBounds.top == prevMovementBounds.bottom) {
                    // If the PIP is resting on top of the IME, then adjust it with the hiding IME
                    toBounds.offsetTo(toBounds.left, movementBounds.bottom);
                } else {
                    toBounds.offset(0, Math.min(0, movementBounds.bottom - stackBounds.top));
                }
            } else {
                // IME hidden
                if (stackBounds.top == prevMovementBounds.bottom) {