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

Commit e935a92a authored by Tiger Huang's avatar Tiger Huang Committed by Android (Google) Code Review
Browse files

Merge "Ignore orientation requests from apps on the close-to-square display" into qt-dev

parents 998e5037 86e6d079
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -3328,9 +3328,8 @@
    -->
    <integer name="config_dockedStackDividerSnapMode">0</integer>

    <!-- The maximum aspect ratio (longerSide/shorterSide) that is treated as close-to-square. If
         config_forceDefaultOrientation is set to true, the rotation on a close-to-square display
         will be fixed. -->
    <!-- The maximum aspect ratio (longerSide/shorterSide) that is treated as close-to-square. The
         orientation requests from apps would be ignored if the display is close-to-square. -->
    <item name="config_closeToSquareDisplayMaxAspectRatio" format="float" type="dimen">1.333</item>

    <!-- List of comma separated package names for which we the system will not show crash, ANR,
+36 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -374,6 +375,20 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
     */
    private int mLastKeyguardForcedOrientation = SCREEN_ORIENTATION_UNSPECIFIED;

    /**
     * The maximum aspect ratio (longerSide/shorterSide) that is treated as close-to-square. The
     * orientation requests from apps would be ignored if the display is close-to-square.
     */
    @VisibleForTesting
    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.
     */
