diff options
4 files changed, 157 insertions, 229 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java index 97aeda4b053f..582ff2180c83 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java @@ -94,11 +94,14 @@ public class PipSurfaceTransactionHelper { public PipSurfaceTransactionHelper scale(SurfaceControl.Transaction tx, SurfaceControl leash, Rect sourceBounds, Rect destinationBounds, float degrees) { mTmpSourceRectF.set(sourceBounds); + // We want the matrix to position the surface relative to the screen coordinates so offset + // the source to 0,0 + mTmpSourceRectF.offsetTo(0, 0); mTmpDestinationRectF.set(destinationBounds); mTmpTransform.setRectToRect(mTmpSourceRectF, mTmpDestinationRectF, Matrix.ScaleToFit.FILL); - mTmpTransform.postRotate(degrees); - tx.setMatrix(leash, mTmpTransform, mTmpFloat9) - .setPosition(leash, mTmpDestinationRectF.left, mTmpDestinationRectF.top); + mTmpTransform.postRotate(degrees, + mTmpDestinationRectF.centerX(), mTmpDestinationRectF.centerY()); + tx.setMatrix(leash, mTmpTransform, mTmpFloat9); return this; } 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 805123f81d81..f8125fd5764e 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 @@ -16,111 +16,115 @@ package com.android.wm.shell.pip.phone; import android.graphics.Point; +import android.graphics.PointF; import android.graphics.Rect; /** * Helper class to calculate the new size given two-fingers pinch to resize. */ public class PipPinchResizingAlgorithm { - private static final Rect TMP_RECT = new Rect(); + + private static final int PINCH_RESIZE_MAX_ANGLE_ROTATION = 45; + private static final float OVERROTATE_DAMP_FACTOR = 0.4f; + private static final float ANGLE_THRESHOLD = 5f; + + private final PointF mTmpDownVector = new PointF(); + private final PointF mTmpLastVector = new PointF(); + private final PointF mTmpDownCentroid = new PointF(); + private final PointF mTmpLastCentroid = new PointF(); + /** - * Given inputs and requirements and current PiP bounds, return the new size. - * - * @param x0 x-coordinate of the primary input. - * @param y0 y-coordinate of the primary input. - * @param x1 x-coordinate of the secondary input. - * @param y1 y-coordinate of the secondary input. - * @param downx0 x-coordinate of the original down point of the primary input. - * @param downy0 y-coordinate of the original down ponit of the primary input. - * @param downx1 x-coordinate of the original down point of the secondary input. - * @param downy1 y-coordinate of the original down point of the secondary input. - * @param currentPipBounds current PiP bounds. - * @param minVisibleWidth minimum visible width. - * @param minVisibleHeight minimum visible height. - * @param maxSize max size. - * @return The new resized PiP bounds, sharing the same center. + * Updates {@param resizeBoundsOut} with the new bounds of the PIP, and returns the angle in + * degrees that the PIP should be rotated. */ - public static Rect pinchResize(float x0, float y0, float x1, float y1, - float downx0, float downy0, float downx1, float downy1, Rect currentPipBounds, - int minVisibleWidth, int minVisibleHeight, Point maxSize) { - - int width = currentPipBounds.width(); - int height = currentPipBounds.height(); - int left = currentPipBounds.left; - int top = currentPipBounds.top; - int right = currentPipBounds.right; - int bottom = currentPipBounds.bottom; - final float aspect = (float) width / (float) height; - final int widthDelta = Math.round(Math.abs(x0 - x1) - Math.abs(downx0 - downx1)); - final int heightDelta = Math.round(Math.abs(y0 - y1) - Math.abs(downy0 - downy1)); - final int dx = (int) ((x0 - downx0 + x1 - downx1) / 2); - final int dy = (int) ((y0 - downy0 + y1 - downy1) / 2); - - width = Math.max(minVisibleWidth, Math.min(width + widthDelta, maxSize.x)); - height = Math.max(minVisibleHeight, Math.min(height + heightDelta, maxSize.y)); - - // Calculate 2 rectangles fulfilling all requirements for either X or Y being the major - // drag axis. What ever is producing the bigger rectangle will be chosen. - int width1; - int width2; - int height1; - int height2; - if (aspect > 1.0f) { - // 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); - 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))); - } - // 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); - 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))); - } - } 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); - 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))); - } - // 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); - 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))); - } - } + public float calculateBoundsAndAngle(PointF downPoint, PointF downSecondPoint, + PointF lastPoint, PointF lastSecondPoint, Point minSize, Point maxSize, + Rect initialBounds, Rect resizeBoundsOut) { + float downDist = (float) Math.hypot(downSecondPoint.x - downPoint.x, + downSecondPoint.y - downPoint.y); + float dist = (float) Math.hypot(lastSecondPoint.x - lastPoint.x, + lastSecondPoint.y - lastPoint.y); + float minScale = getMinScale(initialBounds, minSize); + float maxScale = getMaxScale(initialBounds, maxSize); + float scale = Math.max(minScale, Math.min(maxScale, dist / downDist)); + + // Scale the bounds by the change in distance between the points + resizeBoundsOut.set(initialBounds); + scaleRectAboutCenter(resizeBoundsOut, scale); + + // Translate by the centroid movement + getCentroid(downPoint, downSecondPoint, mTmpDownCentroid); + getCentroid(lastPoint, lastSecondPoint, mTmpLastCentroid); + resizeBoundsOut.offset((int) (mTmpLastCentroid.x - mTmpDownCentroid.x), + (int) (mTmpLastCentroid.y - mTmpDownCentroid.y)); + + // Calculate the angle + mTmpDownVector.set(downSecondPoint.x - downPoint.x, + downSecondPoint.y - downPoint.y); + mTmpLastVector.set(lastSecondPoint.x - lastPoint.x, + lastSecondPoint.y - lastPoint.y); + float angle = (float) Math.atan2(cross(mTmpDownVector, mTmpLastVector), + dot(mTmpDownVector, mTmpLastVector)); + return constrainRotationAngle((float) Math.toDegrees(angle)); + } + + private float getMinScale(Rect bounds, Point minSize) { + return Math.max((float) minSize.x / bounds.width(), (float) minSize.y / bounds.height()); + } + + private float getMaxScale(Rect bounds, Point maxSize) { + return Math.min((float) maxSize.x / bounds.width(), (float) maxSize.y / bounds.height()); + } + + private float constrainRotationAngle(float angle) { + // Remove some degrees so that user doesn't immediately start rotating until a threshold + return Math.signum(angle) * Math.max(0, (Math.abs(dampedRotate(angle)) - ANGLE_THRESHOLD)); + } + + /** + * Given the current rotation angle, dampen it so that as it approaches the maximum angle, + * dampen it. + */ + private float dampedRotate(float amount) { + if (Float.compare(amount, 0) == 0) return 0; - // Use the bigger of the two rectangles if the major change was positive, otherwise - // do the opposite. - final boolean grows = width > (right - left) || height > (bottom - top); - if (grows == (width1 * height1 > width2 * height2)) { - width = width1; - height = height1; - } else { - width = width2; - height = height2; + float f = amount / PINCH_RESIZE_MAX_ANGLE_ROTATION; + f = f / (Math.abs(f)) * (overRotateInfluenceCurve(Math.abs(f))); + + // Clamp this factor, f, to -1 < f < 1 + if (Math.abs(f) >= 1) { + f /= Math.abs(f); } + return OVERROTATE_DAMP_FACTOR * f * PINCH_RESIZE_MAX_ANGLE_ROTATION; + } + + /** + * Returns a value that corresponds to y = (f - 1)^3 + 1. + */ + private float overRotateInfluenceCurve(float f) { + f -= 1.0f; + return f * f * f + 1.0f; + } - TMP_RECT.set(currentPipBounds.centerX() - width / 2, - currentPipBounds.centerY() - height / 2, - currentPipBounds.centerX() + width / 2, - currentPipBounds.centerY() + height / 2); - TMP_RECT.offset(dx, dy); - return TMP_RECT; + private void getCentroid(PointF p1, PointF p2, PointF centroidOut) { + centroidOut.set((p2.x + p1.x) / 2, (p2.y + p1.y) / 2); + } + + private float dot(PointF p1, PointF p2) { + return p1.x * p2.x + p1.y * p2.y; + } + + private float cross(PointF p1, PointF p2) { + return p1.x * p2.y - p1.y * p2.x; + } + + private void scaleRectAboutCenter(Rect r, float scale) { + if (scale != 1.0f) { + int cx = r.centerX(); + int cy = r.centerY(); + r.offset(-cx, -cy); + r.scale(scale); + r.offset(cx, cy); + } } } 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 adbd3b853e6c..2eb63edbaeb1 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 @@ -63,10 +63,7 @@ public class PipResizeGestureHandler { private static final String TAG = "PipResizeGestureHandler"; private static final int PINCH_RESIZE_SNAP_DURATION = 250; - private static final int PINCH_RESIZE_MAX_ANGLE_ROTATION = 45; private static final float PINCH_RESIZE_AUTO_MAX_RATIO = 0.9f; - private static final float OVERROTATE_DAMP_FACTOR = 0.4f; - private static final float ANGLE_THRESHOLD = 5f; private final Context mContext; private final PipBoundsAlgorithm mPipBoundsAlgorithm; @@ -75,17 +72,20 @@ public class PipResizeGestureHandler { private final PipTaskOrganizer mPipTaskOrganizer; private final PhonePipMenuController mPhonePipMenuController; private final PipUiEventLogger mPipUiEventLogger; + private final PipPinchResizingAlgorithm mPinchResizingAlgorithm; private final int mDisplayId; private final ShellExecutor mMainExecutor; private final Region mTmpRegion = new Region(); private final PointF mDownPoint = new PointF(); - private final PointF mDownSecondaryPoint = new PointF(); + private final PointF mDownSecondPoint = new PointF(); + private final PointF mLastPoint = new PointF(); + private final PointF mLastSecondPoint = new PointF(); private final Point mMaxSize = new Point(); private final Point mMinSize = new Point(); private final Rect mLastResizeBounds = new Rect(); private final Rect mUserResizeBounds = new Rect(); - private final Rect mLastDownBounds = new Rect(); + private final Rect mDownBounds = new Rect(); private final Rect mDragCornerSize = new Rect(); private final Rect mTmpTopLeftCorner = new Rect(); private final Rect mTmpTopRightCorner = new Rect(); @@ -103,11 +103,7 @@ public class PipResizeGestureHandler { private boolean mIsEnabled; private boolean mEnablePinchResize; private boolean mIsSysUiStateValid; - // For drag-resize private boolean mThresholdCrossed; - // For pinch-resize - private boolean mThresholdCrossed0; - private boolean mThresholdCrossed1; private boolean mOngoingPinchToResize = false; private float mAngle = 0; int mFirstIndex = -1; @@ -135,6 +131,7 @@ public class PipResizeGestureHandler { mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable; mPhonePipMenuController = menuActivityController; mPipUiEventLogger = pipUiEventLogger; + mPinchResizingAlgorithm = new PipPinchResizingAlgorithm(); } public void init() { @@ -294,6 +291,10 @@ public class PipResizeGestureHandler { return mEnablePinchResize; } + public boolean isResizing() { + return mAllowGesture; + } + public boolean willStartResizeGesture(MotionEvent ev) { if (isInValidSysUiState()) { switch (ev.getActionMasked()) { @@ -362,6 +363,7 @@ public class PipResizeGestureHandler { if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { mFirstIndex = -1; mSecondIndex = -1; + mAllowGesture = false; finishResize(); } @@ -371,14 +373,16 @@ public class PipResizeGestureHandler { if (action == MotionEvent.ACTION_POINTER_DOWN) { if (mFirstIndex == -1 && mSecondIndex == -1) { + mAllowGesture = true; mFirstIndex = 0; mSecondIndex = 1; mDownPoint.set(ev.getRawX(mFirstIndex), ev.getRawY(mFirstIndex)); - mDownSecondaryPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex)); - + mDownSecondPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex)); + mDownBounds.set(mPipBoundsState.getBounds()); - mLastDownBounds.set(mPipBoundsState.getBounds()); - mLastResizeBounds.set(mLastDownBounds); + mLastPoint.set(mDownPoint); + mLastSecondPoint.set(mLastSecondPoint); + mLastResizeBounds.set(mDownBounds); } } @@ -391,133 +395,36 @@ public class PipResizeGestureHandler { float y0 = ev.getRawY(mFirstIndex); float x1 = ev.getRawX(mSecondIndex); float y1 = ev.getRawY(mSecondIndex); + mLastPoint.set(x0, y0); + mLastSecondPoint.set(x1, y1); - double hypot0 = Math.hypot(x0 - mDownPoint.x, y0 - mDownPoint.y); - double hypot1 = Math.hypot(x1 - mDownSecondaryPoint.x, y1 - mDownSecondaryPoint.y); // Capture inputs - if (hypot0 > mTouchSlop && !mThresholdCrossed0) { + if (!mThresholdCrossed + && (distanceBetween(mDownSecondPoint, mLastSecondPoint) > mTouchSlop + || distanceBetween(mDownPoint, mLastPoint) > mTouchSlop)) { mInputMonitor.pilferPointers(); - mThresholdCrossed0 = true; + mThresholdCrossed = true; // Reset the down to begin resizing from this point - mDownPoint.set(x0, y0); + mDownPoint.set(mLastPoint); + mDownSecondPoint.set(mLastSecondPoint); } - if (hypot1 > mTouchSlop && !mThresholdCrossed1) { - mInputMonitor.pilferPointers(); - mThresholdCrossed1 = true; - // Reset the down to begin resizing from this point - mDownSecondaryPoint.set(x1, y1); - } - if (mThresholdCrossed0 || mThresholdCrossed1) { + + if (mThresholdCrossed) { if (mPhonePipMenuController.isMenuVisible()) { mPhonePipMenuController.hideMenu(); } - x0 = mThresholdCrossed0 ? x0 : mDownPoint.x; - y0 = mThresholdCrossed0 ? y0 : mDownPoint.y; - x1 = mThresholdCrossed1 ? x1 : mDownSecondaryPoint.x; - y1 = mThresholdCrossed1 ? y1 : mDownSecondaryPoint.y; - - final Rect originalPipBounds = mPipBoundsState.getBounds(); - int focusX = (int) originalPipBounds.centerX(); - int focusY = (int) originalPipBounds.centerY(); - - float down0X = mDownPoint.x; - float down0Y = mDownPoint.y; - float down1X = mDownSecondaryPoint.x; - float down1Y = mDownSecondaryPoint.y; - - float angle = 0; - if (down0X > focusX && down0Y < focusY && down1X < focusX && down1Y > focusY) { - // Top right + Bottom left pinch to zoom. - angle = calculateRotationAngle(mLastResizeBounds.centerX(), - mLastResizeBounds.centerY(), x0, y0, x1, y1, true); - } else if (down1X > focusX && down1Y < focusY - && down0X < focusX && down0Y > focusY) { - // Top right + Bottom left pinch to zoom. - angle = calculateRotationAngle(mLastResizeBounds.centerX(), - mLastResizeBounds.centerY(), x1, y1, x0, y0, true); - } else if (down0X < focusX && down0Y < focusY - && down1X > focusX && down1Y > focusY) { - // Top left + bottom right pinch to zoom. - angle = calculateRotationAngle(mLastResizeBounds.centerX(), - mLastResizeBounds.centerY(), x0, y0, x1, y1, false); - } else if (down1X < focusX && down1Y < focusY - && down0X > focusX && down0Y > focusY) { - // Top left + bottom right pinch to zoom. - angle = calculateRotationAngle(mLastResizeBounds.centerX(), - mLastResizeBounds.centerY(), x1, y1, x0, y0, false); - } - mAngle = angle; - - mLastResizeBounds.set(PipPinchResizingAlgorithm.pinchResize(x0, y0, x1, y1, - mDownPoint.x, mDownPoint.y, mDownSecondaryPoint.x, mDownSecondaryPoint.y, - originalPipBounds, mMinSize.x, mMinSize.y, mMaxSize)); + mAngle = mPinchResizingAlgorithm.calculateBoundsAndAngle(mDownPoint, + mDownSecondPoint, mLastPoint, mLastSecondPoint, mMinSize, mMaxSize, + mDownBounds, mLastResizeBounds); - mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds, - (float) -mAngle, null); + mPipTaskOrganizer.scheduleUserResizePip(mDownBounds, mLastResizeBounds, + mAngle, null); mPipBoundsState.setHasUserResizedPip(true); } } } - private float calculateRotationAngle(int pivotX, int pivotY, float topX, float topY, - float bottomX, float bottomY, boolean positive) { - - // The base angle is the angle formed by taking the angle between the center horizontal - // and one of the corners. - double baseAngle = Math.toDegrees(Math.atan2(Math.abs(mLastResizeBounds.top - pivotY), - Math.abs(mLastResizeBounds.right - pivotX))); - - double angle0 = mThresholdCrossed0 - ? Math.toDegrees(Math.atan2(pivotY - topY, topX - pivotX)) : baseAngle; - double angle1 = mThresholdCrossed0 - ? Math.toDegrees(Math.atan2(pivotY - bottomY, bottomX - pivotX)) : baseAngle; - - - if (positive) { - angle1 = angle1 < 0 ? 180 + angle1 : angle1 - 180; - } else { - angle0 = angle0 < 0 ? -angle0 - 180 : 180 - angle0; - angle1 = -angle1; - } - - // Calculate the percentage difference of [0, 90] compare to the base angle. - double diff0 = (Math.max(-90, Math.min(angle0, 90)) - baseAngle) / 90; - double diff1 = (Math.max(-90, Math.min(angle1, 90)) - baseAngle) / 90; - - final float angle = - (float) (diff0 + diff1) / 2 * PINCH_RESIZE_MAX_ANGLE_ROTATION * (positive ? 1 : -1); - - // Remove some degrees so that user doesn't immediately start rotating until a threshold - return angle / Math.abs(angle) - * Math.max(0, (Math.abs(dampedRotate(angle)) - ANGLE_THRESHOLD)); - } - - /** - * Given the current rotation angle, dampen it so that as it approaches the maximum angle, - * dampen it. - */ - private float dampedRotate(float amount) { - if (Float.compare(amount, 0) == 0) return 0; - - float f = amount / PINCH_RESIZE_MAX_ANGLE_ROTATION; - f = f / (Math.abs(f)) * (overRotateInfluenceCurve(Math.abs(f))); - - // Clamp this factor, f, to -1 < f < 1 - if (Math.abs(f) >= 1) { - f /= Math.abs(f); - } - return OVERROTATE_DAMP_FACTOR * f * PINCH_RESIZE_MAX_ANGLE_ROTATION; - } - - /** - * Returns a value that corresponds to y = (f - 1)^3 + 1. - */ - private float overRotateInfluenceCurve(float f) { - f -= 1.0f; - return f * f * f + 1.0f; - } - private void onDragCornerResize(MotionEvent ev) { int action = ev.getActionMasked(); float x = ev.getX(); @@ -529,7 +436,7 @@ public class PipResizeGestureHandler { if (mAllowGesture) { setCtrlType((int) x, (int) y); mDownPoint.set(x, y); - mLastDownBounds.set(mPipBoundsState.getBounds()); + mDownBounds.set(mPipBoundsState.getBounds()); } if (!currentPipBounds.contains((int) ev.getX(), (int) ev.getY()) && mPhonePipMenuController.isMenuVisible()) { @@ -560,11 +467,11 @@ public class PipResizeGestureHandler { mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(x, y, mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x, mMinSize.y, mMaxSize, true, - mLastDownBounds.width() > mLastDownBounds.height())); + mDownBounds.width() > mDownBounds.height())); mPipBoundsAlgorithm.transformBoundsToAspectRatio(mLastResizeBounds, mPipBoundsState.getAspectRatio(), false /* useCurrentMinEdgeSize */, true /* useCurrentSize */); - mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds, + mPipTaskOrganizer.scheduleUserResizePip(mDownBounds, mLastResizeBounds, null); mPipBoundsState.setHasUserResizedPip(true); } @@ -593,12 +500,12 @@ public class PipResizeGestureHandler { // If user resize is pretty close to max size, just auto resize to max. if (mLastResizeBounds.width() >= PINCH_RESIZE_AUTO_MAX_RATIO * mMaxSize.x || mLastResizeBounds.height() >= PINCH_RESIZE_AUTO_MAX_RATIO * mMaxSize.y) { - mLastResizeBounds.set(0, 0, mMaxSize.x, mMaxSize.y); + resizeRectAboutCenter(mLastResizeBounds, mMaxSize.x, mMaxSize.y); } final float snapFraction = mPipBoundsAlgorithm.getSnapFraction(mLastResizeBounds); mPipBoundsAlgorithm.applySnapFraction(mLastResizeBounds, snapFraction); mPipTaskOrganizer.scheduleAnimateResizePip(startBounds, mLastResizeBounds, - PINCH_RESIZE_SNAP_DURATION, -mAngle, callback); + PINCH_RESIZE_SNAP_DURATION, mAngle, callback); } else { mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds, PipAnimationController.TRANSITION_DIRECTION_USER_RESIZE, callback); @@ -642,6 +549,20 @@ public class PipResizeGestureHandler { mOhmOffset = offset; } + private float distanceBetween(PointF p1, PointF p2) { + return (float) Math.hypot(p2.x - p1.x, p2.y - p1.y); + } + + private void resizeRectAboutCenter(Rect rect, int w, int h) { + int cx = rect.centerX(); + int cy = rect.centerY(); + int l = cx - w / 2; + int r = l + w; + int t = cy - h / 2; + int b = t + h; + rect.set(l, t, r, b); + } + public void dump(PrintWriter pw, String prefix) { final String innerPrefix = prefix + " "; pw.println(prefix + TAG); 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 75166b64a7bf..39697067ef54 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 @@ -664,7 +664,7 @@ public class PipTouchHandler { } else if (menuState == MENU_STATE_NONE && mMenuState == MENU_STATE_FULL) { // Try and restore the PiP to the closest edge, using the saved snap fraction // if possible - if (resize) { + if (resize && !mPipResizeGestureHandler.isResizing()) { if (mDeferResizeToNormalBoundsUntilRotation == -1) { // This is a very special case: when the menu is expanded and visible, // navigating to another activity can trigger auto-enter PiP, and if the |