From dcb5e60c3837d561fd8232caa0239cdbd3b74155 Mon Sep 17 00:00:00 2001 From: "jorgegil@google.com" Date: Tue, 29 Jun 2021 10:39:00 -0700 Subject: Check the min menu size when exp. to normal bounds The normal bounds may be too small to fit all menu icons, so before expanding to the normal bounds, first check that the expected menu size will fit and if not adjust the bounds so that it will. Bug: 191296663 Test: atest PipBoundsAlgorithmTest manual - verify vertical YT video fits all three actions Change-Id: I531d86501927a6a3ffeb069193c592366ef8f584 --- .../android/wm/shell/pip/PipBoundsAlgorithm.java | 51 +++++++++++++++++++ .../wm/shell/pip/phone/PipTouchHandler.java | 11 ++-- .../wm/shell/pip/PipBoundsAlgorithmTest.java | 58 ++++++++++++++++++++++ 3 files changed, 117 insertions(+), 3 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java index 046c32071358..a4b866aa3f5e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java @@ -19,6 +19,7 @@ package com.android.wm.shell.pip; import static android.util.TypedValue.COMPLEX_UNIT_DIP; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.PictureInPictureParams; import android.content.Context; import android.content.pm.ActivityInfo; @@ -453,6 +454,56 @@ public class PipBoundsAlgorithm { return new Size(width, height); } + /** + * @return the normal bounds adjusted so that they fit the menu actions. + */ + public Rect adjustNormalBoundsToFitMenu(@NonNull Rect normalBounds, + @Nullable Size minMenuSize) { + if (minMenuSize == null) { + return normalBounds; + } + if (normalBounds.width() >= minMenuSize.getWidth() + && normalBounds.height() >= minMenuSize.getHeight()) { + // The normal bounds can fit the menu as is, no need to adjust the bounds. + return normalBounds; + } + final Rect adjustedNormalBounds = new Rect(); + final boolean needsWidthAdj = minMenuSize.getWidth() > normalBounds.width(); + final boolean needsHeightAdj = minMenuSize.getHeight() > normalBounds.height(); + final int adjWidth; + final int adjHeight; + if (needsWidthAdj && needsHeightAdj) { + // Both the width and the height are too small - find the edge that needs the larger + // adjustment and scale that edge. The other edge will scale beyond the minMenuSize + // when the aspect ratio is applied. + final float widthScaleFactor = + ((float) (minMenuSize.getWidth())) / ((float) (normalBounds.width())); + final float heightScaleFactor = + ((float) (minMenuSize.getHeight())) / ((float) (normalBounds.height())); + if (widthScaleFactor > heightScaleFactor) { + adjWidth = minMenuSize.getWidth(); + adjHeight = Math.round(adjWidth / mPipBoundsState.getAspectRatio()); + } else { + adjHeight = minMenuSize.getHeight(); + adjWidth = Math.round(adjHeight * mPipBoundsState.getAspectRatio()); + } + } else if (needsWidthAdj) { + // Width is too small - use the min menu size width instead. + adjWidth = minMenuSize.getWidth(); + adjHeight = Math.round(adjWidth / mPipBoundsState.getAspectRatio()); + } else { + // Height is too small - use the min menu size height instead. + adjHeight = minMenuSize.getHeight(); + adjWidth = Math.round(adjHeight * mPipBoundsState.getAspectRatio()); + } + adjustedNormalBounds.set(0, 0, adjWidth, adjHeight); + // Make sure the bounds conform to the aspect ratio and min edge size. + transformBoundsToAspectRatio(adjustedNormalBounds, + mPipBoundsState.getAspectRatio(), true /* useCurrentMinEdgeSize */, + true /* useCurrentSize */); + return adjustedNormalBounds; + } + /** * Dumps internal states. */ 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 b1086c575f49..0bcd1a363eb6 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 @@ -726,12 +726,17 @@ public class PipTouchHandler { } private void animateToNormalSize(Runnable callback) { + // Save the current bounds as the user-resize bounds. mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds()); - final Rect normalBounds = new Rect(mPipBoundsState.getNormalBounds()); + + final Size minMenuSize = mMenuController.getEstimatedMinMenuSize(); + final Rect normalBounds = mPipBoundsState.getNormalBounds(); + final Rect destBounds = mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, + minMenuSize); Rect restoredMovementBounds = new Rect(); - mPipBoundsAlgorithm.getMovementBounds(normalBounds, + mPipBoundsAlgorithm.getMovementBounds(destBounds, mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0); - mSavedSnapFraction = mMotionHelper.animateToExpandedState(normalBounds, + mSavedSnapFraction = mMotionHelper.animateToExpandedState(destBounds, mPipBoundsState.getMovementBounds(), restoredMovementBounds, callback); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java index a0c6d1138698..90f898aa09da 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java @@ -402,6 +402,64 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds); } + @Test + public void adjustNormalBoundsToFitMenu_alreadyFits() { + final Rect normalBounds = new Rect(0, 0, 400, 711); + final Size minMenuSize = new Size(396, 292); + mPipBoundsState.setAspectRatio( + ((float) normalBounds.width()) / ((float) normalBounds.height())); + + final Rect bounds = + mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, minMenuSize); + + assertEquals(normalBounds, bounds); + } + + @Test + public void adjustNormalBoundsToFitMenu_widthTooSmall() { + final Rect normalBounds = new Rect(0, 0, 297, 528); + final Size minMenuSize = new Size(396, 292); + mPipBoundsState.setAspectRatio( + ((float) normalBounds.width()) / ((float) normalBounds.height())); + + final Rect bounds = + mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, minMenuSize); + + assertEquals(minMenuSize.getWidth(), bounds.width()); + assertEquals(minMenuSize.getWidth() / mPipBoundsState.getAspectRatio(), + bounds.height(), 0.3f); + } + + @Test + public void adjustNormalBoundsToFitMenu_heightTooSmall() { + final Rect normalBounds = new Rect(0, 0, 400, 280); + final Size minMenuSize = new Size(396, 292); + mPipBoundsState.setAspectRatio( + ((float) normalBounds.width()) / ((float) normalBounds.height())); + + final Rect bounds = + mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, minMenuSize); + + assertEquals(minMenuSize.getHeight(), bounds.height()); + assertEquals(minMenuSize.getHeight() * mPipBoundsState.getAspectRatio(), + bounds.width(), 0.3f); + } + + @Test + public void adjustNormalBoundsToFitMenu_widthAndHeightTooSmall() { + final Rect normalBounds = new Rect(0, 0, 350, 280); + final Size minMenuSize = new Size(396, 292); + mPipBoundsState.setAspectRatio( + ((float) normalBounds.width()) / ((float) normalBounds.height())); + + final Rect bounds = + mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds, minMenuSize); + + assertEquals(minMenuSize.getWidth(), bounds.width()); + assertEquals(minMenuSize.getWidth() / mPipBoundsState.getAspectRatio(), + bounds.height(), 0.3f); + } + private void overrideDefaultAspectRatio(float aspectRatio) { final TestableResources res = mContext.getOrCreateTestableResources(); res.addOverride( -- cgit v1.2.3-59-g8ed1b