@@ -909,6 +924,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo

        mDisplayPolicy = new DisplayPolicy(service, this);
        mDisplayRotation = new DisplayRotation(service, this);
        mCloseToSquareMaxAspectRatio = service.mContext.getResources().getFloat(
                com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio);
        if (isDefaultDisplay) {
            // The policy may be invoked right after here, so it requires the necessary default
            // fields of this display content.
@@ -1539,6 +1556,21 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo

        mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
                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);
    }

    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;
    }

    /**
@@ -2119,6 +2151,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
    int getOrientation() {
        final WindowManagerPolicy policy = mWmService.mPolicy;

        if (mIgnoreRotationForApps) {
            return SCREEN_ORIENTATION_USER;
        }

        if (mWmService.mDisplayFrozen) {
            if (mLastWindowForcedOrientation != SCREEN_ORIENTATION_UNSPECIFIED) {
                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
+1 −22
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
import android.util.SparseArray;
import android.view.DisplayCutout;
import android.view.Surface;

import com.android.internal.annotations.VisibleForTesting;
@@ -74,8 +73,6 @@ public class DisplayRotation {
    private final int mDeskDockRotation;
    private final int mUndockedHdmiRotation;

    private final float mCloseToSquareMaxAspectRatio;

    private OrientationListener mOrientationListener;
    private StatusBarManagerInternal mStatusBarManagerInternal;
    private SettingsObserver mSettingsObserver;
@@ -163,9 +160,6 @@ public class DisplayRotation {
        mUndockedHdmiRotation = readRotation(
                com.android.internal.R.integer.config_undockedHdmiRotation);

        mCloseToSquareMaxAspectRatio = mContext.getResources().getFloat(
                com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio);

        if (isDefaultDisplay) {
            final Handler uiHandler = UiThread.getHandler();
            mOrientationListener = new OrientationListener(mContext, uiHandler);
@@ -242,31 +236,16 @@ public class DisplayRotation {
        // It's also not likely to rotate a TV screen.
        final boolean isTv = mContext.getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_LEANBACK);
        // Not much of use to rotate the display since it's close to square.
        final boolean isCloseToSquare =
                isNonDecorDisplayCloseToSquare(Surface.ROTATION_0, width, height);
        final boolean forceDesktopMode =
                mService.mForceDesktopModeOnExternalDisplays && !isDefaultDisplay;
        mDefaultFixedToUserRotation =
                (isCar || isTv || mService.mIsPc || forceDesktopMode || isCloseToSquare)
                (isCar || isTv || mService.mIsPc || forceDesktopMode)
                // For debug purposes the next line turns this feature off with:
                // $ adb shell setprop config.override_forced_orient true
                // $ adb shell wm size reset
                && !"true".equals(SystemProperties.get("config.override_forced_orient"));
    }

    private boolean isNonDecorDisplayCloseToSquare(int rotation, int width, int height) {
        final DisplayCutout displayCutout =
                mDisplayContent.calculateDisplayCutoutForRotation(rotation).getDisplayCutout();
        final int uiMode = mService.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;
    }

    void setRotation(int rotation) {
        if (mOrientationListener != null) {
            mOrientationListener.setCurrentRotation(rotation);
+39 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.wm;
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_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.Q;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -29,6 +30,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
@@ -535,6 +537,43 @@ public class DisplayContentTests extends WindowTestsBase {
                SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
    }

    @Test
    public void testOrientationForAspectRatio() {
        final DisplayContent dc = createNewDisplay();

        // When display content is created its configuration is not yet initialized, which could
        // cause unnecessary configuration propagation, so initialize it here.
        final Configuration config = new Configuration();
        dc.computeScreenConfiguration(config);
        dc.onRequestedOverrideConfigurationChanged(config);

        // Create a window that requests a fixed orientation. It will define device orientation
        // by default.
        final WindowState window = createWindow(null /* parent */, TYPE_APPLICATION_OVERLAY, dc,
                "window");
        window.mHasSurface = true;
        window.mAttrs.screenOrientation = SCREEN_ORIENTATION_LANDSCAPE;

        // --------------------------------
        // Test non-close-to-square display
        // --------------------------------
        dc.mBaseDisplayWidth = 1000;
        dc.mBaseDisplayHeight = (int) (dc.mBaseDisplayWidth * dc.mCloseToSquareMaxAspectRatio * 2f);
        dc.configureDisplayPolicy();

        assertEquals("Screen orientation must be defined by the window by default.",
                window.mAttrs.screenOrientation, dc.getOrientation());

        // ----------------------------
        // Test close-to-square display
        // ----------------------------
        dc.mBaseDisplayHeight = dc.mBaseDisplayWidth;
        dc.configureDisplayPolicy();

        assertEquals("Screen orientation must be SCREEN_ORIENTATION_USER.",
                SCREEN_ORIENTATION_USER, dc.getOrientation());
    }

    @Test
    public void testDisableDisplayInfoOverrideFromWindowManager() {
        final DisplayContent dc = createNewDisplay();
+2 −37
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.server.wm;

import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;

@@ -394,19 +393,6 @@ public class DisplayRotationTests {
        verifyOrientationListenerRegistration(0);
    }

    @Test
    public void testNotEnablesSensor_ForceDefaultRotation_Squared() throws Exception {
        mBuilder.build();
        configureDisplayRotation(SCREEN_ORIENTATION_LOCKED, false, false);

        when(mMockDisplayPolicy.isScreenOnEarly()).thenReturn(true);
        when(mMockDisplayPolicy.isAwake()).thenReturn(true);
        when(mMockDisplayPolicy.isKeyguardDrawComplete()).thenReturn(true);
        when(mMockDisplayPolicy.isWindowManagerDrawComplete()).thenReturn(true);
        mTarget.updateOrientationListener();
        verifyOrientationListenerRegistration(0);
    }

    private void enableOrientationSensor() {
        when(mMockDisplayPolicy.isScreenOnEarly()).thenReturn(true);
        when(mMockDisplayPolicy.isAwake()).thenReturn(true);
@@ -532,15 +518,6 @@ public class DisplayRotationTests {
                Surface.ROTATION_180));
    }

    @Test
    public void testReturnsUserRotation_ForceDefaultRotation_Squared() throws Exception {
        mBuilder.build();
        configureDisplayRotation(SCREEN_ORIENTATION_LOCKED, false, false);

        assertEquals(Surface.ROTATION_0, mTarget.rotationForOrientation(SCREEN_ORIENTATION_PORTRAIT,
                Surface.ROTATION_180));
    }

    @Test
    public void testReturnsLidOpenRotation_LidOpen() throws Exception {
        mBuilder.setLidOpenRotation(Surface.ROTATION_90).build();
@@ -643,14 +620,9 @@ public class DisplayRotationTests {
                width = 1080;
                height = 1920;
                break;
            case SCREEN_ORIENTATION_LOCKED:
                // We use locked for squared display.
                width = 1080;
                height = 1080;
                break;
            default:
                throw new IllegalArgumentException("displayOrientation needs to be landscape, "
                        + "portrait or locked, but we got "
                throw new IllegalArgumentException("displayOrientation needs to be either landscape"
                        + " or portrait, but we got "
                        + ActivityInfo.screenOrientationToString(displayOrientation));
        }

@@ -660,10 +632,6 @@ public class DisplayRotationTests {
                .thenReturn(isCar);
        when(mockPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
                .thenReturn(isTv);
        when(mMockDisplayPolicy.getNonDecorDisplayWidth(anyInt(), anyInt(), anyInt(), anyInt(),
                any())).thenReturn(width);
        when(mMockDisplayPolicy.getNonDecorDisplayHeight(anyInt(), anyInt(), anyInt(), anyInt(),
                any())).thenReturn(height);

        final int shortSizeDp = (isCar || isTv) ? 540 : 720;
        final int longSizeDp = 960;
@@ -831,9 +799,6 @@ public class DisplayRotationTests {
                    .thenReturn(convertRotationToDegrees(mDeskDockRotation));
            when(mMockRes.getInteger(com.android.internal.R.integer.config_undockedHdmiRotation))
                    .thenReturn(convertRotationToDegrees(mUndockedHdmiRotation));
            when(mMockRes.getFloat(
                    com.android.internal.R.dimen.config_closeToSquareDisplayMaxAspectRatio))
                    .thenReturn(1.33f);

            mMockSensorManager = mock(SensorManager.class);
            when(mMockContext.getSystemService(Context.SENSOR_SERVICE))