From beefdec180d6763691517aefdce91ea995e8d66b Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Fri, 30 Oct 2020 18:14:48 -0700 Subject: [PATCH 1/2] Set PiP stashing to a set 32dp away from the edge of the screen. Bug: 165793553 Test: Stash PIP Change-Id: Ib6e0058a9e0c6b60605c6143e9407ce809abebf3 --- libs/WindowManager/Shell/res/values/dimen.xml | 3 +++ .../wm/shell/pip/phone/PipMotionHelper.java | 21 +++++++++++++------ .../wm/shell/pip/phone/PipTouchHandler.java | 1 + 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 1d85e9fceac9c..b87a642a8dc78 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -57,6 +57,9 @@ 4dp 0dp + + 32dp + 24dp 50dp diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java index 9240b3f41ff4b..9247c683a0820 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java @@ -33,6 +33,7 @@ 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; @@ -60,7 +61,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private static final int EXPAND_STACK_TO_MENU_DURATION = 250; private static final int LEAVE_PIP_DURATION = 300; private static final int SHIFT_DURATION = 300; - private static final float STASH_RATIO = 0.25f; /** Friction to use for PIP when it moves via physics fling animations. */ private static final float DEFAULT_FRICTION = 2f; @@ -94,6 +94,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, /** The destination bounds to which PIP is animating. */ private final Rect mAnimatingToBounds = new Rect(); + private int mStashOffset = 0; + /** Coordinator instance for resolving conflicts with other floating content. */ private FloatingContentCoordinator mFloatingContentCoordinator; @@ -189,6 +191,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback); mTemporaryBoundsPhysicsAnimator.setCustomAnimationHandler( mSfAnimationHandlerThreadLocal.get()); + reloadResources(); mResizePipUpdateListener = (target, values) -> { if (!mTemporaryBounds.isEmpty()) { @@ -198,6 +201,11 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, }; } + void reloadResources() { + mStashOffset = mContext.getResources() + .getDimensionPixelSize(R.dimen.pip_stash_offset); + } + @NonNull @Override public Rect getFloatingBoundsOnScreen() { @@ -414,9 +422,10 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, FloatProperties.RECT_Y, velocityY, mFlingConfigY, mSpringConfig) .withEndActions(endAction); - final float offset = ((float) getBounds().width()) * (1.0f - STASH_RATIO); - final float leftEdge = isStash ? mMovementBounds.left - offset : mMovementBounds.left; - final float rightEdge = isStash ? mMovementBounds.right + offset : mMovementBounds.right; + final float leftEdge = isStash ? mStashOffset - mPipBoundsState.getBounds().width() + : mMovementBounds.left; + final float rightEdge = isStash ? mPipBoundsState.getDisplayBounds().right - mStashOffset + : mMovementBounds.right; final float xEndValue = velocityX < 0 ? leftEdge : rightEdge; final float estimatedFlingYEndValue = @@ -524,9 +533,9 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, DEFAULT_FRICTION, mMovementBounds.left, mMovementBounds.right); mFlingConfigY = new PhysicsAnimator.FlingConfig( DEFAULT_FRICTION, mMovementBounds.top, mMovementBounds.bottom); - final float offset = ((float) getBounds().width()) * (1.0f - STASH_RATIO); mStashConfigX = new PhysicsAnimator.FlingConfig( - DEFAULT_FRICTION, mMovementBounds.left - offset, mMovementBounds.right + offset); + DEFAULT_FRICTION, mStashOffset - mPipBoundsState.getBounds().width(), + mPipBoundsState.getDisplayBounds().right - mStashOffset); } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index e95e4a07ed922..b6bd0e0b6ddf6 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -221,6 +221,7 @@ public class PipTouchHandler { R.dimen.pip_expanded_shortest_edge_size); mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset); mPipDismissTargetHandler.updateMagneticTargetSize(); + mMotionHelper.reloadResources(); } private boolean shouldShowResizeHandle() { From 1640ffd49d55451924aa2045df505eaa44712dfe Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Fri, 30 Oct 2020 18:31:03 -0700 Subject: [PATCH 2/2] Don't allow PiP to be interactive when stashed. User can still move the PiP around, but disable: - showing menu - resizing - double-tap gestures Bug: 165793553 Test: Stash PIP Change-Id: I899d8aa3ffffc4087c706f121dee69f63addc9ab --- .../com/android/wm/shell/pip/PipBoundsState.java | 15 +++++++++++++++ .../shell/pip/phone/PipResizeGestureHandler.java | 15 ++++++++++++--- .../wm/shell/pip/phone/PipTouchHandler.java | 16 ++++++++++------ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java index d0ab31dd72c89..fc523aef9d16b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java @@ -37,6 +37,7 @@ public final class PipBoundsState { private final @NonNull Rect mBounds = new Rect(); private float mAspectRatio; + private boolean mIsStashed; private PipReentryState mPipReentryState; private ComponentName mLastPipComponentName; private final DisplayInfo mDisplayInfo = new DisplayInfo(); @@ -54,6 +55,20 @@ public final class PipBoundsState { return new Rect(mBounds); } + /** + * Dictate where PiP currently should be stashed or not. + */ + public void setStashed(boolean isStashed) { + mIsStashed = isStashed; + } + + /** + * Whether PiP is stashed or not. + */ + public boolean isStashed() { + return mIsStashed; + } + public void setAspectRatio(float aspectRatio) { mAspectRatio = aspectRatio; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java index ef3875597aa28..f3d8c7b0f5982 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java @@ -47,6 +47,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.policy.TaskResizingAlgorithm; import com.android.wm.shell.R; import com.android.wm.shell.pip.PipBoundsHandler; +import com.android.wm.shell.pip.PipBoundsState; import com.android.wm.shell.pip.PipTaskOrganizer; import com.android.wm.shell.pip.PipUiEventLogger; @@ -67,6 +68,7 @@ public class PipResizeGestureHandler { private final Context mContext; private final PipBoundsHandler mPipBoundsHandler; private final PipMotionHelper mMotionHelper; + private final PipBoundsState mPipBoundsState; private final int mDisplayId; private final Executor mMainExecutor; private final ScaleGestureDetector mScaleGestureDetector; @@ -107,13 +109,15 @@ public class PipResizeGestureHandler { private int mCtrlType; public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler, - PipMotionHelper motionHelper, PipTaskOrganizer pipTaskOrganizer, - Function movementBoundsSupplier, Runnable updateMovementBoundsRunnable, - PipUiEventLogger pipUiEventLogger, PipMenuActivityController menuActivityController) { + PipBoundsState pipBoundsState, PipMotionHelper motionHelper, + PipTaskOrganizer pipTaskOrganizer, Function movementBoundsSupplier, + Runnable updateMovementBoundsRunnable, PipUiEventLogger pipUiEventLogger, + PipMenuActivityController menuActivityController) { mContext = context; mDisplayId = context.getDisplayId(); mMainExecutor = context.getMainExecutor(); mPipBoundsHandler = pipBoundsHandler; + mPipBoundsState = pipBoundsState; mMotionHelper = motionHelper; mPipTaskOrganizer = pipTaskOrganizer; mMovementBoundsSupplier = movementBoundsSupplier; @@ -263,6 +267,11 @@ public class PipResizeGestureHandler { } private void onInputEvent(InputEvent ev) { + // Don't allow resize when PiP is stashed. + if (mPipBoundsState.isStashed()) { + return; + } + if (ev instanceof MotionEvent) { if (mUsingPinchToZoom) { mScaleGestureDetector.onTouchEvent((MotionEvent) ev); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index b6bd0e0b6ddf6..d820e772d490b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -179,8 +179,8 @@ public class PipTouchHandler { mMotionHelper = new PipMotionHelper(mContext, pipBoundsState, pipTaskOrganizer, mMenuController, mPipBoundsHandler.getSnapAlgorithm(), floatingContentCoordinator); mPipResizeGestureHandler = - new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper, - pipTaskOrganizer, this::getMovementBounds, + new PipResizeGestureHandler(context, pipBoundsHandler, pipBoundsState, + mMotionHelper, pipTaskOrganizer, this::getMovementBounds, this::updateMovementBounds, pipUiEventLogger, menuController); mPipDismissTargetHandler = new PipDismissTargetHandler(context, pipUiEventLogger, mMotionHelper, mHandler); @@ -464,7 +464,7 @@ public class PipTouchHandler { } MotionEvent ev = (MotionEvent) inputEvent; - if (mPipResizeGestureHandler.willStartResizeGesture(ev)) { + if (!mPipBoundsState.isStashed() && mPipResizeGestureHandler.willStartResizeGesture(ev)) { // Initialize the touch state for the gesture, but immediately reset to invalidate the // gesture mTouchState.onTouchEvent(ev); @@ -554,6 +554,8 @@ public class PipTouchHandler { } } + shouldDeliverToMenu |= !mPipBoundsState.isStashed(); + // Deliver the event to PipMenuActivity to handle button click if the menu has shown. if (shouldDeliverToMenu) { final MotionEvent cloneEvent = MotionEvent.obtain(ev); @@ -716,7 +718,7 @@ public class PipTouchHandler { // If the menu is still visible then just poke the menu // so that it will timeout after the user stops touching it - if (mMenuState != MENU_STATE_NONE) { + if (mMenuState != MENU_STATE_NONE && !mPipBoundsState.isStashed()) { mMenuController.pokeMenu(); } } @@ -728,6 +730,7 @@ public class PipTouchHandler { } if (touchState.startedDragging()) { + mPipBoundsState.setStashed(false); mSavedSnapFraction = -1f; mPipDismissTargetHandler.showDismissTargetMaybe(); } @@ -786,12 +789,13 @@ public class PipTouchHandler { if (mEnableStash && (animatingBounds.right > mPipBoundsState.getDisplayBounds().right || animatingBounds.left < mPipBoundsState.getDisplayBounds().left)) { + mPipBoundsState.setStashed(true); mMotionHelper.stashToEdge(vel.x, vel.y, this::flingEndAction /* endAction */); } else { mMotionHelper.flingToSnapTarget(vel.x, vel.y, this::flingEndAction /* endAction */); } - } else if (mTouchState.isDoubleTap()) { + } else if (mTouchState.isDoubleTap() && !mPipBoundsState.isStashed()) { // If using pinch to zoom, double-tap functions as resizing between max/min size if (mPipResizeGestureHandler.isUsingPinchToZoom()) { final boolean toExpand = @@ -810,7 +814,7 @@ public class PipTouchHandler { setTouchEnabled(false); mMotionHelper.expandLeavePip(); } - } else if (mMenuState != MENU_STATE_FULL) { + } else if (mMenuState != MENU_STATE_FULL && !mPipBoundsState.isStashed()) { if (!mTouchState.isWaitingForDoubleTap()) { // User has stalled long enough for this not to be a drag or a double tap, just // expand the menu