From d93fff6c0ffac8724dd12bd98cc0eef5a77d0f27 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Tue, 13 Oct 2020 15:13:46 -0700 Subject: [PATCH] Support ignoring orientation request on DisplayArea level 1. Move the mIgnoreOrientationRequest to DisplayArea so that one can set it on DisplayContent and DisplayAreaGroup to ignore orientation request from non-app windows. 2. Have the DisplayContent to return SCREEN_ORIENTATION_UNSPECIFIED when it is SCREEN_ORIENTATION_UNSET so that the display respects sensor rotation. 3. Move the logic of using last orientation back to TDA, otherwise when TDA returns UNSET because ignore is set, DC may incorrectly uses the last orientation. Bug: 170725334 Bug: 155431879 Test: manual: test with setting TDA and DC to ignore Test: atest WmTests:TaskDisplayAreaTests Test: atest WmTests:WindowOrganizerTests Test: atest WmTests:DisplayAreaTest Test: atest WmTests:DisplayContentTests Change-Id: Ie92b059c453204799a58efd39dc9b23f7d62816d --- .../window/WindowContainerTransaction.java | 8 +-- data/etc/services.core.protolog.json | 36 ++++++---- .../com/android/server/wm/DisplayArea.java | 66 +++++++++++++++++++ .../com/android/server/wm/DisplayContent.java | 29 ++++---- .../android/server/wm/TaskDisplayArea.java | 46 +++++-------- .../server/wm/WindowOrganizerController.java | 30 ++++----- .../android/server/wm/DisplayAreaTest.java | 22 +++++++ .../android/server/wm/TaskRecordTests.java | 6 +- .../server/wm/WindowOrganizerTests.java | 38 ++++++++++- 9 files changed, 203 insertions(+), 78 deletions(-) diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index ba901549f2b56..eba4fd21166d2 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -238,10 +238,10 @@ public final class WindowContainerTransaction implements Parcelable { } /** - * Sets whether a container should ignore the orientation request from apps below it. It - * currently only applies to {@link com.android.server.wm.TaskDisplayArea}. When {@code false}, - * it may rotate based on the orientation request; When {@code true}, it can never specify - * orientation, but shows the fixed-orientation apps in the letterbox. + * Sets whether a container should ignore the orientation request from apps and windows below + * it. It currently only applies to {@link com.android.server.wm.DisplayArea}. When + * {@code false}, it may rotate based on the orientation request; When {@code true}, it can + * never specify orientation, but shows the fixed-orientation apps below it in the letterbox. * @hide */ @NonNull diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index 59727d5b25559..31dae22df4546 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -301,12 +301,6 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowState.java" }, - "-1741065110": { - "message": "No app is requesting an orientation, return %d for display id=%d", - "level": "VERBOSE", - "group": "WM_DEBUG_ORIENTATION", - "at": "com\/android\/server\/wm\/DisplayContent.java" - }, "-1730156332": { "message": "Display id=%d rotation changed to %d from %d, lastOrientation=%d", "level": "VERBOSE", @@ -529,6 +523,12 @@ "group": "WM_DEBUG_STATES", "at": "com\/android\/server\/wm\/Task.java" }, + "-1480772131": { + "message": "No app or window is requesting an orientation, return %d for display id=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, "-1474292612": { "message": "Could not find task for id: %d", "level": "DEBUG", @@ -2515,12 +2515,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowToken.java" }, - "845234215": { - "message": "App is requesting an orientation, return %d for display id=%d", - "level": "VERBOSE", - "group": "WM_DEBUG_ORIENTATION", - "at": "com\/android\/server\/wm\/DisplayContent.java" - }, "849147756": { "message": "Finish collecting in transition %d", "level": "VERBOSE", @@ -2923,6 +2917,12 @@ "group": "WM_DEBUG_IME", "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java" }, + "1381227466": { + "message": "App is requesting an orientation, return %d for display id=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/TaskDisplayArea.java" + }, "1401295262": { "message": "Mode default, asking user", "level": "WARN", @@ -3133,6 +3133,18 @@ "group": "WM_DEBUG_RESIZE", "at": "com\/android\/server\/wm\/WindowState.java" }, + "1640436199": { + "message": "No app is requesting an orientation, return %d for display id=%d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/TaskDisplayArea.java" + }, + "1648338379": { + "message": "Display id=%d is ignoring all orientation requests, return %d", + "level": "VERBOSE", + "group": "WM_DEBUG_ORIENTATION", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, "1653210583": { "message": "Removing app %s delayed=%b animation=%s animating=%b", "level": "VERBOSE", diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java index 1718b2aef0c99..e4f8d8ba6399c 100644 --- a/services/core/java/com/android/server/wm/DisplayArea.java +++ b/services/core/java/com/android/server/wm/DisplayArea.java @@ -41,6 +41,7 @@ import android.window.IDisplayAreaOrganizer; import com.android.internal.protolog.common.ProtoLog; import com.android.server.policy.WindowManagerPolicy; +import java.io.PrintWriter; import java.util.Comparator; import java.util.function.BiFunction; import java.util.function.Consumer; @@ -71,6 +72,13 @@ public class DisplayArea extends WindowContainer { IDisplayAreaOrganizer mOrganizer; private final Configuration mTmpConfiguration = new Configuration(); + /** + * 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. + */ + protected boolean mIgnoreOrientationRequest; + DisplayArea(WindowManagerService wms, Type type, String name) { this(wms, type, name, FEATURE_UNDEFINED); } @@ -127,6 +135,52 @@ public class DisplayArea extends WindowContainer { } } + @Override + int getOrientation(int candidate) { + mLastOrientationSource = null; + if (mIgnoreOrientationRequest) { + return SCREEN_ORIENTATION_UNSET; + } + + return super.getOrientation(candidate); + } + + /** + * Sets whether this {@link DisplayArea} should ignore fixed-orientation request from apps and + * windows below it. + * + * @return Whether the display orientation changed after calling this method. + */ + boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) { + if (mIgnoreOrientationRequest == ignoreOrientationRequest) { + return false; + } + mIgnoreOrientationRequest = ignoreOrientationRequest; + + // Check whether we should notify Display to update orientation. + if (mDisplayContent == null) { + return false; + } + + // The orientation request from this DA may now be respected. + if (!ignoreOrientationRequest) { + return mDisplayContent.updateOrientation(); + } + + final int lastOrientation = mDisplayContent.getLastOrientation(); + final WindowContainer lastOrientationSource = mDisplayContent.getLastOrientationSource(); + if (lastOrientation == SCREEN_ORIENTATION_UNSET + || lastOrientation == SCREEN_ORIENTATION_UNSPECIFIED) { + // Orientation won't be changed. + return false; + } + if (lastOrientationSource == null || lastOrientationSource.isDescendantOf(this)) { + // Try update if the orientation may be affected. + return mDisplayContent.updateOrientation(); + } + return false; + } + /** * When a {@link DisplayArea} is repositioned, it should only be moved among its siblings of the * same {@link Type}. @@ -199,6 +253,14 @@ public class DisplayArea extends WindowContainer { proto.end(token); } + @Override + void dump(PrintWriter pw, String prefix, boolean dumpAll) { + super.dump(pw, prefix, dumpAll); + if (mIgnoreOrientationRequest) { + pw.println(prefix + "mIgnoreOrientationRequest=true"); + } + } + @Override long getProtoFieldId() { return DISPLAY_AREA; @@ -409,6 +471,10 @@ public class DisplayArea extends WindowContainer { @Override int getOrientation(int candidate) { mLastOrientationSource = null; + if (mIgnoreOrientationRequest) { + return SCREEN_ORIENTATION_UNSET; + } + // Find a window requesting orientation. final WindowState win = getWindow(mGetOrientingWindow); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index e7f0e3eb7a76c..0bade7db911f1 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -28,8 +28,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; @@ -2347,6 +2347,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override int getOrientation() { mLastOrientationSource = null; + if (mIgnoreOrientationRequest) { + // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation + ProtoLog.v(WM_DEBUG_ORIENTATION, + "Display id=%d is ignoring all orientation requests, return %d", + mDisplayId, SCREEN_ORIENTATION_UNSPECIFIED); + return SCREEN_ORIENTATION_UNSPECIFIED; + } if (mWmService.mDisplayFrozen) { if (mWmService.mPolicy.isKeyguardLocked()) { @@ -2363,19 +2370,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } final int orientation = super.getOrientation(); - if (orientation != SCREEN_ORIENTATION_UNSET && orientation != SCREEN_ORIENTATION_BEHIND) { + if (orientation == SCREEN_ORIENTATION_UNSET) { + // Return SCREEN_ORIENTATION_UNSPECIFIED so that Display respect sensor rotation ProtoLog.v(WM_DEBUG_ORIENTATION, - "App is requesting an orientation, return %d for display id=%d", - orientation, mDisplayId); - return orientation; + "No app or window is requesting an orientation, return %d for display id=%d", + SCREEN_ORIENTATION_UNSPECIFIED, mDisplayId); + return SCREEN_ORIENTATION_UNSPECIFIED; } - ProtoLog.v(WM_DEBUG_ORIENTATION, - "No app is requesting an orientation, return %d for display id=%d", - getLastOrientation(), mDisplayId); - // The next app has not been requested to be visible, so we keep the current orientation - // to prevent freezing/unfreezing the display too early. - return getLastOrientation(); + return orientation; } void updateDisplayInfo() { @@ -4243,6 +4246,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override int getOrientation(int candidate) { + if (mIgnoreOrientationRequest) { + return SCREEN_ORIENTATION_UNSET; + } + // IME does not participate in orientation. return candidate; } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index d69fb0b823d07..830ad5d6043bc 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -29,10 +29,12 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.app.WindowConfiguration.isSplitScreenWindowingMode; +import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS; import static com.android.server.wm.ActivityTaskManagerService.TAG_STACK; @@ -149,13 +151,6 @@ final class TaskDisplayArea extends DisplayArea { */ private boolean mRemoved; - /** - * Whether the task display area should ignore fixed-orientation request. If {@code true}, it - * can never specify orientation, but show the fixed-orientation apps in the letterbox; - * otherwise, it rotates based on the fixed-orientation request when it has the focus. - */ - private boolean mIgnoreOrientationRequest; - /** * The id of a leaf task that most recently being moved to front. */ @@ -654,28 +649,9 @@ final class TaskDisplayArea extends DisplayArea { } } - /** - * Sets whether the task display area should ignore fixed-orientation request from apps. - * - * @return Whether the display orientation changed - */ - boolean setIgnoreOrientationRequest(boolean ignoreOrientationRequest) { - if (mIgnoreOrientationRequest == ignoreOrientationRequest) { - return false; - } - - mIgnoreOrientationRequest = ignoreOrientationRequest; - if (isLastFocused()) { - // Update orientation if this TDA is the last focused, otherwise it shouldn't affect - // the display. - return mDisplayContent.updateOrientation(); - } - - return false; - } - @Override int getOrientation(int candidate) { + mLastOrientationSource = null; // Only allow to specify orientation if this TDA is not set to ignore orientation request, // and it has the focus. if (mIgnoreOrientationRequest || !isLastFocused()) { @@ -708,7 +684,21 @@ final class TaskDisplayArea extends DisplayArea { return SCREEN_ORIENTATION_UNSPECIFIED; } - return super.getOrientation(candidate); + final int orientation = super.getOrientation(candidate); + if (orientation != SCREEN_ORIENTATION_UNSET + && orientation != SCREEN_ORIENTATION_BEHIND) { + ProtoLog.v(WM_DEBUG_ORIENTATION, + "App is requesting an orientation, return %d for display id=%d", + orientation, mDisplayContent.mDisplayId); + return orientation; + } + + ProtoLog.v(WM_DEBUG_ORIENTATION, + "No app is requesting an orientation, return %d for display id=%d", + mDisplayContent.getLastOrientation(), mDisplayContent.mDisplayId); + // The next app has not been requested to be visible, so we keep the current orientation + // to prevent freezing/unfreezing the display too early. + return mDisplayContent.getLastOrientation(); } @Override diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 6a5784435ad66..5e07f5187c546 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -380,24 +380,18 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub return effects; } - private int applyTaskDisplayAreaChanges(TaskDisplayArea taskDisplayArea, - WindowContainerTransaction.Change c) { - int effects = applyDisplayAreaChanges(taskDisplayArea, c); - if ((c.getChangeMask() - & WindowContainerTransaction.Change.CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) { - if (taskDisplayArea.setIgnoreOrientationRequest(c.getIgnoreOrientationRequest())) { - effects |= TRANSACT_EFFECTS_LIFECYCLE; - } - } - - return effects; - } - - private int applyDisplayAreaChanges(WindowContainer container, + private int applyDisplayAreaChanges(DisplayArea displayArea, WindowContainerTransaction.Change c) { final int[] effects = new int[1]; - container.forAllTasks(task -> { + if ((c.getChangeMask() + & WindowContainerTransaction.Change.CHANGE_IGNORE_ORIENTATION_REQUEST) != 0) { + if (displayArea.setIgnoreOrientationRequest(c.getIgnoreOrientationRequest())) { + effects[0] |= TRANSACT_EFFECTS_LIFECYCLE; + } + } + + displayArea.forAllTasks(task -> { Task tr = (Task) task; if ((c.getChangeMask() & WindowContainerTransaction.Change.CHANGE_HIDDEN) != 0) { if (tr.setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, c.getHidden())) { @@ -475,10 +469,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub int effects = applyChanges(wc, c); - if (wc instanceof TaskDisplayArea) { - effects |= applyTaskDisplayAreaChanges((TaskDisplayArea) wc, c); - } else if (wc instanceof DisplayArea) { - effects |= applyDisplayAreaChanges(wc, c); + if (wc instanceof DisplayArea) { + effects |= applyDisplayAreaChanges(wc.asDisplayArea(), c); } else if (wc instanceof Task) { effects |= applyTaskChanges(wc.asTask(), c); } diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java index f88530c1f23e7..01c1f1f73ee9a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java @@ -438,6 +438,28 @@ public class DisplayAreaTest { area.getOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR)); } + @Test + public void testSetIgnoreOrientationRequest() { + final DisplayArea.Tokens area = new DisplayArea.Tokens(mWms, ABOVE_TASKS, "test"); + final WindowToken token = createWindowToken(TYPE_APPLICATION_OVERLAY); + spyOn(token); + doReturn(mock(DisplayContent.class)).when(token).getDisplayContent(); + doNothing().when(token).setParent(any()); + final WindowState win = createWindowState(token); + spyOn(win); + doNothing().when(win).setParent(any()); + win.mAttrs.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + token.addChild(win, 0); + area.addChild(token); + doReturn(true).when(win).isVisible(); + + assertEquals(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, area.getOrientation()); + + area.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */); + + assertEquals(ActivityInfo.SCREEN_ORIENTATION_UNSET, area.getOrientation()); + } + private static class TestDisplayArea extends DisplayArea { private TestDisplayArea(WindowManagerService wms, Rect bounds) { super(wms, ANY, "half display area"); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java index d2b7ac4c3b248..7975899dacbcb 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java @@ -1002,14 +1002,18 @@ public class TaskRecordTests extends WindowTestsBase { public void testNotSpecifyOrientationByFloatingTask() { final Task task = getTestTask(); final ActivityRecord activity = task.getTopMostActivity(); + final WindowContainer parentContainer = task.getParent(); final TaskDisplayArea taskDisplayArea = task.getDisplayArea(); activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); + assertEquals(SCREEN_ORIENTATION_LANDSCAPE, parentContainer.getOrientation()); assertEquals(SCREEN_ORIENTATION_LANDSCAPE, taskDisplayArea.getOrientation()); task.setWindowingMode(WINDOWING_MODE_PINNED); - assertEquals(SCREEN_ORIENTATION_UNSET, taskDisplayArea.getOrientation()); + // TDA returns the last orientation when child returns UNSET + assertEquals(SCREEN_ORIENTATION_UNSET, parentContainer.getOrientation()); + assertEquals(SCREEN_ORIENTATION_LANDSCAPE, taskDisplayArea.getOrientation()); } @Test diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java index 0152fc607f735..45534ddd57b55 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java @@ -366,7 +366,7 @@ public class WindowOrganizerTests extends WindowTestsBase { } @Test - public void testSetIgnoreOrientationRequest() { + public void testSetIgnoreOrientationRequest_taskDisplayArea() { removeGlobalMinSizeRestriction(); final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); final Task stack = taskDisplayArea.createStack( @@ -378,7 +378,7 @@ public class WindowOrganizerTests extends WindowTestsBase { activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); // TDA returns UNSET when ignoreOrientationRequest == true - // DC is UNSPECIFIED because it is using the previous (default) when TDA returns UNSET. + // DC is UNSPECIFIED when child returns UNSET assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET); assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSPECIFIED); @@ -399,8 +399,40 @@ public class WindowOrganizerTests extends WindowTestsBase { mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); // TDA returns UNSET when ignoreOrientationRequest == true - // DC is LANDSCAPE because it is using the previous when TDA returns UNSET. + // DC is UNSPECIFIED when child returns UNSET assertThat(taskDisplayArea.getOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSET); + assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSPECIFIED); + } + + @Test + public void testSetIgnoreOrientationRequest_displayContent() { + removeGlobalMinSizeRestriction(); + final TaskDisplayArea taskDisplayArea = mDisplayContent.getDefaultTaskDisplayArea(); + final Task stack = taskDisplayArea.createStack( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */); + final ActivityRecord activity = new ActivityBuilder(mAtm).setCreateTask(true) + .setStack(stack).build(); + mDisplayContent.setFocusedApp(activity); + activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); + + // DC uses the orientation request from app + assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE); + + WindowContainerTransaction t = new WindowContainerTransaction(); + t.setIgnoreOrientationRequest( + mDisplayContent.mRemoteToken.toWindowContainerToken(), + true /* ignoreOrientationRequest */); + mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); + + // DC returns UNSPECIFIED when ignoreOrientationRequest == true + assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_UNSPECIFIED); + + t.setIgnoreOrientationRequest( + mDisplayContent.mRemoteToken.toWindowContainerToken(), + false /* ignoreOrientationRequest */); + mWm.mAtmService.mWindowOrganizerController.applyTransaction(t); + + // DC uses the orientation request from app after mIgnoreOrientationRequest is set to false assertThat(mDisplayContent.getLastOrientation()).isEqualTo(SCREEN_ORIENTATION_LANDSCAPE); }