diff options
5 files changed, 96 insertions, 42 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java index c487f7543dcf..214e6ad455a1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipBoundsState.java @@ -377,6 +377,16 @@ public class PipBoundsState { /** Sets the preferred size of PIP as specified by the activity in PIP mode. */ public void setOverrideMinSize(@Nullable Size overrideMinSize) { + if (overrideMinSize != null) { + final Size defaultSize = mSizeSpecSource.getDefaultSize(getAspectRatio()); + if (overrideMinSize.getWidth() > defaultSize.getWidth() + || overrideMinSize.getHeight() > defaultSize.getHeight()) { + ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "Ignore override min size(%s): larger than default size (%s)", + overrideMinSize, defaultSize); + return; + } + } final boolean changed = !Objects.equals(overrideMinSize, getOverrideMinSize()); mSizeSpecSource.setOverrideMinSize(overrideMinSize); if (changed && mOnMinimalSizeChangeCallback != null) { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java index 6bda2259b44c..7aea8ef1ba48 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsAlgorithmTest.java @@ -147,7 +147,9 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { public void getDefaultBounds_widerOverrideMinSize_matchesMinSizeWidthAndDefaultAspectRatio() { overrideDefaultAspectRatio(1.0f); // The min size's aspect ratio is greater than the default aspect ratio. - final Size overrideMinSize = new Size(150, 120); + final Size widerSize = mSizeSpecSource.getDefaultSize(1.5f); + final Size overrideMinSize = new Size( + widerSize.getWidth() / 2, widerSize.getHeight() / 2); mPipBoundsState.setOverrideMinSize(overrideMinSize); final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds(); @@ -163,7 +165,9 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { public void getDefaultBounds_tallerOverrideMinSize_matchesMinSizeHeightAndDefaultAspectRatio() { overrideDefaultAspectRatio(1.0f); // The min size's aspect ratio is greater than the default aspect ratio. - final Size overrideMinSize = new Size(120, 150); + final Size tallerSize = mSizeSpecSource.getDefaultSize(0.5f); + final Size overrideMinSize = new Size( + tallerSize.getWidth() / 2, tallerSize.getHeight() / 2); mPipBoundsState.setOverrideMinSize(overrideMinSize); final Rect defaultBounds = mPipBoundsAlgorithm.getDefaultBounds(); @@ -306,10 +310,12 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { DEFAULT_ASPECT_RATIO, (MAX_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2 }; + final Size defaultSize = mSizeSpecSource.getDefaultSize(1.0f); + final int defaultMinHeight = defaultSize.getHeight() / 2; final Size[] minimalSizes = new Size[] { - new Size((int) (200 * aspectRatios[0]), 200), - new Size((int) (200 * aspectRatios[1]), 200), - new Size((int) (200 * aspectRatios[2]), 200) + new Size((int) (defaultMinHeight * aspectRatios[0]), defaultMinHeight), + new Size((int) (defaultMinHeight * aspectRatios[1]), defaultMinHeight), + new Size((int) (defaultMinHeight * aspectRatios[2]), defaultMinHeight) }; for (int i = 0; i < aspectRatios.length; i++) { final float aspectRatio = aspectRatios[i]; @@ -331,15 +337,17 @@ public class PipBoundsAlgorithmTest extends ShellTestCase { @Test public void getAdjustedDestinationBounds_ignoreMinBounds() { - final float aspectRatio = (DEFAULT_ASPECT_RATIO + MAX_ASPECT_RATIO) / 2; - final Rect currentBounds = new Rect(0, 0, 0, 100); - currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left; - final Size minSize = new Size(currentBounds.width() / 2, currentBounds.height() / 2); - - mPipBoundsState.setAspectRatio(aspectRatio); + final float oldAspectRatio = (DEFAULT_ASPECT_RATIO + MAX_ASPECT_RATIO) / 2; + final float newAspectRatio = (DEFAULT_ASPECT_RATIO + MIN_ASPECT_RATIO) / 2; + final Size defaultSize = mSizeSpecSource.getDefaultSize(oldAspectRatio); + final Size minSize = new Size( + defaultSize.getWidth() / 2, defaultSize.getHeight() / 2); + final Rect currentBounds = new Rect(0, 0, defaultSize.getWidth(), defaultSize.getHeight()); + + mPipBoundsState.setAspectRatio(newAspectRatio); mPipBoundsState.setOverrideMinSize(minSize); final Rect destinationBounds = mPipBoundsAlgorithm.getAdjustedDestinationBounds( - currentBounds, aspectRatio); + currentBounds, newAspectRatio); assertTrue("Destination bounds ignores minimal size", destinationBounds.width() > minSize.getWidth() diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java index ad664acfdc37..01b76edd9b25 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipBoundsStateTest.java @@ -51,7 +51,6 @@ import java.util.function.Consumer; @SmallTest public class PipBoundsStateTest extends ShellTestCase { - private static final Size DEFAULT_SIZE = new Size(10, 10); private static final float DEFAULT_SNAP_FRACTION = 1.0f; /** The minimum possible size of the override min size's width or height */ @@ -184,10 +183,14 @@ public class PipBoundsStateTest extends ShellTestCase { @Test public void testSetOverrideMinSize_changed_callbackInvoked() { final Runnable callback = mock(Runnable.class); - mPipBoundsState.setOverrideMinSize(new Size(5, 5)); + mPipBoundsState.setAspectRatio(2f); + final Size defaultSize = mSizeSpecSource.getDefaultSize(mPipBoundsState.getAspectRatio()); + mPipBoundsState.setOverrideMinSize( + new Size(defaultSize.getWidth() / 2, defaultSize.getHeight() / 2)); mPipBoundsState.setOnMinimalSizeChangeCallback(callback); - mPipBoundsState.setOverrideMinSize(new Size(10, 10)); + mPipBoundsState.setOverrideMinSize( + new Size(defaultSize.getWidth() / 4, defaultSize.getHeight() / 4)); verify(callback).run(); } @@ -195,24 +198,47 @@ public class PipBoundsStateTest extends ShellTestCase { @Test public void testSetOverrideMinSize_notChanged_callbackNotInvoked() { final Runnable callback = mock(Runnable.class); - mPipBoundsState.setOverrideMinSize(new Size(100, 150)); + mPipBoundsState.setAspectRatio(2f); + final Size defaultSize = mSizeSpecSource.getDefaultSize(mPipBoundsState.getAspectRatio()); + mPipBoundsState.setOverrideMinSize( + new Size(defaultSize.getWidth() / 2, defaultSize.getHeight() / 2)); mPipBoundsState.setOnMinimalSizeChangeCallback(callback); - mPipBoundsState.setOverrideMinSize(new Size(100, 150)); + mPipBoundsState.setOverrideMinSize( + new Size(defaultSize.getWidth() / 2, defaultSize.getHeight() / 2)); verify(callback, never()).run(); } @Test + public void testSetOverrideMinSize_tooLarge_ignored() { + final Runnable callback = mock(Runnable.class); + mPipBoundsState.setAspectRatio(2f); + final Size defaultSize = mSizeSpecSource.getDefaultSize(mPipBoundsState.getAspectRatio()); + final Size halfSize = new Size(defaultSize.getWidth() / 2, defaultSize.getHeight() / 2); + final Size doubleSize = new Size(defaultSize.getWidth() * 2, defaultSize.getHeight() * 2); + mPipBoundsState.setOverrideMinSize(halfSize); + mPipBoundsState.setOnMinimalSizeChangeCallback(callback); + + mPipBoundsState.setOverrideMinSize(doubleSize); + + assertEquals("Override min size should be ignored", + mPipBoundsState.getOverrideMinSize(), halfSize); + verify(callback, never()).run(); + } + + @Test public void testGetOverrideMinEdgeSize() { mPipBoundsState.setOverrideMinSize(null); assertEquals(0, mPipBoundsState.getOverrideMinEdgeSize()); - mPipBoundsState.setOverrideMinSize(new Size(100, 110)); - assertEquals(100, mPipBoundsState.getOverrideMinEdgeSize()); + mPipBoundsState.setAspectRatio(2f); + final Size defaultSize = mSizeSpecSource.getDefaultSize(mPipBoundsState.getAspectRatio()); + final Size halfSize = new Size(defaultSize.getWidth() / 2, defaultSize.getHeight() / 2); + mPipBoundsState.setOverrideMinSize(halfSize); - mPipBoundsState.setOverrideMinSize(new Size(150, 200)); - assertEquals(150, mPipBoundsState.getOverrideMinEdgeSize()); + assertEquals(Math.min(halfSize.getWidth(), halfSize.getHeight()), + mPipBoundsState.getOverrideMinEdgeSize()); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java index 26688236d5be..c6a0fc3d49db 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java @@ -164,10 +164,12 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void startSwipePipToHome_updatesOverrideMinSize() { - final Size minSize = new Size(400, 320); + final Rational aspectRatio = new Rational(2, 1); + final Size defaultSize = mSizeSpecSource.getDefaultSize(aspectRatio.floatValue()); + final Size minSize = new Size(defaultSize.getWidth() / 2, defaultSize.getHeight() / 2); mPipTaskOrganizer.startSwipePipToHome(mComponent1, createActivityInfo(minSize), - createPipParams(null)); + createPipParams(aspectRatio)); assertEquals(minSize, mPipBoundsState.getOverrideMinSize()); } @@ -192,10 +194,12 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskAppeared_updatesOverrideMinSize() { - final Size minSize = new Size(400, 320); + final Rational aspectRatio = new Rational(2, 1); + final Size defaultSize = mSizeSpecSource.getDefaultSize(aspectRatio.floatValue()); + final Size minSize = new Size(defaultSize.getWidth() / 2, defaultSize.getHeight() / 2); mPipTaskOrganizer.onTaskAppeared( - createTaskInfo(mComponent1, createPipParams(null), minSize), + createTaskInfo(mComponent1, createPipParams(aspectRatio), minSize), mock(SurfaceControl.class)); assertEquals(minSize, mPipBoundsState.getOverrideMinSize()); @@ -248,13 +252,15 @@ public class PipTaskOrganizerTest extends ShellTestCase { @Test public void onTaskInfoChanged_inPip_updatesOverrideMinSize() { + final Rational aspectRatio = new Rational(2, 1); + final Size defaultSize = mSizeSpecSource.getDefaultSize(aspectRatio.floatValue()); + final Size minSize = new Size(defaultSize.getWidth() / 2, defaultSize.getHeight() / 2); mPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, - createPipParams(null)), mock(SurfaceControl.class)); + createPipParams(aspectRatio)), mock(SurfaceControl.class)); sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); - final Size minSize = new Size(400, 320); mPipTaskOrganizer.onTaskInfoChanged(createTaskInfo(mComponent2, - createPipParams(null), minSize)); + createPipParams(aspectRatio), minSize)); assertEquals(minSize, mPipBoundsState.getOverrideMinSize()); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 6cd1336122be..09e2ffd54248 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -2170,25 +2170,29 @@ class Task extends TaskFragment { void adjustForMinimalTaskDimensions(@NonNull Rect bounds, @NonNull Rect previousBounds, @NonNull Configuration parentConfig) { - int minWidth = mMinWidth; - int minHeight = mMinHeight; // If the task has no requested minimal size, we'd like to enforce a minimal size // so that the user can not render the task fragment too small to manipulate. We don't need // to do this for the root pinned task as the bounds are controlled by the system. - if (!inPinnedWindowingMode()) { - // Use Display specific min sizes when there is one associated with this Task. - final int defaultMinSizeDp = mDisplayContent == null - ? DEFAULT_MIN_TASK_SIZE_DP : mDisplayContent.mMinSizeOfResizeableTaskDp; - final float density = (float) parentConfig.densityDpi / DisplayMetrics.DENSITY_DEFAULT; - final int defaultMinSize = (int) (defaultMinSizeDp * density); + if (inPinnedWindowingMode()) { + Slog.i(TAG, "Skip adjustForMinimalTaskDimensions for pip task"); + return; + } - if (minWidth == INVALID_MIN_SIZE) { - minWidth = defaultMinSize; - } - if (minHeight == INVALID_MIN_SIZE) { - minHeight = defaultMinSize; - } + int minWidth = mMinWidth; + int minHeight = mMinHeight; + // Use Display specific min sizes when there is one associated with this Task. + final int defaultMinSizeDp = mDisplayContent == null + ? DEFAULT_MIN_TASK_SIZE_DP : mDisplayContent.mMinSizeOfResizeableTaskDp; + final float density = (float) parentConfig.densityDpi / DisplayMetrics.DENSITY_DEFAULT; + final int defaultMinSize = (int) (defaultMinSizeDp * density); + + if (minWidth == INVALID_MIN_SIZE) { + minWidth = defaultMinSize; + } + if (minHeight == INVALID_MIN_SIZE) { + minHeight = defaultMinSize; } + if (bounds.isEmpty()) { // If inheriting parent bounds, check if parent bounds adhere to minimum size. If they // do, we can just skip. |