summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Garfield Tan <xutan@google.com> 2019-09-30 18:08:17 -0700
committer Garfield Tan <xutan@google.com> 2019-10-02 09:53:56 -0700
commit23f67518ea367cfe0fcfd6764eb0270937e641b5 (patch)
tree076a6cc9f91fd6a2ea68308f018cbef23c828c06
parent22562664e9cc1114a1918fd939dca8a97103f144 (diff)
Use stable frame to position freeform windows.
We should generally speaking avoid launching apps behind stable insets by default, unless either app requests to do it or user has moved the app to there previously. Bug: 139274545 Test: ManifestLayoutTests failures indicate windows are put out of stable insets. Still need CTS fix to finally fix that test case. Test: atest TaskLaunchParamsModifierTests Change-Id: I8bc5d23d2ae87f8343aef18023ee7b4fcf9a1bed
-rw-r--r--services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java54
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java78
2 files changed, 79 insertions, 53 deletions
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index 1c015d0787dd..9712277495df 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -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;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index e6c9b9f7a160..dd85f69b7160 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -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;
}