Merge "Use stable frame to position freeform windows."
This commit is contained in:
committed by
Android (Google) Code Review
commit
5237275f5d
@@ -398,9 +398,11 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
|
||||
return;
|
||||
}
|
||||
|
||||
final Rect bounds = display.getBounds();
|
||||
final int defaultWidth = bounds.width();
|
||||
final int defaultHeight = bounds.height();
|
||||
// Use stable frame instead of raw frame to avoid launching freeform windows on top of
|
||||
// stable insets, which usually are system widgets such as sysbar & navbar.
|
||||
final Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
|
||||
final int defaultWidth = displayStableBounds.width();
|
||||
final int defaultHeight = displayStableBounds.height();
|
||||
|
||||
int width;
|
||||
int height;
|
||||
@@ -451,6 +453,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
|
||||
}
|
||||
|
||||
outBounds.set(0, 0, width, height);
|
||||
outBounds.offset(displayStableBounds.left, displayStableBounds.top);
|
||||
final int xOffset = (int) (fractionOfHorizontalOffset * (defaultWidth - width));
|
||||
final int yOffset = (int) (fractionOfVerticalOffset * (defaultHeight - height));
|
||||
outBounds.offset(xOffset, yOffset);
|
||||
@@ -627,10 +630,14 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
|
||||
@NonNull ActivityInfo.WindowLayout layout, int orientation, @NonNull Rect bounds) {
|
||||
// Default size, which is letterboxing/pillarboxing in display. That's to say the large
|
||||
// dimension of default size is the small dimension of display size, and the small dimension
|
||||
// of default size is calculated to keep the same aspect ratio as the display's.
|
||||
Rect displayBounds = display.getBounds();
|
||||
final int portraitHeight = Math.min(displayBounds.width(), displayBounds.height());
|
||||
final int otherDimension = Math.max(displayBounds.width(), displayBounds.height());
|
||||
// of default size is calculated to keep the same aspect ratio as the display's. Here we use
|
||||
// stable bounds of displays because that indicates the area that isn't occupied by system
|
||||
// widgets (e.g. sysbar and navbar).
|
||||
Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
|
||||
final int portraitHeight =
|
||||
Math.min(displayStableBounds.width(), displayStableBounds.height());
|
||||
final int otherDimension =
|
||||
Math.max(displayStableBounds.width(), displayStableBounds.height());
|
||||
final int portraitWidth = (portraitHeight * portraitHeight) / otherDimension;
|
||||
final int defaultWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitHeight
|
||||
: portraitWidth;
|
||||
@@ -656,16 +663,17 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
|
||||
final int height = Math.min(defaultHeight, Math.max(phoneHeight, layoutMinHeight));
|
||||
|
||||
bounds.set(0, 0, width, height);
|
||||
bounds.offset(displayStableBounds.left, displayStableBounds.top);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets centered bounds of width x height. If inOutBounds is not empty, the result bounds
|
||||
* centers at its center or display's center if inOutBounds is empty.
|
||||
* centers at its center or display's app bounds center if inOutBounds is empty.
|
||||
*/
|
||||
private void centerBounds(@NonNull ActivityDisplay display, int width, int height,
|
||||
@NonNull Rect inOutBounds) {
|
||||
if (inOutBounds.isEmpty()) {
|
||||
display.getBounds(inOutBounds);
|
||||
inOutBounds.set(display.mDisplayContent.mDisplayFrames.mStable);
|
||||
}
|
||||
final int left = inOutBounds.centerX() - width / 2;
|
||||
final int top = inOutBounds.centerY() - height / 2;
|
||||
@@ -674,40 +682,40 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
|
||||
|
||||
private void adjustBoundsToFitInDisplay(@NonNull ActivityDisplay display,
|
||||
@NonNull Rect inOutBounds) {
|
||||
final Rect displayBounds = display.getBounds();
|
||||
final Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable;
|
||||
|
||||
if (displayBounds.width() < inOutBounds.width()
|
||||
|| displayBounds.height() < inOutBounds.height()) {
|
||||
if (displayStableBounds.width() < inOutBounds.width()
|
||||
|| displayStableBounds.height() < inOutBounds.height()) {
|
||||
// There is no way for us to fit the bounds in the display without changing width
|
||||
// or height. Just move the start to align with the display.
|
||||
final int layoutDirection =
|
||||
mSupervisor.mRootActivityContainer.getConfiguration().getLayoutDirection();
|
||||
final int left = layoutDirection == View.LAYOUT_DIRECTION_RTL
|
||||
? displayBounds.width() - inOutBounds.width()
|
||||
: 0;
|
||||
inOutBounds.offsetTo(left, 0 /* newTop */);
|
||||
? displayStableBounds.right - inOutBounds.right + inOutBounds.left
|
||||
: displayStableBounds.left;
|
||||
inOutBounds.offsetTo(left, displayStableBounds.top);
|
||||
return;
|
||||
}
|
||||
|
||||
final int dx;
|
||||
if (inOutBounds.right > displayBounds.right) {
|
||||
if (inOutBounds.right > displayStableBounds.right) {
|
||||
// Right edge is out of display.
|
||||
dx = displayBounds.right - inOutBounds.right;
|
||||
} else if (inOutBounds.left < displayBounds.left) {
|
||||
dx = displayStableBounds.right - inOutBounds.right;
|
||||
} else if (inOutBounds.left < displayStableBounds.left) {
|
||||
// Left edge is out of display.
|
||||
dx = displayBounds.left - inOutBounds.left;
|
||||
dx = displayStableBounds.left - inOutBounds.left;
|
||||
} else {
|
||||
// Vertical edges are all in display.
|
||||
dx = 0;
|
||||
}
|
||||
|
||||
final int dy;
|
||||
if (inOutBounds.top < displayBounds.top) {
|
||||
if (inOutBounds.top < displayStableBounds.top) {
|
||||
// Top edge is out of display.
|
||||
dy = displayBounds.top - inOutBounds.top;
|
||||
} else if (inOutBounds.bottom > displayBounds.bottom) {
|
||||
dy = displayStableBounds.top - inOutBounds.top;
|
||||
} else if (inOutBounds.bottom > displayStableBounds.bottom) {
|
||||
// Bottom edge is out of display.
|
||||
dy = displayBounds.bottom - inOutBounds.bottom;
|
||||
dy = displayStableBounds.bottom - inOutBounds.bottom;
|
||||
} else {
|
||||
// Horizontal edges are all in display.
|
||||
dy = 0;
|
||||
|
||||
@@ -29,6 +29,8 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.util.DisplayMetrics.DENSITY_DEFAULT;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
|
||||
import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
|
||||
|
||||
@@ -65,6 +67,10 @@ import java.util.Locale;
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
private static final Rect DISPLAY_BOUNDS = new Rect(/* left */ 0, /* top */ 0,
|
||||
/* right */ 1920, /* bottom */ 1080);
|
||||
private static final Rect DISPLAY_STABLE_BOUNDS = new Rect(/* left */ 100,
|
||||
/* top */ 200, /* right */ 1620, /* bottom */ 680);
|
||||
|
||||
private ActivityRecord mActivity;
|
||||
|
||||
@@ -614,7 +620,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(0, mResult.mBounds.left);
|
||||
assertEquals(DISPLAY_STABLE_BOUNDS.left, mResult.mBounds.left);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -630,7 +636,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(0, mResult.mBounds.top);
|
||||
assertEquals(DISPLAY_STABLE_BOUNDS.top, mResult.mBounds.top);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -646,8 +652,8 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(0, mResult.mBounds.left);
|
||||
assertEquals(0, mResult.mBounds.top);
|
||||
assertEquals(DISPLAY_STABLE_BOUNDS.left, mResult.mBounds.left);
|
||||
assertEquals(DISPLAY_STABLE_BOUNDS.top, mResult.mBounds.top);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -663,7 +669,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(1920, mResult.mBounds.right);
|
||||
assertEquals(DISPLAY_STABLE_BOUNDS.right, mResult.mBounds.right);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -679,7 +685,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(1080, mResult.mBounds.bottom);
|
||||
assertEquals(DISPLAY_STABLE_BOUNDS.bottom, mResult.mBounds.bottom);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -695,8 +701,8 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(1920, mResult.mBounds.right);
|
||||
assertEquals(1080, mResult.mBounds.bottom);
|
||||
assertEquals(DISPLAY_STABLE_BOUNDS.right, mResult.mBounds.right);
|
||||
assertEquals(DISPLAY_STABLE_BOUNDS.bottom, mResult.mBounds.bottom);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -712,7 +718,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(900, 500, 1020, 580), mResult.mBounds);
|
||||
assertEquals(new Rect(800, 400, 920, 480), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -728,7 +734,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(0, 500, 120, 580), mResult.mBounds);
|
||||
assertEquals(new Rect(100, 400, 220, 480), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -744,7 +750,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(900, 0, 1020, 80), mResult.mBounds);
|
||||
assertEquals(new Rect(800, 200, 920, 280), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -760,7 +766,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(0, 0, 120, 80), mResult.mBounds);
|
||||
assertEquals(new Rect(100, 200, 220, 280), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -776,7 +782,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(1800, 500, 1920, 580), mResult.mBounds);
|
||||
assertEquals(new Rect(1500, 400, 1620, 480), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -792,7 +798,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(900, 1000, 1020, 1080), mResult.mBounds);
|
||||
assertEquals(new Rect(800, 600, 920, 680), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -808,7 +814,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(1800, 1000, 1920, 1080), mResult.mBounds);
|
||||
assertEquals(new Rect(1500, 600, 1620, 680), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -819,12 +825,12 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
|
||||
|
||||
final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
|
||||
.setWidthFraction(0.0625f).setHeightFraction(0.1f).build();
|
||||
.setWidthFraction(0.125f).setHeightFraction(0.1f).build();
|
||||
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
|
||||
/* source */ null, /* options */ null, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(900, 486, 1020, 594), mResult.mBounds);
|
||||
assertEquals(new Rect(765, 416, 955, 464), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -952,13 +958,12 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
|
||||
mActivity, /* source */ null, options, mCurrent, mResult));
|
||||
|
||||
final Rect displayBounds = freeformDisplay.getBounds();
|
||||
assertEquals("Distance to left and right should be equal.",
|
||||
mResult.mBounds.left - displayBounds.left,
|
||||
displayBounds.right - mResult.mBounds.right);
|
||||
mResult.mBounds.left - DISPLAY_STABLE_BOUNDS.left,
|
||||
DISPLAY_STABLE_BOUNDS.right - mResult.mBounds.right, /* delta */ 1);
|
||||
assertEquals("Distance to top and bottom should be equal.",
|
||||
mResult.mBounds.top - displayBounds.top,
|
||||
displayBounds.bottom - mResult.mBounds.bottom);
|
||||
mResult.mBounds.top - DISPLAY_STABLE_BOUNDS.top,
|
||||
DISPLAY_STABLE_BOUNDS.bottom - mResult.mBounds.bottom, /* delta */ 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1041,15 +1046,16 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
|
||||
|
||||
mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
|
||||
mCurrent.mBounds.set(100, 200, 2120, 1380);
|
||||
mCurrent.mBounds.set(100, 300, 1820, 1380);
|
||||
|
||||
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
|
||||
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
|
||||
mActivity, /* source */ null, options, mCurrent, mResult));
|
||||
|
||||
assertTrue("Result bounds should start from origin, but it's " + mResult.mBounds,
|
||||
mResult.mBounds.left == 0 && mResult.mBounds.top == 0);
|
||||
assertTrue("Result bounds should start from app bounds's origin, but it's "
|
||||
+ mResult.mBounds,
|
||||
mResult.mBounds.left == 100 && mResult.mBounds.top == 200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1067,15 +1073,16 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
|
||||
|
||||
mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
|
||||
mCurrent.mBounds.set(100, 200, 2120, 1380);
|
||||
mCurrent.mBounds.set(100, 300, 1820, 1380);
|
||||
|
||||
mActivity.info.applicationInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
|
||||
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
|
||||
mActivity, /* source */ null, options, mCurrent, mResult));
|
||||
|
||||
assertTrue("Result bounds should start from origin, but it's " + mResult.mBounds,
|
||||
mResult.mBounds.left == -100 && mResult.mBounds.top == 0);
|
||||
assertTrue("Result bounds should start from top-right corner of app bounds, but "
|
||||
+ "it's " + mResult.mBounds,
|
||||
mResult.mBounds.left == -100 && mResult.mBounds.top == 200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1083,6 +1090,11 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
|
||||
WINDOWING_MODE_FREEFORM);
|
||||
|
||||
// This test case requires a relatively big app bounds to ensure the default size calculated
|
||||
// by letterbox won't be too small to hold the minimum width/height.
|
||||
freeformDisplay.mDisplayContent.mDisplayFrames.mStable.set(/* left */ 10, /* top */ 10,
|
||||
/* right */ 1910, /* top */ 1070);
|
||||
|
||||
final ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
|
||||
|
||||
@@ -1245,7 +1257,7 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
|
||||
mActivity, /* source */ null, options, mCurrent, mResult));
|
||||
|
||||
assertEquals(new Rect(0, 0, 300, 300), mResult.mBounds);
|
||||
assertEquals(new Rect(100, 200, 400, 500), mResult.mBounds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1301,9 +1313,15 @@ public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
|
||||
private TestActivityDisplay createNewActivityDisplay(int windowingMode) {
|
||||
final TestActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
|
||||
display.setWindowingMode(windowingMode);
|
||||
display.setBounds(/* left */ 0, /* top */ 0, /* right */ 1920, /* bottom */ 1080);
|
||||
display.setBounds(DISPLAY_BOUNDS);
|
||||
display.getConfiguration().densityDpi = DENSITY_DEFAULT;
|
||||
display.getConfiguration().orientation = ORIENTATION_LANDSCAPE;
|
||||
display.mDisplayContent.mDisplayFrames.mStable.set(DISPLAY_STABLE_BOUNDS);
|
||||
spyOn(display.mDisplayContent.mDisplayFrames);
|
||||
|
||||
// We didn't set up the overall environment for this test, so we need to mute the side
|
||||
// effect of layout passes that loosen the stable frame.
|
||||
doNothing().when(display.mDisplayContent.mDisplayFrames).onBeginLayout();
|
||||
return display;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user