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

Commit 292826ee authored by Mariia Sandrikova's avatar Mariia Sandrikova
Browse files

Add a way to disable auto rotation for immersive apps

Provide a way to always show a rotation button instead of auto rotating for immersive applications when the following conditions are met:
1) Top activity requests to hide status and navigation bars
2) Top activity is fullscreen and in optimal orientation (without letterboxing)
3) Rotation will lead to letterboxing due to fixed orientation.
4) ignoreOrientationRequest is enabled and config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled is enabled

This is needed because immersive apps, such as games, are often not optimized for all orientations and can have a poor UX when rotated. Additionally, some games relying on sensors for the gameplay so users can trigger such rotations accidentally when auto rotation is on.

Test: atest LetterboxConfigurationDeviceConfigTests DisplayRotationCompatPolicyForImmersiveAppsTests
Bug: 251404186
Change-Id: I0b5d8f666b8bec9bd9d6fb5303986d3c288e283f
parent 60632570
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -5245,6 +5245,14 @@
         having a separating hinge. -->
         having a separating hinge. -->
    <bool name="config_isDisplayHingeAlwaysSeparating">false</bool>
    <bool name="config_isDisplayHingeAlwaysSeparating">false</bool>


    <!-- Whether enabling rotation compat policy for immersive apps that prevents auto rotation
         into non-optimal screen orientation while in fullscreen. This is needed because immersive
         apps, such as games, are often not optimized for all orientations and can have a poor UX
         when rotated. Additionally, some games rely on sensors for the gameplay so users can
         trigger such rotations accidentally when auto rotation is on.
         Applicable only if ignoreOrientationRequest is enabled. -->
    <bool name="config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled">false</bool>

    <!-- Aspect ratio of letterboxing for fixed orientation. Values <= 1.0 will be ignored.
    <!-- Aspect ratio of letterboxing for fixed orientation. Values <= 1.0 will be ignored.
         Note: Activity min/max aspect ratio restrictions will still be respected.
         Note: Activity min/max aspect ratio restrictions will still be respected.
         Therefore this override can control the maximum screen area that can be occupied by
         Therefore this override can control the maximum screen area that can be occupied by
+1 −0
Original line number Original line Diff line number Diff line
@@ -4413,6 +4413,7 @@
  <java-symbol type="dimen" name="controls_thumbnail_image_max_height" />
  <java-symbol type="dimen" name="controls_thumbnail_image_max_height" />
  <java-symbol type="dimen" name="controls_thumbnail_image_max_width" />
  <java-symbol type="dimen" name="controls_thumbnail_image_max_width" />


  <java-symbol type="bool" name="config_letterboxIsDisplayRotationImmersiveAppCompatPolicyEnabled" />
  <java-symbol type="dimen" name="config_fixedOrientationLetterboxAspectRatio" />
  <java-symbol type="dimen" name="config_fixedOrientationLetterboxAspectRatio" />
  <java-symbol type="dimen" name="config_letterboxBackgroundWallpaperBlurRadius" />
  <java-symbol type="dimen" name="config_letterboxBackgroundWallpaperBlurRadius" />
  <java-symbol type="integer" name="config_letterboxActivityCornersRadius" />
  <java-symbol type="integer" name="config_letterboxActivityCornersRadius" />
+2 −1
Original line number Original line Diff line number Diff line
@@ -249,7 +249,8 @@ public class RotationButtonController {
    }
    }


    public void setRotationLockedAtAngle(int rotationSuggestion) {
    public void setRotationLockedAtAngle(int rotationSuggestion) {
        RotationPolicy.setRotationLockAtAngle(mContext, true, rotationSuggestion);
        RotationPolicy.setRotationLockAtAngle(mContext, /* enabled= */ isRotationLocked(),
                /* rotation= */ rotationSuggestion);
    }
    }


    public boolean isRotationLocked() {
    public boolean isRotationLocked() {
+1 −0
Original line number Original line Diff line number Diff line
@@ -6024,6 +6024,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        }
        }
    }
    }


    @Nullable
    ActivityRecord topRunningActivity() {
    ActivityRecord topRunningActivity() {
        return topRunningActivity(false /* considerKeyguardState */);
        return topRunningActivity(false /* considerKeyguardState */);
    }
    }
