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

Commit d32bda7b authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Don't ignore app requested rotation on near-square screens

... because it causes compatibility issues resulting in broken
layouts or crashes. Near square is a screen with aspect ratio <1.33.

Bug: 166059443
Bug: 123507947
Bug: 129909104
Test: Verify app-requested rotation on a near-square screen
Change-Id: I05a338b526d3af07d3e482e650259a882ed76090
parent ac88fb39
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -6643,8 +6643,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        final Configuration resolvedConfig = getResolvedOverrideConfiguration();
        final Configuration resolvedConfig = getResolvedOverrideConfiguration();
        final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
        final Rect resolvedBounds = resolvedConfig.windowConfiguration.getBounds();
        final int requestedOrientation = getRequestedConfigurationOrientation();
        final int requestedOrientation = getRequestedConfigurationOrientation();
        final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED
        final boolean orientationRequested = requestedOrientation != ORIENTATION_UNDEFINED;
                && !mDisplayContent.ignoreRotationForApps();
        final int orientation = orientationRequested
        final int orientation = orientationRequested
                ? requestedOrientation
                ? requestedOrientation
                : newParentConfiguration.orientation;
                : newParentConfiguration.orientation;
+0 −32
Original line number Original line Diff line number Diff line
@@ -28,7 +28,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
@@ -366,13 +365,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    @VisibleForTesting
    @VisibleForTesting
    final float mCloseToSquareMaxAspectRatio;
    final float mCloseToSquareMaxAspectRatio;


    /**
     * If this is true, we would not rotate the display for apps. The rotation would be either the
     * sensor rotation or the user rotation, controlled by
     * {@link WindowManagerPolicy.UserRotationMode}.
     */
    private boolean mIgnoreRotationForApps;

    /**
    /**
     * Keep track of wallpaper visibility to notify changes.
     * Keep track of wallpaper visibility to notify changes.
     */
     */
@@ -1751,26 +1743,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp


        mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
        mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
                calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
                calculateDisplayCutoutForRotation(mDisplayInfo.rotation));

        // Not much of use to rotate the display for apps since it's close to square.
        mIgnoreRotationForApps = isNonDecorDisplayCloseToSquare(Surface.ROTATION_0, width, height);
    }

    /** @return {@code true} if the orientation requested from application will be ignored. */
    boolean ignoreRotationForApps() {
        return mIgnoreRotationForApps;
    }

    private boolean isNonDecorDisplayCloseToSquare(int rotation, int width, int height) {
        final DisplayCutout displayCutout =
                calculateDisplayCutoutForRotation(rotation).getDisplayCutout();
        final int uiMode = mWmService.mPolicy.getUiMode();
        final int w = mDisplayPolicy.getNonDecorDisplayWidth(
                width, height, rotation, uiMode, displayCutout);
        final int h = mDisplayPolicy.getNonDecorDisplayHeight(
                width, height, rotation, uiMode, displayCutout);
        final float aspectRatio = Math.max(w, h) / (float) Math.min(w, h);
        return aspectRatio <= mCloseToSquareMaxAspectRatio;
    }
    }


    /**
    /**
@@ -2336,10 +2308,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    int getOrientation() {
    int getOrientation() {
        mLastOrientationSource = null;
        mLastOrientationSource = null;


        if (mIgnoreRotationForApps) {
            return SCREEN_ORIENTATION_USER;
        }

        if (mWmService.mDisplayFrozen) {
        if (mWmService.mDisplayFrozen) {
            if (mWmService.mPolicy.isKeyguardLocked()) {
            if (mWmService.mPolicy.isKeyguardLocked()) {
                // Use the last orientation the while the display is frozen with the keyguard
                // Use the last orientation the while the display is frozen with the keyguard
+4 −4
Original line number Original line Diff line number Diff line
@@ -24,7 +24,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
import static android.os.Build.VERSION_CODES.P;
import static android.os.Build.VERSION_CODES.P;
import static android.os.Build.VERSION_CODES.Q;
import static android.os.Build.VERSION_CODES.Q;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -762,13 +761,14 @@ public class DisplayContentTests extends WindowTestsBase {
                window.mAttrs.screenOrientation, dc.getOrientation());
                window.mAttrs.screenOrientation, dc.getOrientation());


        // ----------------------------
        // ----------------------------
        // Test close-to-square display
        // Test close-to-square display - should be handled in the same way
        // ----------------------------
        // ----------------------------
        dc.mBaseDisplayHeight = dc.mBaseDisplayWidth;
        dc.mBaseDisplayHeight = dc.mBaseDisplayWidth;
        dc.configureDisplayPolicy();
        dc.configureDisplayPolicy();


        assertEquals("Screen orientation must be SCREEN_ORIENTATION_USER.",
        assertEquals(
                SCREEN_ORIENTATION_USER, dc.getOrientation());
                "Screen orientation must be defined by the window even on close-to-square display.",
                window.mAttrs.screenOrientation, dc.getOrientation());
    }
    }


    @Test
    @Test
+4 −15
Original line number Original line Diff line number Diff line
@@ -138,8 +138,6 @@ public class SizeCompatTests extends WindowTestsBase {
    public void testFixedAspectRatioBoundsWithDecorInSquareDisplay() {
    public void testFixedAspectRatioBoundsWithDecorInSquareDisplay() {
        final int notchHeight = 100;
        final int notchHeight = 100;
        setUpApp(new TestDisplayContent.Builder(mAtm, 600, 800).setNotch(notchHeight).build());
        setUpApp(new TestDisplayContent.Builder(mAtm, 600, 800).setNotch(notchHeight).build());
        // Rotation is ignored so because the display size is close to square (700/600<1.333).
        assertTrue(mActivity.mDisplayContent.ignoreRotationForApps());


        final Rect displayBounds = mActivity.mDisplayContent.getWindowConfiguration().getBounds();
        final Rect displayBounds = mActivity.mDisplayContent.getWindowConfiguration().getBounds();
        final float aspectRatio = 1.2f;
        final float aspectRatio = 1.2f;
@@ -163,23 +161,14 @@ public class SizeCompatTests extends WindowTestsBase {
        mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
        mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
        assertFitted();
        assertFitted();


        // After the orientation of activity is changed, even display is not rotated, the aspect
        // After the orientation of activity is changed, the display is rotated, the aspect
        // ratio should be the same (bounds=[0, 0 - 600, 600], appBounds=[0, 100 - 600, 600]).
        // ratio should be the same (bounds=[100, 0 - 800, 583], appBounds=[100, 0 - 800, 583]).
        assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
        assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */);
        // The notch is still on top.
        // The notch is no longer on top.
        assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight);
        assertEquals(appBounds, mActivity.getBounds());


        mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
        mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
        assertFitted();
        assertFitted();

        // Close-to-square display can rotate without being restricted by the requested orientation.
        // The notch becomes on the left side. The activity is horizontal centered in 100 ~ 800.
        // So the bounds and appBounds will be [200, 0 - 700, 600] (500x600) that is still fitted.
        // Left = 100 + (800 - 100 - 500) / 2 = 200.
        rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
        assertFitted();
        assertEquals(appBounds.left,
                notchHeight + (displayBounds.width() - notchHeight - appBounds.width()) / 2);
    }
    }


    @Test
    @Test