diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index f08b4fc0fe91f..3588470f4a7ec 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -1059,11 +1059,19 @@ public class DisplayRotation { preferredRotation = lastRotation; } } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED - && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { - // Apply rotation lock. Does not apply to NOSENSOR. + && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR + && orientation != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + && orientation != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + && orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE + && orientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT) { + // Apply rotation lock. Does not apply to NOSENSOR or specific rotations. // The idea is that the user rotation expresses a weak preference for the direction // of gravity and as NOSENSOR is never affected by gravity, then neither should // NOSENSOR be affected by rotation lock (although it will be affected by docks). + // Also avoid setting user rotation when app has preference over one particular rotation + // to avoid leaving the rotation to the reverse of it which has the compatible + // orientation, but isn't what app wants, when the user rotation is the reverse of the + // preferred rotation. preferredRotation = mUserRotation; } else { // No overriding preference. 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 059ff3d70660e..bd17bf26d70d1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -238,15 +238,55 @@ public class DisplayRotationTests { } @Test - public void testReturnsUserRotation_UserRotationLocked_CompatibleAppRequest() + public void testReturnsLandscape_UserRotationLockedSeascape_AppRequestsLandscape() throws Exception { mBuilder.build(); - configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false, false); + configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */, + false /* isTv */); + + freezeRotation(Surface.ROTATION_180); + + assertEquals(Surface.ROTATION_0, mTarget.rotationForOrientation( + ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, Surface.ROTATION_90)); + } + + @Test + public void testReturnsSeascape_UserRotationLockedSeascape_AppRequestsSeascape() + throws Exception { + mBuilder.build(); + configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */, + false /* isTv */); freezeRotation(Surface.ROTATION_180); assertEquals(Surface.ROTATION_180, mTarget.rotationForOrientation( - ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, Surface.ROTATION_90)); + ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE, Surface.ROTATION_90)); + } + + @Test + public void testReturnsPortrait_UserRotationLockedPortrait_AppRequestsPortrait() + throws Exception { + mBuilder.build(); + configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */, + false /* isTv */); + + freezeRotation(Surface.ROTATION_270); + + assertEquals(Surface.ROTATION_270, mTarget.rotationForOrientation( + ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, Surface.ROTATION_0)); + } + + @Test + public void testReturnsUpsideDown_UserRotationLockedUpsideDown_AppRequestsUpsideDown() + throws Exception { + mBuilder.build(); + configureDisplayRotation(SCREEN_ORIENTATION_LANDSCAPE, false /* isCar */, + false /* isTv */); + + freezeRotation(Surface.ROTATION_90); + + assertEquals(Surface.ROTATION_90, mTarget.rotationForOrientation( + ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, Surface.ROTATION_0)); } @Test