+27 −9
Original line number Original line Diff line number Diff line
@@ -100,6 +100,8 @@ public class DisplayRotation {
    private final DisplayWindowSettings mDisplayWindowSettings;
    private final DisplayWindowSettings mDisplayWindowSettings;
    private final Context mContext;
    private final Context mContext;
    private final Object mLock;
    private final Object mLock;
    @Nullable
    private final DisplayRotationImmersiveAppCompatPolicy mCompatPolicyForImmersiveApps;


    public final boolean isDefaultDisplay;
    public final boolean isDefaultDisplay;
    private final boolean mSupportAutoRotation;
    private final boolean mSupportAutoRotation;
@@ -205,7 +207,7 @@ public class DisplayRotation {


    /**
    /**
     * A flag to indicate if the display rotation should be fixed to user specified rotation
     * A flag to indicate if the display rotation should be fixed to user specified rotation
     * regardless of all other states (including app requrested orientation). {@code true} the
     * regardless of all other states (including app requested orientation). {@code true} the
     * display rotation should be fixed to user specified rotation, {@code false} otherwise.
     * display rotation should be fixed to user specified rotation, {@code false} otherwise.
     */
     */
    private int mFixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
    private int mFixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
@@ -232,6 +234,7 @@ public class DisplayRotation {
        mContext = context;
        mContext = context;
        mLock = lock;
        mLock = lock;
        isDefaultDisplay = displayContent.isDefaultDisplay;
        isDefaultDisplay = displayContent.isDefaultDisplay;
        mCompatPolicyForImmersiveApps = initImmersiveAppCompatPolicy(service, displayContent);


        mSupportAutoRotation =
        mSupportAutoRotation =
                mContext.getResources().getBoolean(R.bool.config_supportAutoRotation);
                mContext.getResources().getBoolean(R.bool.config_supportAutoRotation);
@@ -255,6 +258,14 @@ public class DisplayRotation {
        }
        }
    }
    }


    @VisibleForTesting
    @Nullable
    DisplayRotationImmersiveAppCompatPolicy initImmersiveAppCompatPolicy(
                WindowManagerService service, DisplayContent displayContent) {
        return DisplayRotationImmersiveAppCompatPolicy.createIfNeeded(
                service.mLetterboxConfiguration, this, displayContent);
    }

    // Change the default value to the value specified in the sysprop
    // Change the default value to the value specified in the sysprop
    // ro.bootanim.set_orientation_<display_id>. Four values are supported: ORIENTATION_0,
    // ro.bootanim.set_orientation_<display_id>. Four values are supported: ORIENTATION_0,
    // ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270.
    // ORIENTATION_90, ORIENTATION_180 and ORIENTATION_270.
@@ -1305,11 +1316,11 @@ public class DisplayRotation {
        return mAllowAllRotations;
        return mAllowAllRotations;
    }
    }


    private boolean isLandscapeOrSeascape(int rotation) {
    boolean isLandscapeOrSeascape(@Surface.Rotation final int rotation) {
        return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
        return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
    }
    }


    private boolean isAnyPortrait(int rotation) {
    boolean isAnyPortrait(@Surface.Rotation final int rotation) {
        return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
        return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
    }
    }


@@ -1348,9 +1359,16 @@ public class DisplayRotation {
        return mFoldController != null && mFoldController.overrideFrozenRotation();
        return mFoldController != null && mFoldController.overrideFrozenRotation();
    }
    }


    private boolean isRotationChoicePossible(int orientation) {
    private boolean isRotationChoiceAllowed(@Surface.Rotation final int proposedRotation) {
        // Rotation choice is only shown when the user is in locked mode.
        final boolean isRotationLockEnforced = mCompatPolicyForImmersiveApps != null
        if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
                && mCompatPolicyForImmersiveApps.isRotationLockEnforced(proposedRotation);

        // Don't show rotation choice button if
        if (!isRotationLockEnforced // not enforcing locked rotation
                // and the screen rotation is not locked by the user.
                && mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) {
            return false;
        }


        // Don't show rotation choice if we are in tabletop or book modes.
        // Don't show rotation choice if we are in tabletop or book modes.
        if (isTabletopAutoRotateOverrideEnabled()) return false;
        if (isTabletopAutoRotateOverrideEnabled()) return false;
@@ -1402,7 +1420,7 @@ public class DisplayRotation {
        }
        }


        // Ensure that some rotation choice is possible for the given orientation.
        // Ensure that some rotation choice is possible for the given orientation.
        switch (orientation) {
        switch (mCurrentAppOrientation) {
            case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
            case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
            case ActivityInfo.SCREEN_ORIENTATION_USER:
            case ActivityInfo.SCREEN_ORIENTATION_USER:
            case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
            case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
@@ -1719,11 +1737,11 @@ public class DisplayRotation {




        @Override
        @Override
        public void onProposedRotationChanged(int rotation) {
        public void onProposedRotationChanged(@Surface.Rotation int rotation) {
            ProtoLog.v(WM_DEBUG_ORIENTATION, "onProposedRotationChanged, rotation=%d", rotation);
            ProtoLog.v(WM_DEBUG_ORIENTATION, "onProposedRotationChanged, rotation=%d", rotation);
            // Send interaction power boost to improve redraw performance.
            // Send interaction power boost to improve redraw performance.
            mService.mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0);
            mService.mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0);
            if (isRotationChoicePossible(mCurrentAppOrientation)) {
            if (isRotationChoiceAllowed(rotation)) {
                final boolean isValid = isValidRotationChoice(rotation);
                final boolean isValid = isValidRotationChoice(rotation);
                sendProposedRotationChangeToStatusBarInternal(rotation, isValid);
                sendProposedRotationChangeToStatusBarInternal(rotation, isValid);
            } else {
            } else {
Loading