From b7dea9baf7e38296bee2e26b4291846864e09de5 Mon Sep 17 00:00:00 2001 From: Darryl L Johnson Date: Mon, 22 Jun 2020 19:52:31 -0700 Subject: [PATCH] Respect the orientation of a home activity in the process of launching when split-screen enabled. The home activity in the process of launching isn't considered visible (isVisible() returns false) since an app transition prevents the value from being committed. This ensures that the orientation value returned for TaskDisplayArea#getOrientation() also takes into account home activities currently in the process of launching when split-screen is enabled. Fixes: 159473343 Test: Install non-resizable 3P home. Enter split screen primary with recents on secondary, rotate device, navigate back. Test: TaskDisplayAreaTests#testGetOrientation_nonResizableHomeStackWithHomeActivityPendingVisibilityChange Change-Id: I0b14bbe222a13ecdfc3245af2ae7db75eb374e7a --- .../android/server/wm/TaskDisplayArea.java | 17 ++++++--- .../server/wm/TaskDisplayAreaTests.java | 37 +++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) 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();