PiP pinch-to-resize: add double-tap to max/min size.
Per spec, max size would be the biggest possible bounds within the
movement bounds (displayWidth - 2 * insetWidth), and min size would be
40% of the width.
This also fixes the issue of portrait PiP not resizing correctly due to
wrong math being done in the resize algorithm.
Bug: 166478885
Test: Double-tap on PiP
Change-Id: I2e239d23a0e2519c0b482005614a1faddb1f808a
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 d0d9b26..9595b5a 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
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
+import android.graphics.Point;
import android.graphics.Rect;
import android.util.Size;
import android.view.DisplayInfo;
@@ -59,6 +60,8 @@
private final @NonNull Rect mExpandedBounds = new Rect();
private final @NonNull Rect mNormalMovementBounds = new Rect();
private final @NonNull Rect mExpandedMovementBounds = new Rect();
+ private final Point mMaxSize = new Point();
+ private final Point mMinSize = new Point();
private final @NonNull Context mContext;
private float mAspectRatio;
private int mStashedState = STASH_TYPE_NONE;
@@ -151,6 +154,24 @@
mExpandedMovementBounds.set(bounds);
}
+ /** Sets the max possible size for resize. */
+ public void setMaxSize(int width, int height) {
+ mMaxSize.set(width, height);
+ }
+
+ /** Sets the min possible size for resize. */
+ public void setMinSize(int width, int height) {
+ mMinSize.set(width, height);
+ }
+
+ public Point getMaxSize() {
+ return mMaxSize;
+ }
+
+ public Point getMinSize() {
+ return mMinSize;
+ }
+
/** Returns the expanded movement bounds. */
@NonNull
public Rect getExpandedMovementBounds() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java
index 28cbe35..721f621 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipPinchResizingAlgorithm.java
@@ -85,21 +85,21 @@
} else {
// Assuming that the width is our target we calculate the height.
width1 = Math.max(minVisibleWidth, Math.min(maxSize.x, width));
- height1 = Math.round((float) width1 * aspect);
+ height1 = Math.round((float) width1 / aspect);
if (height1 < minVisibleHeight) {
// If the resulting height is too small we adjust to the minimal size.
height1 = minVisibleHeight;
width1 = Math.max(minVisibleWidth,
- Math.min(maxSize.x, Math.round((float) height1 / aspect)));
+ Math.min(maxSize.x, Math.round((float) height1 * aspect)));
}
// Assuming that the height is our target we calculate the width.
height2 = Math.max(minVisibleHeight, Math.min(maxSize.y, height));
- width2 = Math.round((float) height2 / aspect);
+ width2 = Math.round((float) height2 * aspect);
if (width2 < minVisibleWidth) {
// If the resulting width is too small we adjust to the minimal size.
width2 = minVisibleWidth;
height2 = Math.max(minVisibleHeight,
- Math.min(maxSize.y, Math.round((float) width2 * aspect)));
+ Math.min(maxSize.y, Math.round((float) width2 / aspect)));
}
}
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 6b6bf5e..6a26eab 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
@@ -359,9 +359,13 @@
mPipBoundsState.getExpandedBounds(), insetBounds, expandedMovementBounds,
bottomOffset);
- mPipResizeGestureHandler.updateMinSize(normalBounds.width(), normalBounds.height());
- mPipResizeGestureHandler.updateMaxSize(mPipBoundsState.getExpandedBounds().width(),
- mPipBoundsState.getExpandedBounds().height());
+ if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
+ updatePinchResizeSizeConstraints(insetBounds, normalBounds, aspectRatio);
+ } else {
+ mPipResizeGestureHandler.updateMinSize(normalBounds.width(), normalBounds.height());
+ mPipResizeGestureHandler.updateMaxSize(mPipBoundsState.getExpandedBounds().width(),
+ mPipBoundsState.getExpandedBounds().height());
+ }
// The extra offset does not really affect the movement bounds, but are applied based on the
// current state (ime showing, or shelf offset) when we need to actually shift
@@ -430,6 +434,30 @@
}
}
+ private void updatePinchResizeSizeConstraints(Rect insetBounds, Rect normalBounds,
+ float aspectRatio) {
+ final int shorterLength = Math.min(mPipBoundsState.getDisplayBounds().width(),
+ mPipBoundsState.getDisplayBounds().height());
+ final int padding = insetBounds.left;
+ final int minWidth, minHeight, maxWidth, maxHeight;
+ if (aspectRatio > 1f) {
+ minWidth = (int) Math.min(normalBounds.width(), shorterLength * 0.4);
+ minHeight = (int) (minWidth / aspectRatio);
+ maxWidth = (int) Math.max(normalBounds.width(), shorterLength - 2 * padding);
+ maxHeight = (int) (maxWidth / aspectRatio);
+ } else {
+ minHeight = (int) Math.min(normalBounds.height(), shorterLength * 0.4);
+ minWidth = (int) (minHeight * aspectRatio);
+ maxHeight = (int) Math.max(normalBounds.height(), shorterLength - 2 * padding);
+ maxWidth = (int) (maxHeight * aspectRatio);
+ }
+
+ mPipResizeGestureHandler.updateMinSize(minWidth, minHeight);
+ mPipResizeGestureHandler.updateMaxSize(maxWidth, maxHeight);
+ mPipBoundsState.setMaxSize(maxWidth, maxHeight);
+ mPipBoundsState.setMinSize(minWidth, minHeight);
+ }
+
/**
* TODO Add appropriate description
*/
@@ -640,13 +668,36 @@
}
}
- private void animateToExpandedState(Runnable callback) {
- Rect expandedBounds = new Rect(mPipBoundsState.getExpandedBounds());
- mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds,
- mPipBoundsState.getMovementBounds(), mPipBoundsState.getExpandedMovementBounds(),
+ private void animateToMaximizedState(Runnable callback) {
+ Rect maxMovementBounds = new Rect();
+ Rect maxBounds = new Rect(0, 0, mPipBoundsState.getMaxSize().x,
+ mPipBoundsState.getMaxSize().y);
+ mPipBoundsAlgorithm.getMovementBounds(maxBounds, mInsetBounds, maxMovementBounds,
+ mIsImeShowing ? mImeHeight : 0);
+ mSavedSnapFraction = mMotionHelper.animateToExpandedState(maxBounds,
+ mPipBoundsState.getMovementBounds(), maxMovementBounds,
callback);
}
+ private void animateToMinimizedState() {
+ animateToUnexpandedState(new Rect(0, 0, mPipBoundsState.getMinSize().x,
+ mPipBoundsState.getMinSize().y));
+ }
+
+ private void animateToExpandedState(Runnable callback) {
+ mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
+ final Rect currentBounds = mPipBoundsState.getBounds();
+ final Rect expandedBounds = mPipBoundsState.getExpandedBounds();
+ Rect finalExpandedBounds = new Rect(expandedBounds.width() > expandedBounds.width()
+ && expandedBounds.height() > expandedBounds.height()
+ ? currentBounds : expandedBounds);
+ Rect restoredMovementBounds = new Rect();
+ mPipBoundsAlgorithm.getMovementBounds(finalExpandedBounds,
+ mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
+ mSavedSnapFraction = mMotionHelper.animateToExpandedState(finalExpandedBounds,
+ mPipBoundsState.getMovementBounds(), restoredMovementBounds, callback);
+ }
+
private void animateToUnexpandedState(Rect restoreBounds) {
Rect restoredMovementBounds = new Rect();
mPipBoundsAlgorithm.getMovementBounds(restoreBounds,
@@ -789,17 +840,15 @@
// If using pinch to zoom, double-tap functions as resizing between max/min size
if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
final boolean toExpand = mPipBoundsState.getBounds().width()
- < mPipBoundsState.getExpandedBounds().width()
+ < mPipBoundsState.getMaxSize().x
&& mPipBoundsState.getBounds().height()
- < mPipBoundsState.getExpandedBounds().height();
- mPipResizeGestureHandler.setUserResizeBounds(toExpand
- ? mPipBoundsState.getExpandedBounds()
- : mPipBoundsState.getNormalBounds());
+ < mPipBoundsState.getMaxSize().y;
if (toExpand) {
- animateToExpandedState(null);
+ animateToMaximizedState(null);
} else {
- animateToUnexpandedState(mPipBoundsState.getNormalBounds());
+ animateToMinimizedState();
}
+ mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
} else {
// Expand to fullscreen if this is a double tap
// the PiP should be frozen until the transition ends