Respect min/max aspect ratio in freeform launch bounds

Bug: 194520339
Test: atest WmTests:TaskLaunchParamsModifierTests
Change-Id: I99f86ea49bc62df3fe3861fd25992c3f4e8d1136
This commit is contained in:
jorgegil@google.com
2021-08-10 08:49:59 -07:00
parent 55290e4d16
commit c99afb71e2
2 changed files with 142 additions and 4 deletions

View File

@@ -713,7 +713,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
// First we get the default size we want.
getDefaultFreeformSize(displayArea, layout, orientation, mTmpBounds);
getDefaultFreeformSize(root.info, displayArea, layout, orientation, mTmpBounds);
if (hasInitialBounds || sizeMatches(inOutBounds, mTmpBounds)) {
// We're here because either input parameters specified initial bounds, or the suggested
// bounds have the same size of the default freeform size. We should use the suggested
@@ -781,7 +781,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
return orientation;
}
private void getDefaultFreeformSize(@NonNull TaskDisplayArea displayArea,
private void getDefaultFreeformSize(@NonNull ActivityInfo info,
@NonNull TaskDisplayArea displayArea,
@NonNull ActivityInfo.WindowLayout layout, int orientation, @NonNull Rect bounds) {
// Default size, which is letterboxing/pillarboxing in displayArea. That's to say the large
// dimension of default size is the small dimension of displayArea size, and the small
@@ -812,11 +813,38 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
final int layoutMinWidth = (layout == null) ? -1 : layout.minWidth;
final int layoutMinHeight = (layout == null) ? -1 : layout.minHeight;
// Final result.
// Aspect ratio requirements.
final float minAspectRatio = info.getMinAspectRatio();
final float maxAspectRatio = info.getMaxAspectRatio();
final int width = Math.min(defaultWidth, Math.max(phoneWidth, layoutMinWidth));
final int height = Math.min(defaultHeight, Math.max(phoneHeight, layoutMinHeight));
final float aspectRatio = (float) Math.max(width, height) / (float) Math.min(width, height);
bounds.set(0, 0, width, height);
// Adjust the width and height to the aspect ratio requirements.
int adjWidth = width;
int adjHeight = height;
if (minAspectRatio >= 1 && aspectRatio < minAspectRatio) {
// The aspect ratio is below the minimum, adjust it to the minimum.
if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
// Fix the width, scale the height.
adjHeight = (int) (adjWidth / minAspectRatio + 0.5f);
} else {
// Fix the height, scale the width.
adjWidth = (int) (adjHeight / minAspectRatio + 0.5f);
}
} else if (maxAspectRatio >= 1 && aspectRatio > maxAspectRatio) {
// The aspect ratio exceeds the maximum, adjust it to the maximum.
if (orientation == SCREEN_ORIENTATION_LANDSCAPE) {
// Fix the width, scale the height.
adjHeight = (int) (adjWidth / maxAspectRatio + 0.5f);
} else {
// Fix the height, scale the width.
adjWidth = (int) (adjHeight / maxAspectRatio + 0.5f);
}
}
bounds.set(0, 0, adjWidth, adjHeight);
bounds.offset(stableBounds.left, stableBounds.top);
}

View File

@@ -1320,6 +1320,50 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
DISPLAY_STABLE_BOUNDS.bottom - mResult.mBounds.bottom, /* delta */ 1);
}
@Test
public void testDefaultFreeformSizeRespectsMinAspectRatio() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
mActivity.info.setMinAspectRatio(5f);
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder()
.setOptions(options).calculate());
final float aspectRatio =
(float) Math.max(mResult.mBounds.width(), mResult.mBounds.height())
/ (float) Math.min(mResult.mBounds.width(), mResult.mBounds.height());
assertTrue("Bounds aspect ratio should be at least 5.0, but was " + aspectRatio,
aspectRatio >= 5f);
}
@Test
public void testDefaultFreeformSizeRespectsMaxAspectRatio() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
mActivity.info.setMaxAspectRatio(1.5f);
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder()
.setOptions(options).calculate());
final float aspectRatio =
(float) Math.max(mResult.mBounds.width(), mResult.mBounds.height())
/ (float) Math.min(mResult.mBounds.width(), mResult.mBounds.height());
assertTrue("Bounds aspect ratio should be at most 1.5, but was " + aspectRatio,
aspectRatio <= 1.5f);
}
@Test
public void testCascadesToSourceSizeForFreeform() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
@@ -1347,6 +1391,72 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
mResult.mBounds.centerY() < displayBounds.centerY());
}
@Test
public void testCascadesToSourceSizeForFreeformRespectingMinAspectRatio() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
final ActivityRecord source = createSourceActivity(freeformDisplay);
source.setBounds(0, 0, 412, 732);
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
mActivity.info.setMinAspectRatio(5f);
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setSource(source).setOptions(options).calculate());
final Rect displayBounds = freeformDisplay.getBounds();
assertTrue("Left bounds should be larger than 0.", mResult.mBounds.left > 0);
assertTrue("Top bounds should be larger than 0.", mResult.mBounds.top > 0);
assertTrue("Bounds should be centered at somewhere in the left half, but it's "
+ "centerX is " + mResult.mBounds.centerX(),
mResult.mBounds.centerX() < displayBounds.centerX());
assertTrue("Bounds should be centered at somewhere in the top half, but it's "
+ "centerY is " + mResult.mBounds.centerY(),
mResult.mBounds.centerY() < displayBounds.centerY());
final float aspectRatio =
(float) Math.max(mResult.mBounds.width(), mResult.mBounds.height())
/ (float) Math.min(mResult.mBounds.width(), mResult.mBounds.height());
assertTrue("Bounds aspect ratio should be at least 5.0, but was " + aspectRatio,
aspectRatio >= 5f);
}
@Test
public void testCascadesToSourceSizeForFreeformRespectingMaxAspectRatio() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
final ActivityRecord source = createSourceActivity(freeformDisplay);
source.setBounds(0, 0, 412, 732);
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
mActivity.info.setMaxAspectRatio(1.5f);
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setSource(source).setOptions(options).calculate());
final Rect displayBounds = freeformDisplay.getBounds();
assertTrue("Left bounds should be larger than 0.", mResult.mBounds.left > 0);
assertTrue("Top bounds should be larger than 0.", mResult.mBounds.top > 0);
assertTrue("Bounds should be centered at somewhere in the left half, but it's "
+ "centerX is " + mResult.mBounds.centerX(),
mResult.mBounds.centerX() < displayBounds.centerX());
assertTrue("Bounds should be centered at somewhere in the top half, but it's "
+ "centerY is " + mResult.mBounds.centerY(),
mResult.mBounds.centerY() < displayBounds.centerY());
final float aspectRatio =
(float) Math.max(mResult.mBounds.width(), mResult.mBounds.height())
/ (float) Math.min(mResult.mBounds.width(), mResult.mBounds.height());
assertTrue("Bounds aspect ratio should be at most 1.5, but was " + aspectRatio,
aspectRatio <= 1.5f);
}
@Test
public void testAdjustBoundsToFitDisplay_TopLeftOutOfDisplay() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(