Reset "allowAllRotations" when the physical display changed.

Previously the config resource was read once and cached forever.

There are different config resource values based on the screen
dimensions, therefore we need to make sure that the value is reset
when displays change.

Test: DisplayRotationTests, DisplayWindowSettingsTest +
      Manually on device
Bug: 203814571
Change-Id: I116d9922342ea4f1ca5858873a1d38c4c5d52161
This commit is contained in:
Christian Göllner
2022-01-19 14:11:20 +01:00
parent 8563424438
commit 0047d16dd2
4 changed files with 105 additions and 2 deletions

View File

@@ -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.

View File

@@ -297,6 +297,8 @@ class DisplayWindowSettings {
final boolean ignoreOrientationRequest = settings.mIgnoreOrientationRequest != null
? settings.mIgnoreOrientationRequest : false;
dc.setIgnoreOrientationRequest(ignoreOrientationRequest);
dc.getDisplayRotation().resetAllowAllRotations();
}
/**

View File

@@ -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
// =================================

View File

@@ -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);