Persist user rotations of external displays.
It also introduces a command line tool to rotate external displays for
testing purposes.
Instead of changing signatures of freezeRotation(), thawRotation() and
isRotationFrozen(), introduce 3 new methods to IWindowManager interface.
The old methods are being used pervasively.
Also resolved some style issues in DisplaySettings class.
Bug: 113252523
Bug: 111361251
Test: Rotation locks via settings still work. User rotation mode and
user rotation values for external devices are persisted as expected in
storage. DisplaySettingsTests passes.
Change-Id: I1746bea98a588f0bbd30c9f0617a7a23dc6e4209
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index bd82553..847cff9 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -55,6 +55,7 @@
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayRotation" : TAG_WM;
private final WindowManagerService mService;
+ private final DisplayContent mDisplayContent;
private final DisplayPolicy mDisplayPolicy;
private final Context mContext;
private final Object mLock;
@@ -106,6 +107,7 @@
DisplayRotation(WindowManagerService service, DisplayContent displayContent,
DisplayPolicy displayPolicy, Context context, Object lock) {
mService = service;
+ mDisplayContent = displayContent;
mDisplayPolicy = displayPolicy;
mContext = context;
mLock = lock;
@@ -225,6 +227,70 @@
}
}
+ void restoreUserRotation(int userRotationMode, int userRotation) {
+ if (userRotationMode != WindowManagerPolicy.USER_ROTATION_FREE
+ && userRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) {
+ Slog.w(TAG, "Trying to restore an invalid user rotation mode " + userRotationMode
+ + " for " + mDisplayContent);
+ userRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+ }
+ if (userRotation < Surface.ROTATION_0 || userRotation > Surface.ROTATION_270) {
+ Slog.w(TAG, "Trying to restore an invalid user rotation " + userRotation
+ + " for " + mDisplayContent);
+ userRotation = Surface.ROTATION_0;
+ }
+ mUserRotationMode = userRotationMode;
+ mUserRotation = userRotation;
+ }
+
+ private void setUserRotation(int userRotationMode, int userRotation) {
+ if (isDefaultDisplay) {
+ // We'll be notified via settings listener, so we don't need to update internal values.
+ final ContentResolver res = mContext.getContentResolver();
+ final int accelerometerRotation =
+ userRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED ? 0 : 1;
+ Settings.System.putIntForUser(res, Settings.System.ACCELEROMETER_ROTATION,
+ accelerometerRotation, UserHandle.USER_CURRENT);
+ Settings.System.putIntForUser(res, Settings.System.USER_ROTATION, userRotation,
+ UserHandle.USER_CURRENT);
+ return;
+ }
+
+ boolean changed = false;
+ if (mUserRotationMode != userRotationMode) {
+ mUserRotationMode = userRotationMode;
+ changed = true;
+ }
+ if (mUserRotation != userRotation) {
+ mUserRotation = userRotation;
+ changed = true;
+ }
+ mService.mDisplaySettings.setUserRotation(mDisplayContent, userRotationMode, userRotation);
+ if (changed) {
+ mService.updateRotation(true /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ mService.mDisplaySettings.writeSettingsLocked();
+ }
+ }
+
+ void freezeRotation(int rotation) {
+ rotation = (rotation == -1) ? mDisplayContent.getRotation() : rotation;
+ setUserRotation(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation);
+ }
+
+ void thawRotation() {
+ setUserRotation(WindowManagerPolicy.USER_ROTATION_FREE, mUserRotation);
+ }
+
+ boolean isRotationFrozen() {
+ if (!isDefaultDisplay) {
+ return mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED;
+ }
+
+ return Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) == 0;
+ }
+
/** @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true. */
boolean isDefaultOrientationForced() {
return mForceDefaultOrientation;
@@ -381,9 +447,6 @@
* @param orientation An orientation constant, such as
* {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
* @param lastRotation The most recently used rotation.
- * @param defaultDisplay Flag indicating whether the rotation is computed for the default
- * display. Currently for all non-default displays sensors, docking mode,
- * rotation lock and other factors are ignored.
* @return The surface rotation to use.
*/
int rotationForOrientation(int orientation, int lastRotation) {
@@ -418,8 +481,8 @@
final int preferredRotation;
if (!isDefaultDisplay) {
// For secondary displays we ignore things like displays sensors, docking mode and
- // rotation lock, and always prefer a default rotation.
- preferredRotation = Surface.ROTATION_0;
+ // rotation lock, and always prefer user rotation.
+ preferredRotation = mUserRotation;
} else if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
// Ignore sensor when lid switch is open and rotation is forced.
preferredRotation = mLidOpenRotation;