diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 8c8b33f344fd2..7e01e380eb553 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -1103,6 +1103,21 @@ public class DisplayRotation { return oldRotation != rotation; } + + /** + * Resets whether the screen can be rotated via the accelerometer in all 4 rotations as the + * default behavior. + * + * To be called if there is potential that the value changed. For example if the active display + * changed. + * + * At the moment it is called from + * {@link DisplayWindowSettings#applyRotationSettingsToDisplayLocked}. + */ + void resetAllowAllRotations() { + mAllowAllRotations = ALLOW_ALL_ROTATIONS_UNDEFINED; + } + /** * Given an orientation constant, returns the appropriate surface rotation, taking into account * sensors, docking mode, rotation lock, and other factors. diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java index 483c799c5afa6..70c769d608449 100644 --- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java +++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java @@ -297,6 +297,8 @@ class DisplayWindowSettings { final boolean ignoreOrientationRequest = settings.mIgnoreOrientationRequest != null ? settings.mIgnoreOrientationRequest : false; dc.setIgnoreOrientationRequest(ignoreOrientationRequest); + + dc.getDisplayRotation().resetAllowAllRotations(); } /** 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 6342183ea28e0..25cff61c3b785 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java @@ -18,6 +18,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_SENSOR; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DISABLED; @@ -546,6 +547,80 @@ public class DisplayRotationTests { SCREEN_ORIENTATION_UNSPECIFIED, Surface.ROTATION_0)); } + @Test + public void testReturnsSensorRotation_180degrees_allRotationsAllowed() + throws Exception { + mBuilder.build(); + when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations)) + .thenReturn(true); + configureDisplayRotation(SCREEN_ORIENTATION_PORTRAIT, false, false); + enableOrientationSensor(); + mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180)); + + assertEquals(Surface.ROTATION_180, mTarget.rotationForOrientation( + SCREEN_ORIENTATION_SENSOR, Surface.ROTATION_0)); + } + + @Test + public void testReturnLastRotation_sensor180_allRotationsNotAllowed() + throws Exception { + mBuilder.build(); + when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations)) + .thenReturn(false); + configureDisplayRotation(SCREEN_ORIENTATION_PORTRAIT, false, false); + enableOrientationSensor(); + mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180)); + + assertEquals(Surface.ROTATION_0, mTarget.rotationForOrientation( + SCREEN_ORIENTATION_SENSOR, Surface.ROTATION_0)); + } + + @Test + public void testAllowRotationsIsCached() + throws Exception { + mBuilder.build(); + configureDisplayRotation(SCREEN_ORIENTATION_PORTRAIT, false, false); + enableOrientationSensor(); + + // Rotate once to read the resource + when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations)) + .thenReturn(true); + mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180)); + mTarget.rotationForOrientation(SCREEN_ORIENTATION_SENSOR, Surface.ROTATION_0); + + // Change resource to disallow all rotations. + // Rotate again and 180 degrees rotation should still be returned even if "disallowed". + when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations)) + .thenReturn(false); + mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180)); + assertEquals(Surface.ROTATION_180, mTarget.rotationForOrientation( + SCREEN_ORIENTATION_SENSOR, Surface.ROTATION_0)); + } + + @Test + public void testResetAllowRotations() + throws Exception { + mBuilder.build(); + configureDisplayRotation(SCREEN_ORIENTATION_PORTRAIT, false, false); + enableOrientationSensor(); + + // Rotate once to read the resource + when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations)) + .thenReturn(true); + mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180)); + mTarget.rotationForOrientation(SCREEN_ORIENTATION_SENSOR, Surface.ROTATION_0); + + // Change resource to disallow all rotations. + // Reset "allowAllRotations". + // Rotate again and 180 degrees rotation should not be allowed anymore. + when(mMockRes.getBoolean(com.android.internal.R.bool.config_allowAllRotations)) + .thenReturn(false); + mTarget.resetAllowAllRotations(); + mOrientationSensorListener.onSensorChanged(createSensorEvent(Surface.ROTATION_180)); + assertEquals(Surface.ROTATION_0, mTarget.rotationForOrientation( + SCREEN_ORIENTATION_SENSOR, Surface.ROTATION_0)); + } + // ================================= // Tests for Policy based Rotation // ================================= diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java index 365e749df79fe..093be82c61284 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java @@ -20,10 +20,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_DISABLED; import static android.view.IWindowManager.FIXED_TO_USER_ROTATION_ENABLED; +import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; +import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY; import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY; -import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL; -import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -259,6 +259,17 @@ public class DisplayWindowSettingsTests extends WindowTestsBase { assertFalse(mSecondaryDisplay.mDisplayScalingDisabled); } + @Test + public void testResetAllowAllRotations() { + final DisplayRotation displayRotation = mock(DisplayRotation.class); + spyOn(mPrimaryDisplay); + doReturn(displayRotation).when(mPrimaryDisplay).getDisplayRotation(); + + mDisplayWindowSettings.applyRotationSettingsToDisplayLocked(mPrimaryDisplay); + + verify(displayRotation).resetAllowAllRotations(); + } + @Test public void testDefaultToFreeUserRotation() { mDisplayWindowSettings.applySettingsToDisplayLocked(mSecondaryDisplay);