summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java36
-rw-r--r--services/core/java/com/android/server/wm/DisplayRotation.java23
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java39
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java39
5 files changed, 80 insertions, 62 deletions
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ccf8509c2f8f..2163a5532018 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3322,9 +3322,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,
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3f783f67b73c..6c198352a938 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -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;
@@ -371,6 +372,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.
*/
private boolean mLastWallpaperVisible = false;
@@ -898,6 +913,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.
@@ -1523,6 +1540,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;
}
/**
@@ -2103,6 +2135,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
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 34a480291863..282ed42468dd 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -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);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index e60e54c9e44f..bbba0a00e861 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -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;
@@ -528,6 +530,43 @@ public class DisplayContentTests extends WindowTestsBase {
}
@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();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index 1c10ffb01f8e..49d38c062049 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -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);
@@ -533,15 +519,6 @@ public class DisplayRotationTests {
}
@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();
configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false);
@@ -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))