Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +51 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +8 −3 Original line number Diff line number Diff line Loading @@ -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); } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java +58 −0 Original line number Diff line number Diff line Loading @@ -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( Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java +51 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +8 −3 Original line number Diff line number Diff line Loading @@ -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); } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java +58 −0 Original line number Diff line number Diff line Loading @@ -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( Loading