Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ccf766b9 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Set app space position to app configuration

The frames in ClientWindowFrames for client use app coordinate space,
and InsetsState also apply app's scale. So the position of the bounds
in Configuration should be consistent with them.

So the sandbox calculation such as "displayFrame.left - bounds.left"
can be consistent. Previously it may be "appSpace - screenSpace".

In general, ActivityRecord#getBounds() is used for window layout in
server side so it is in screen space.
While record.getWindowConfiguration.getBounds() is used to report to
app so it is in app space.

Fix: 270401710
Test: SizeCompatTests#testFixedScreenBoundsWhenDisplaySizeChanged
      SizeCompatTests#testFixedOrientationRotateCutoutDisplay
Change-Id: Ife48bd5789db7cb9ba32302b345128cd4419a4b6
parent 97cef3f4
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -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)}
     * <p>
     * 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() {
+10 −8
Original line number Diff line number Diff line
@@ -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();