From 2fbdd3bfde12c6755e184208730cfb76e3066741 Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Tue, 21 Mar 2017 17:45:00 -0700 Subject: [PATCH] Fix PiP dismissing on drag away from bottom and then fling Adds two flags to watch for movement outside of the starting area of the gesture, one for dismissing and one for minimizing. Test: - Have PiP at bottom of screen, drag to top and fling down (does not dismiss) - Have PiP at left or right edge of screen, drag PiP to opposite edge and fling to other side (no longer minimizes) Bug: 35358628 Change-Id: I007e2c2c688254dbe1abaecdedc28e281278def8 --- .../systemui/pip/phone/PipTouchHandler.java | 72 +++++++++------------- 1 file changed, 30 insertions(+), 42 deletions(-) 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 f70d5b41ac3e..b689a8504149 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -104,6 +104,8 @@ public class PipTouchHandler { private int mImeHeight; private float mSavedSnapFraction = -1f; private boolean mSendingHoverAccessibilityEvents; + private boolean mMovementWithinMinimize; + private boolean mMovementWithinDismiss; // Touch state private final PipTouchState mTouchState; @@ -435,6 +437,8 @@ public class PipTouchHandler { * Gesture controlling normal movement of the PIP. */ private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() { + // Whether the PiP was on the left side of the screen at the start of the gesture + private boolean mStartedOnLeft; @Override public void onDown(PipTouchState touchState) { @@ -442,6 +446,10 @@ public class PipTouchHandler { return; } + mStartedOnLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX(); + mMovementWithinMinimize = true; + mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom; + // If the menu is still visible, and we aren't minimized, then just poke the menu // so that it will timeout after the user stops touching it if (mMenuController.isMenuVisible() && !mIsMinimized) { @@ -493,6 +501,18 @@ public class PipTouchHandler { if (ENABLE_DISMISS_DRAG_TO_EDGE) { updateDismissFraction(); } + + final PointF curPos = touchState.getLastTouchPosition(); + if (mMovementWithinMinimize) { + // Track if movement remains near starting edge to identify swipes to minimize + mMovementWithinMinimize = mStartedOnLeft + ? curPos.x <= mMovementBounds.left + mTmpBounds.width() + : curPos.x >= mMovementBounds.right; + } + if (mMovementWithinDismiss) { + // Track if movement remains near the bottom edge to identify swipe to dismiss + mMovementWithinDismiss = curPos.y >= mMovementBounds.bottom; + } return true; } return false; @@ -526,8 +546,15 @@ public class PipTouchHandler { } if (touchState.isDragging()) { + final PointF vel = touchState.getVelocity(); + final float velocity = PointF.length(vel.x, vel.y); + final boolean isFling = velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond(); + final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y); final boolean onLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX(); - boolean isFlingToBot = isFlingTowardsEdge(touchState, 4 /* bottom */); + final boolean isFlingToBot = !isHorizontal && mMovementWithinDismiss && vel.y > 0; + final boolean isFlingToEdge = isHorizontal && mMovementWithinMinimize + && (onLeft ? vel.x < 0 : vel.x > 0); + if (ENABLE_DISMISS_DRAG_TO_EDGE && (mMotionHelper.shouldDismissPip() || isFlingToBot)) { mMotionHelper.animateDragToEdgeDismiss(mMotionHelper.getBounds(), @@ -536,8 +563,7 @@ public class PipTouchHandler { MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED, METRIC_VALUE_DISMISSED_BY_DRAG); return true; - } else if (!mIsMinimized && (mMotionHelper.shouldMinimizePip() - || isFlingTowardsEdge(touchState, onLeft ? 2 : 3))) { + } else if (!mIsMinimized && (mMotionHelper.shouldMinimizePip() || isFlingToEdge)) { // Pip should be minimized setMinimizedStateInternal(true); if (mMenuController.isMenuVisible()) { @@ -563,9 +589,7 @@ public class PipTouchHandler { mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds); } - final PointF vel = mTouchState.getVelocity(); - final float velocity = PointF.length(vel.x, vel.y); - if (velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond()) { + if (isFling) { mMotionHelper.flingToSnapTarget(velocity, vel.x, vel.y, mMovementBounds, mUpdateScrimListener); } else { @@ -585,42 +609,6 @@ public class PipTouchHandler { }; /** - * @return whether the gesture ending in {@param vel} is fast enough to be a fling and towards - * the provided {@param edge} where: - * - * 1 = top - * 2 = left - * 3 = right - * 4 = bottom - */ - private boolean isFlingTowardsEdge(PipTouchState touchState, int edge) { - final PointF vel = touchState.getVelocity(); - final PointF downPos = touchState.getDownTouchPosition(); - final Rect bounds = mMotionHelper.getBounds(); - final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y); - final boolean isFling = - PointF.length(vel.x, vel.y) > mFlingAnimationUtils.getMinVelocityPxPerSecond(); - if (!isFling) { - return false; - } - switch (edge) { - case 1: // top - return !isHorizontal && vel.y < 0 - && downPos.y <= mMovementBounds.top + bounds.height(); - case 2: // left - return isHorizontal && vel.x < 0 - && downPos.x <= mMovementBounds.left + bounds.width(); - case 3: // right - return isHorizontal && vel.x > 0 - && downPos.x >= mMovementBounds.right; - case 4: // bottom - return !isHorizontal && vel.y > 0 - && downPos.y >= mMovementBounds.bottom; - } - return false; - } - - /** * Updates the current movement bounds based on whether the menu is currently visible. */ private void updateMovementBounds(boolean isExpanded) { -- 2.11.0