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

Commit f9bf0eab authored by Tiger Huang's avatar Tiger Huang Committed by android-build-merger
Browse files

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

am: e935a92a

Change-Id: Iec7d43e222855106c0718e23757e964f54f7bfc1
parents 57cdc04e e935a92a
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -3344,9 +3344,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))