Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7dea9ba authored by Darryl L Johnson's avatar Darryl L Johnson
Browse files

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
parent 296855fe
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -564,18 +564,25 @@ final class TaskDisplayArea extends DisplayArea<ActivityStack> {
            // 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 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;
        }

+37 −0
Original line number Diff line number Diff line
@@ -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();