Support ignoring app orientation request per display
For products that don't want the app orientation request to change the
display's rotation, but still want the rotation to change based on
sensor readings. Apps requesting a different orientation will be
letterboxed.
Bug: 170725334
Test: adb shell cmd window set-ignore-orienation-request 1
Change-Id: I53bea137ff37b70417ed8f68ade97d9de1f284ae
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index daab70a..c460f74 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -337,11 +337,16 @@
*/
boolean isDisplayRotationFrozen(int displayId);
- /**
+ /**
* Sets if display rotation is fixed to user specified value for given displayId.
*/
void setFixedToUserRotation(int displayId, int fixedToUserRotation);
+ /**
+ * Sets if all requested fixed orientation should be ignored for given displayId.
+ */
+ void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest);
+
/**
* Screenshot the current wallpaper layer, including the whole screen.
*/
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 5122f6c..97196d1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -102,6 +102,18 @@
}
/**
+ * Sets if app requested fixed orientation should be ignored for given displayId.
+ */
+ public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) {
+ try {
+ WindowManagerGlobal.getWindowManagerService().setIgnoreOrientationRequest(
+ displayId, ignoreOrientationRequest);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to setIgnoreOrientationRequest()", e);
+ }
+ }
+
+ /**
* @return the stable insets for the primary display.
*/
public void getStableInsets(Rect outStableInsets) {
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index e4f8d8b..94b3d8d 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -181,6 +181,10 @@
return false;
}
+ boolean getIgnoreOrientationRequest() {
+ return mIgnoreOrientationRequest;
+ }
+
/**
* When a {@link DisplayArea} is repositioned, it should only be moved among its siblings of the
* same {@link Type}.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0bade7d..be03e91 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -5356,8 +5356,13 @@
return mDisplayPolicy.getSystemUiContext();
}
- Point getDisplayPosition() {
- return mWmService.mDisplayManagerInternal.getDisplayPosition(getDisplayId());
+ @Override
+ boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) {
+ if (mIgnoreOrientationRequest == ignoreOrientationRequest) return false;
+ final boolean rotationChanged = super.setIgnoreOrientationRequest(ignoreOrientationRequest);
+ mWmService.mDisplayWindowSettings.setIgnoreOrientationRequest(
+ this, mIgnoreOrientationRequest);
+ return rotationChanged;
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index 04e37fa..f647bea 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -112,6 +112,7 @@
private boolean mShouldShowSystemDecors = false;
private boolean mShouldShowIme = false;
private int mFixedToUserRotation = IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
+ private boolean mIgnoreOrientationRequest = false;
private Entry(String name) {
mName = name;
@@ -131,6 +132,7 @@
mShouldShowSystemDecors = copyFrom.mShouldShowSystemDecors;
mShouldShowIme = copyFrom.mShouldShowIme;
mFixedToUserRotation = copyFrom.mFixedToUserRotation;
+ mIgnoreOrientationRequest = copyFrom.mIgnoreOrientationRequest;
}
/** @return {@code true} if all values are default. */
@@ -144,7 +146,8 @@
&& !mShouldShowWithInsecureKeyguard
&& !mShouldShowSystemDecors
&& !mShouldShowIme
- && mFixedToUserRotation == IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT;
+ && mFixedToUserRotation == IWindowManager.FIXED_TO_USER_ROTATION_DEFAULT
+ && !mIgnoreOrientationRequest;
}
}
@@ -248,6 +251,15 @@
writeSettingsIfNeeded(entry, displayInfo);
}
+ void setIgnoreOrientationRequest(
+ DisplayContent displayContent, boolean ignoreOrientationRequest) {
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ final Entry entry = getOrCreateEntry(displayInfo);
+ if (entry.mIgnoreOrientationRequest == ignoreOrientationRequest) return;
+ entry.mIgnoreOrientationRequest = ignoreOrientationRequest;
+ writeSettingsIfNeeded(entry, displayInfo);
+ }
+
private int getWindowingModeLocked(Entry entry, DisplayContent dc) {
int windowingMode = entry != null ? entry.mWindowingMode
: WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -389,6 +401,7 @@
final boolean hasSizeOverride = entry.mForcedWidth != 0 && entry.mForcedHeight != 0;
dc.mIsDensityForced = hasDensityOverride;
dc.mIsSizeForced = hasSizeOverride;
+ dc.setIgnoreOrientationRequest(entry.mIgnoreOrientationRequest);
final int width = hasSizeOverride ? entry.mForcedWidth : dc.mBaseDisplayWidth;
final int height = hasSizeOverride ? entry.mForcedHeight : dc.mBaseDisplayHeight;
@@ -529,6 +542,8 @@
entry.mShouldShowSystemDecors = getBooleanAttribute(parser, "shouldShowSystemDecors");
entry.mShouldShowIme = getBooleanAttribute(parser, "shouldShowIme");
entry.mFixedToUserRotation = getIntAttribute(parser, "fixedToUserRotation");
+ entry.mIgnoreOrientationRequest
+ = getBooleanAttribute(parser, "ignoreOrientationRequest");
mEntries.put(name, entry);
}
XmlUtils.skipCurrentTag(parser);
@@ -613,6 +628,10 @@
out.attribute(null, "fixedToUserRotation",
Integer.toString(entry.mFixedToUserRotation));
}
+ if (entry.mIgnoreOrientationRequest) {
+ out.attribute(null, "ignoreOrientationRequest",
+ Boolean.toString(entry.mIgnoreOrientationRequest));
+ }
out.endTag(null, "display");
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 223aa1e..429cce2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3714,16 +3714,52 @@
@Override
public void setFixedToUserRotation(int displayId, int fixedToUserRotation) {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
- "freezeRotation()")) {
+ "setFixedToUserRotation()")) {
throw new SecurityException("Requires SET_ORIENTATION permission");
}
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final DisplayContent display = mRoot.getDisplayContent(displayId);
+ if (display == null) {
+ Slog.w(TAG, "Trying to set rotate for app for a missing display.");
+ return;
+ }
+ display.getDisplayRotation().setFixedToUserRotation(fixedToUserRotation);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
+ public void setIgnoreOrientationRequest(int displayId, boolean ignoreOrientationRequest) {
+ mAtmInternal.enforceCallerIsRecentsOrHasPermission(
+ android.Manifest.permission.SET_ORIENTATION, "setIgnoreOrientationRequest()");
+
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final DisplayContent display = mRoot.getDisplayContent(displayId);
+ if (display == null) {
+ Slog.w(TAG, "Trying to setIgnoreOrientationRequest() for a missing display.");
+ return;
+ }
+ display.setIgnoreOrientationRequest(ignoreOrientationRequest);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ boolean getIgnoreOrientationRequest(int displayId) {
synchronized (mGlobalLock) {
final DisplayContent display = mRoot.getDisplayContent(displayId);
if (display == null) {
- Slog.w(TAG, "Trying to set rotate for app for a missing display.");
- return;
+ Slog.w(TAG, "Trying to getIgnoreOrientationRequest() for a missing display.");
+ return false;
}
- display.getDisplayRotation().setFixedToUserRotation(fixedToUserRotation);
+ return display.getIgnoreOrientationRequest();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 506e0dd..fa1c50f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -106,6 +106,10 @@
return runSetDisplayUserRotation(pw);
case "set-fix-to-user-rotation":
return runSetFixToUserRotation(pw);
+ case "set-ignore-orientation-request":
+ return runSetIgnoreOrientationRequest(pw);
+ case "get-ignore-orientation-request":
+ return runGetIgnoreOrientationRequest(pw);
case "dump-visible-window-views":
return runDumpVisibleWindowViews(pw);
default:
@@ -368,6 +372,47 @@
return 0;
}
+ private int runSetIgnoreOrientationRequest(PrintWriter pw) throws RemoteException {
+ int displayId = Display.DEFAULT_DISPLAY;
+ String arg = getNextArgRequired();
+ if ("-d".equals(arg)) {
+ displayId = Integer.parseInt(getNextArgRequired());
+ arg = getNextArgRequired();
+ }
+
+ final boolean ignoreOrientationRequest;
+ switch (arg) {
+ case "true":
+ case "1":
+ ignoreOrientationRequest = true;
+ break;
+ case "false":
+ case "0":
+ ignoreOrientationRequest = false;
+ break;
+ default:
+ getErrPrintWriter().println("Error: expecting true, 1, false, 0, but we "
+ + "get " + arg);
+ return -1;
+ }
+
+ mInterface.setIgnoreOrientationRequest(displayId, ignoreOrientationRequest);
+ return 0;
+ }
+
+ private int runGetIgnoreOrientationRequest(PrintWriter pw) throws RemoteException {
+ int displayId = Display.DEFAULT_DISPLAY;
+ String arg = getNextArg();
+ if ("-d".equals(arg)) {
+ displayId = Integer.parseInt(getNextArgRequired());
+ }
+
+ final boolean ignoreOrientationRequest = mInternal.getIgnoreOrientationRequest(displayId);
+ pw.println("ignoreOrientationRequest " + ignoreOrientationRequest
+ + " for displayId=" + displayId);
+ return 0;
+ }
+
private int runDumpVisibleWindowViews(PrintWriter pw) {
if (!mInternal.checkCallingPermission(android.Manifest.permission.DUMP,
"runDumpVisibleWindowViews()")) {
@@ -433,8 +478,11 @@
pw.println(" Set user rotation mode and user rotation.");
pw.println(" dump-visible-window-views");
pw.println(" Dumps the encoded view hierarchies of visible windows");
- pw.println(" set-fix-to-user-rotation [-d DISPLAY_ID] [enabled|disabled]");
+ pw.println(" set-fix-to-user-rotation [-d DISPLAY_ID] [enabled|disabled|default]");
pw.println(" Enable or disable rotating display for app requested orientation.");
+ pw.println(" set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]");
+ pw.println(" get-ignore-orientation-request [-d DISPLAY_ID] ");
+ pw.println(" If app requested orientation should be ignored.");
if (!IS_USER) {
pw.println(" tracing (start | stop)");
pw.println(" Start or stop window tracing.");