From d5a01599f7c90db0cc9bb11e18883a18660a2a45 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 11 Nov 2016 16:25:04 -0800 Subject: [PATCH] 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 --- .../internal/policy/PipSnapAlgorithm.java | 16 ++++++++++++ core/res/res/values/config.xml | 4 +-- .../systemui/pip/phone/PipTouchHandler.java | 25 ++++++++++--------- .../systemui/pip/phone/PipTouchState.java | 16 ++++++++++++ .../server/wm/PinnedStackController.java | 13 +++++++++- 5 files changed, 59 insertions(+), 15 deletions(-) diff --git a/core/java/com/android/internal/policy/PipSnapAlgorithm.java b/core/java/com/android/internal/policy/PipSnapAlgorithm.java index 1e2a53ba97e46..62d506f781579 100644 --- a/core/java/com/android/internal/policy/PipSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/PipSnapAlgorithm.java @@ -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 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 diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 7005afe5b5f6a..996fd55f69bda 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2492,11 +2492,11 @@ - 10x10 + 8x8 - 216x135 + 192x120 diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index b24d19958f18e..c6dde4623ef39 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -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(); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java index 80af5a6c02680..17d9864e4d25c 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchState.java @@ -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(); diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java index c711b39aabaf9..01a50b7ef340d 100644 --- a/services/core/java/com/android/server/wm/PinnedStackController.java +++ b/services/core/java/com/android/server/wm/PinnedStackController.java @@ -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 - toBounds.offset(0, Math.min(0, movementBounds.bottom - stackBounds.top)); + 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) {