diff options
10 files changed, 121 insertions, 19 deletions
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl index 172456e4d0fa..e6bb1f64ad86 100644 --- a/core/java/android/window/ITaskOrganizerController.aidl +++ b/core/java/android/window/ITaskOrganizerController.aidl @@ -69,4 +69,14 @@ interface ITaskOrganizerController { /** Updates a state of camera compat control for stretched issues in the viewfinder. */ void updateCameraCompatControlState(in WindowContainerToken task, int state); + + /** + * Controls whether ignore orientation request logic in {@link + * com.android.server.wm.DisplayArea} is disabled at runtime. + * + * @param isDisabled when {@code true}, the system always ignores the value of {@link + * com.android.server.wm.DisplayArea#getIgnoreOrientationRequest} and app + * requested orientation is respected. + */ + void setIsIgnoreOrientationRequestDisabled(boolean isDisabled); } diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index 8d88f80ff483..bffd4e437dfa 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -253,6 +253,24 @@ public class TaskOrganizer extends WindowOrganizer { } /** + * Controls whether ignore orientation request logic in {@link + * com.android.server.wm.DisplayArea} is disabled at runtime. + * + * @param isDisabled when {@code true}, the system always ignores the value of {@link + * com.android.server.wm.DisplayArea#getIgnoreOrientationRequest} and app + * requested orientation is respected. + * @hide + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) + public void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) { + try { + mTaskOrganizerController.setIsIgnoreOrientationRequestDisabled(isDisabled); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Gets the executor to run callbacks on. * @hide */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java index 4bb580571145..28681526b4f2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java @@ -225,6 +225,10 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer { @VisibleForTesting void enable() { + // Needed since many Kids apps aren't optimised to support both orientations and it will be + // hard for kids to understand the app compat mode. + // TODO(229961548): Remove ignoreOrientationRequest exception for Kids Mode once possible. + setIsIgnoreOrientationRequestDisabled(true); final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY); if (displayLayout != null) { mDisplayWidth = displayLayout.width(); @@ -245,6 +249,7 @@ public class KidsModeTaskOrganizer extends ShellTaskOrganizer { @VisibleForTesting void disable() { + setIsIgnoreOrientationRequestDisabled(false); mDisplayInsetsController.removeInsetsChangedListener(DEFAULT_DISPLAY, mOnInsetsChangedListener); mDisplayController.removeDisplayWindowListener(mOnDisplaysChangedListener); diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index dfa3b743292e..863782a4316e 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -78,8 +78,11 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { * Whether this {@link DisplayArea} should ignore fixed-orientation request. If {@code true}, it * can never specify orientation, but shows the fixed-orientation apps below it in the * letterbox; otherwise, it rotates based on the fixed-orientation request. + * + * <p>Note: use {@link #getIgnoreOrientationRequest} to access outside of {@link + * #setIgnoreOrientationRequest} since the value can be overridden at runtime on a device level. */ - protected boolean mIgnoreOrientationRequest; + protected boolean mSetIgnoreOrientationRequest; DisplayArea(WindowManagerService wms, Type type, String name) { this(wms, type, name, FEATURE_UNDEFINED); @@ -140,7 +143,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { @Override int getOrientation(int candidate) { mLastOrientationSource = null; - if (mIgnoreOrientationRequest) { + if (getIgnoreOrientationRequest()) { return SCREEN_ORIENTATION_UNSET; } @@ -149,14 +152,15 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { @Override boolean handlesOrientationChangeFromDescendant() { - return !mIgnoreOrientationRequest && super.handlesOrientationChangeFromDescendant(); + return !getIgnoreOrientationRequest() + && super.handlesOrientationChangeFromDescendant(); } @Override boolean onDescendantOrientationChanged(WindowContainer requestingContainer) { // If this is set to ignore the orientation request, we don't propagate descendant // orientation request. - return !mIgnoreOrientationRequest + return !getIgnoreOrientationRequest() && super.onDescendantOrientationChanged(requestingContainer); } @@ -167,10 +171,10 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { * @return Whether the display orientation changed after calling this method. */ boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) { - if (mIgnoreOrientationRequest == ignoreOrientationRequest) { + if (mSetIgnoreOrientationRequest == ignoreOrientationRequest) { return false; } - mIgnoreOrientationRequest = ignoreOrientationRequest; + mSetIgnoreOrientationRequest = ignoreOrientationRequest; // Check whether we should notify Display to update orientation. if (mDisplayContent == null) { @@ -204,7 +208,11 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { } boolean getIgnoreOrientationRequest() { - return mIgnoreOrientationRequest; + // Adding an exception for when ignoreOrientationRequest is overridden at runtime for all + // DisplayArea-s. For example, this is needed for the Kids Mode since many Kids apps aren't + // optimised to support both orientations and it will be hard for kids to understand the + // app compat mode. + return mSetIgnoreOrientationRequest && !mWmService.isIgnoreOrientationRequestDisabled(); } /** @@ -289,8 +297,8 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { @Override void dump(PrintWriter pw, String prefix, boolean dumpAll) { super.dump(pw, prefix, dumpAll); - if (mIgnoreOrientationRequest) { - pw.println(prefix + "mIgnoreOrientationRequest=true"); + if (mSetIgnoreOrientationRequest) { + pw.println(prefix + "mSetIgnoreOrientationRequest=true"); } if (hasRequestedOverrideConfiguration()) { pw.println(prefix + "overrideConfig=" + getRequestedOverrideConfiguration()); @@ -600,7 +608,7 @@ public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> { @Override int getOrientation(int candidate) { mLastOrientationSource = null; - if (mIgnoreOrientationRequest) { + if (getIgnoreOrientationRequest()) { return SCREEN_ORIENTATION_UNSET; } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 466075702409..b2949857a743 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1485,7 +1485,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override boolean handlesOrientationChangeFromDescendant() { - return !mIgnoreOrientationRequest && !getDisplayRotation().isFixedToUserRotation(); + return !getIgnoreOrientationRequest() + && !getDisplayRotation().isFixedToUserRotation(); } /** @@ -4859,7 +4860,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override int getOrientation(int candidate) { - if (mIgnoreOrientationRequest) { + if (getIgnoreOrientationRequest()) { return SCREEN_ORIENTATION_UNSET; } @@ -6098,14 +6099,29 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) { - if (mIgnoreOrientationRequest == ignoreOrientationRequest) return false; + if (mSetIgnoreOrientationRequest == ignoreOrientationRequest) return false; final boolean rotationChanged = super.setIgnoreOrientationRequest(ignoreOrientationRequest); mWmService.mDisplayWindowSettings.setIgnoreOrientationRequest( - this, mIgnoreOrientationRequest); + this, mSetIgnoreOrientationRequest); return rotationChanged; } /** + * Updates orientation if necessary after ignore orientation request override logic in {@link + * WindowManagerService#isIgnoreOrientationRequestDisabled} changes at runtime. + */ + void onIsIgnoreOrientationRequestDisabledChanged() { + if (mFocusedApp != null) { + // We record the last focused TDA that respects orientation request, check if this + // change may affect it. + onLastFocusedTaskDisplayAreaChanged(mFocusedApp.getDisplayArea()); + } + if (mSetIgnoreOrientationRequest) { + updateOrientation(); + } + } + + /** * Locates the appropriate target window for scroll capture. The search progresses top to * bottom. * If {@code searchBehind} is non-null, the search will only consider windows behind this one. diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java index 43ff58083657..5aacb094207e 100644 --- a/services/core/java/com/android/server/wm/DisplayRotation.java +++ b/services/core/java/com/android/server/wm/DisplayRotation.java @@ -1683,7 +1683,7 @@ public class DisplayRotation { mSensorRotation = (listener == null || !listener.mEnabled) ? -2 /* disabled */ : dr.mLastSensorRotation; final DisplayContent dc = dr.mDisplayContent; - mIgnoreOrientationRequest = dc.mIgnoreOrientationRequest; + mIgnoreOrientationRequest = dc.getIgnoreOrientationRequest(); final TaskDisplayArea requestingTda = dc.getOrientationRequestingTaskDisplayArea(); mNonDefaultRequestingTaskDisplayArea = requestingTda == null ? "none" : requestingTda != dc.getDefaultTaskDisplayArea() diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 7a7bf1f877b9..ff94ae65207b 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -640,7 +640,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { @Override int getOrientation(int candidate) { mLastOrientationSource = null; - if (mIgnoreOrientationRequest) { + if (getIgnoreOrientationRequest()) { return SCREEN_ORIENTATION_UNSET; } if (!canSpecifyOrientation()) { @@ -1912,7 +1912,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> { // Only allow to specify orientation if this TDA is not set to ignore orientation request, // and it is the last focused one on this logical display that can request orientation // request. - return !mIgnoreOrientationRequest + return !getIgnoreOrientationRequest() && mDisplayContent.getOrientationRequestingTaskDisplayArea() == this; } diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java index 9bf988f16090..ce392a706623 100644 --- a/services/core/java/com/android/server/wm/TaskOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java @@ -1001,6 +1001,19 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub { } } + @Override + public void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) { + enforceTaskPermission("setIsIgnoreOrientationRequestDisabled()"); + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + mService.mWindowManager.setIsIgnoreOrientationRequestDisabled(isDisabled); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + public boolean handleInterceptBackPressedOnTaskRoot(Task task) { if (task == null || !task.isOrganized() || !mInterceptBackPressedOnRootTasks.contains(task.mTaskId)) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 2f4dc515fd11..1b0e4e341d9b 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -989,6 +989,8 @@ public class WindowManagerService extends IWindowManager.Stub final LetterboxConfiguration mLetterboxConfiguration; + private boolean mIsIgnoreOrientationRequestDisabled; + final InputManagerService mInputManager; final DisplayManagerInternal mDisplayManagerInternal; final DisplayManager mDisplayManager; @@ -4088,6 +4090,36 @@ public class WindowManagerService extends IWindowManager.Stub } } + /** + * Controls whether ignore orientation request logic in {@link DisplayArea} is disabled + * at runtime. + * + * <p>Note: this assumes that {@link #mGlobalLock} is held by the caller. + * + * @param isDisabled when {@code true}, the system always ignores the value of {@link + * DisplayArea#getIgnoreOrientationRequest} and app requested orientation is + * respected. + */ + void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) { + if (isDisabled == mIsIgnoreOrientationRequestDisabled) { + return; + } + mIsIgnoreOrientationRequestDisabled = isDisabled; + for (int i = mRoot.getChildCount() - 1; i >= 0; i--) { + mRoot.getChildAt(i).onIsIgnoreOrientationRequestDisabledChanged(); + } + } + + /** + * Whether the system ignores the value of {@link DisplayArea#getIgnoreOrientationRequest} and + * app requested orientation is respected. + * + * <p>Note: this assumes that {@link #mGlobalLock} is held by the caller. + */ + boolean isIgnoreOrientationRequestDisabled() { + return mIsIgnoreOrientationRequestDisabled; + } + @Override public void freezeRotation(int rotation) { freezeDisplayRotation(Display.DEFAULT_DISPLAY, rotation); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 118f159bee7b..608318d081ba 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -2172,7 +2172,7 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(windowingMode, windowConfig.getWindowingMode()); // test misc display overrides - assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest); + assertEquals(ignoreOrientationRequests, testDisplayContent.mSetIgnoreOrientationRequest); assertEquals(fixedOrientationLetterboxRatio, mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(), 0 /* delta */); @@ -2213,7 +2213,7 @@ public class DisplayContentTests extends WindowTestsBase { assertEquals(windowingMode, windowConfig.getWindowingMode()); // test misc display overrides - assertEquals(ignoreOrientationRequests, testDisplayContent.mIgnoreOrientationRequest); + assertEquals(ignoreOrientationRequests, testDisplayContent.mSetIgnoreOrientationRequest); assertEquals(fixedOrientationLetterboxRatio, mWm.mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio(), 0 /* delta */); |