From 3e595fe8d4020e03012d4666a990bc3898bd9e93 Mon Sep 17 00:00:00 2001 From: Tetsutoki Shiozawa Date: Tue, 7 May 2019 18:27:25 +0900 Subject: [PATCH] Distinguish between landscape and seascape Symptom: android:screenOrientation="landscape" does not work. The activity is shown in seascape mode when the screen orientation is locked in seascape mode. Root cause: DisplayRotation allows showing an activity in seascape mode even though the activity has SCREEN_ORIENTATION_LANDSCAPE flag. Some application wants to avoid seascape mode but it can not. Solution: Respect android:screenOrientation="landscape" attribute. The screen should be flipped from seascape to landscape according to the attribute. Also respect "portrait" in the same way. Bug: 132665278 Test: atest DisplayRotationTest Change-Id: Ia5b1115797df78838c8693206f5ed1f0af62c49c --- .../android/server/wm/DisplayRotation.java | 12 ++++- .../server/wm/DisplayRotationTests.java | 46 +++++++++++++++++-- 2 files changed, 53 insertions(+), 5 deletions(-) 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