diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 7b690383f5f92..e230807240005 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -564,16 +564,23 @@ final class TaskDisplayArea extends DisplayArea { // Apps and their containers are not allowed to specify an orientation while using // root tasks...except for the home stack if it is not resizable and currently // visible (top of) its root task. - if (mRootHomeTask != null && mRootHomeTask.isVisible() - && !mRootHomeTask.isResizeable()) { + if (mRootHomeTask != null && !mRootHomeTask.isResizeable()) { // Manually nest one-level because because getOrientation() checks fillsParent() // which checks that requestedOverrideBounds() is empty. However, in this case, // it is not empty because it's been overridden to maintain the fullscreen size // within a smaller split-root. final Task topHomeTask = mRootHomeTask.getTopMostTask(); - final int orientation = topHomeTask.getOrientation(); - if (orientation != SCREEN_ORIENTATION_UNSET) { - return orientation; + final ActivityRecord topHomeActivity = topHomeTask.getTopNonFinishingActivity(); + // If a home activity is in the process of launching and isn't yet visible we + // should still respect the stack's preferred orientation to ensure rotation occurs + // before the home activity finishes launching. + final boolean isHomeActivityLaunching = topHomeActivity != null + && topHomeActivity.mVisibleRequested; + if (topHomeTask.isVisible() || isHomeActivityLaunching) { + final int orientation = topHomeTask.getOrientation(); + if (orientation != SCREEN_ORIENTATION_UNSET) { + return orientation; + } } } return SCREEN_ORIENTATION_UNSPECIFIED; diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java index 786f8d8af0249..8c3661b409f40 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java @@ -28,14 +28,17 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.wm.ActivityStack.ActivityState.RESUMED; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -207,6 +210,40 @@ public class TaskDisplayAreaTests extends WindowTestsBase { false /* reuseCandidate */); } + @Test + public void testGetOrientation_nonResizableHomeStackWithHomeActivityPendingVisibilityChange() { + final RootWindowContainer rootWindowContainer = mWm.mAtmService.mRootWindowContainer; + final TaskDisplayArea defaultTaskDisplayArea = + rootWindowContainer.getDefaultTaskDisplayArea(); + + final ActivityStack rootHomeTask = defaultTaskDisplayArea.getRootHomeTask(); + rootHomeTask.mResizeMode = RESIZE_MODE_UNRESIZEABLE; + + final ActivityStack primarySplitTask = + new ActivityTestsBase.StackBuilder(rootWindowContainer) + .setTaskDisplayArea(defaultTaskDisplayArea) + .setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) + .setActivityType(ACTIVITY_TYPE_STANDARD) + .setOnTop(true) + .setCreateActivity(true) + .build(); + ActivityRecord primarySplitActivity = primarySplitTask.getTopNonFinishingActivity(); + assertNotNull(primarySplitActivity); + primarySplitActivity.setState(RESUMED, + "testGetOrientation_nonResizableHomeStackWithHomeActivityPendingVisibilityChange"); + + ActivityRecord homeActivity = rootHomeTask.getTopNonFinishingActivity(); + if (homeActivity == null) { + homeActivity = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService) + .setStack(rootHomeTask).setCreateTask(true).build(); + } + homeActivity.setVisible(false); + homeActivity.mVisibleRequested = true; + assertFalse(rootHomeTask.isVisible()); + + assertEquals(rootWindowContainer.getOrientation(), rootHomeTask.getOrientation()); + } + private void assertGetOrCreateStack(int windowingMode, int activityType, Task candidateTask, boolean reuseCandidate) { final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea();