diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index b946e7e060443..7ada2135212c2 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -8307,6 +8307,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A * requested in the config or via an ADB command. For more context see {@link * LetterboxUiController#getHorizontalPositionMultiplier(Configuration)} and * {@link LetterboxUiController#getVerticalPositionMultiplier(Configuration)} + *

+ * Note that this is the final step that can change the resolved bounds. After this method + * is called, the position of the bounds will be moved to app space as sandboxing if the + * activity has a size compat scale. */ private void updateResolvedBoundsPosition(Configuration newParentConfiguration) { final Configuration resolvedConfig = getResolvedOverrideConfiguration(); @@ -8368,6 +8372,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // Since bounds has changed, the configuration needs to be computed accordingly. getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration); + + // The position of configuration bounds were calculated in screen space because that is + // easier to resolve the relative position in parent container. However, if the activity is + // scaled, the position should follow the scale because the configuration will be sent to + // the client which is expected to be in a scaled environment. + if (mSizeCompatScale != 1f) { + final int screenPosX = resolvedBounds.left; + final int screenPosY = resolvedBounds.top; + final int dx = (int) (screenPosX / mSizeCompatScale + 0.5f) - screenPosX; + final int dy = (int) (screenPosY / mSizeCompatScale + 0.5f) - screenPosY; + offsetBounds(resolvedConfig, dx, dy); + } } void recomputeConfiguration() { diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index d77b6ada268e0..4eb070df0e47b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -573,11 +573,11 @@ public class SizeCompatTests extends WindowTestsBase { // The scale is 2000/2500=0.8. The horizontal centered offset is (1000-(1000*0.8))/2=100. final float scale = (float) display.mBaseDisplayHeight / currentBounds.height(); final int offsetX = (int) (display.mBaseDisplayWidth - (origBounds.width() * scale)) / 2; - assertEquals(offsetX, currentBounds.left); + final int screenX = mActivity.getBounds().left; + assertEquals(offsetX, screenX); - // The position of configuration bounds should be the same as compat bounds. - assertEquals(mActivity.getBounds().left, currentBounds.left); - assertEquals(mActivity.getBounds().top, currentBounds.top); + // The position of configuration bounds should be in app space. + assertEquals(screenX, (int) (currentBounds.left * scale + 0.5f)); // Activity is sandboxed to the offset size compat bounds. assertActivityMaxBoundsSandboxed(); @@ -607,7 +607,7 @@ public class SizeCompatTests extends WindowTestsBase { // The size should still be in portrait [100, 0 - 1100, 2500] = 1000x2500. assertEquals(origBounds.width(), currentBounds.width()); assertEquals(origBounds.height(), currentBounds.height()); - assertEquals(offsetX, currentBounds.left); + assertEquals(offsetX, mActivity.getBounds().left); assertScaled(); // Activity is sandboxed due to size compat mode. assertActivityMaxBoundsSandboxed(); @@ -770,9 +770,11 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(origAppBounds.height(), appBounds.height()); // The activity is 1000x1400 and the display is 2500x1000. assertScaled(); - // The position in configuration should be global coordinates. - assertEquals(mActivity.getBounds().left, currentBounds.left); - assertEquals(mActivity.getBounds().top, currentBounds.top); + final float scale = mActivity.getCompatScale(); + // The position in configuration should be in app coordinates. + final Rect screenBounds = mActivity.getBounds(); + assertEquals(screenBounds.left, (int) (currentBounds.left * scale + 0.5f)); + assertEquals(screenBounds.top, (int) (currentBounds.top * scale + 0.5f)); // Activity max bounds are sandboxed due to size compat mode. assertActivityMaxBoundsSandboxed();