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

Commit a6aca431 authored by Tony Huang's avatar Tony Huang Committed by Automerger Merge Worker
Browse files

Merge "Improve pip to split transition" into tm-qpr-dev am: 95eb72f9 am: 8d1d4fa2

parents 6816b082 8d1d4fa2
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -1479,9 +1479,13 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
                applyFinishBoundsResize(wct, direction, false);
            }
        } else {
            final boolean isPipTopLeft =
                    direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN && isPipToTopLeft();
            applyFinishBoundsResize(wct, direction, isPipTopLeft);
            applyFinishBoundsResize(wct, direction, isPipToTopLeft());
            // Use sync transaction to apply finish transaction for enter split case.
            if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
                mSyncTransactionQueue.runInSync(t -> {
                    t.merge(tx);
                });
            }
        }

        finishResizeForMenu(destinationBounds);
@@ -1518,8 +1522,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener,
        mSurfaceTransactionHelper.round(tx, mLeash, isInPip());

        wct.setBounds(mToken, taskBounds);
        // Pip to split should use sync transaction to sync split bounds change.
        if (direction != TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
            wct.setBoundsChangeTransaction(mToken, tx);
        }
    }

    /**
     * Applies the window container transaction to finish a bounds resize.
+5 −9
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSIT
import static com.android.wm.shell.common.split.SplitScreenUtils.isValidToSplit;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.common.split.SplitScreenUtils.samePackage;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
@@ -89,7 +88,6 @@ import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.recents.RecentTasksController;
import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -339,8 +337,7 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    }

    public boolean moveToSideStage(int taskId, @SplitPosition int sideStagePosition) {
        return moveToStage(taskId, STAGE_TYPE_SIDE, sideStagePosition,
                new WindowContainerTransaction());
        return moveToStage(taskId, sideStagePosition, new WindowContainerTransaction());
    }

    /**
@@ -351,13 +348,13 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
        mStageCoordinator.updateSurfaces(transaction);
    }

    private boolean moveToStage(int taskId, @StageType int stageType,
            @SplitPosition int stagePosition, WindowContainerTransaction wct) {
    private boolean moveToStage(int taskId, @SplitPosition int stagePosition,
            WindowContainerTransaction wct) {
        final ActivityManager.RunningTaskInfo task = mTaskOrganizer.getRunningTaskInfo(taskId);
        if (task == null) {
            throw new IllegalArgumentException("Unknown taskId" + taskId);
        }
        return mStageCoordinator.moveToStage(task, stageType, stagePosition, wct);
        return mStageCoordinator.moveToStage(task, stagePosition, wct);
    }

    public boolean removeFromSideStage(int taskId) {
@@ -382,10 +379,9 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
    }

    public void enterSplitScreen(int taskId, boolean leftOrTop, WindowContainerTransaction wct) {
        final int stageType = isSplitScreenVisible() ? STAGE_TYPE_UNDEFINED : STAGE_TYPE_SIDE;
        final int stagePosition =
                leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT;
        moveToStage(taskId, stageType, stagePosition, wct);
        moveToStage(taskId, stagePosition, wct);
    }

    public void exitSplitScreen(int toTopTaskId, @ExitReason int exitReason) {
+28 −41
Original line number Diff line number Diff line
@@ -373,56 +373,43 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        return STAGE_TYPE_UNDEFINED;
    }

    boolean moveToStage(ActivityManager.RunningTaskInfo task, @StageType int stageType,
            @SplitPosition int stagePosition, WindowContainerTransaction wct) {
    boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition,
            WindowContainerTransaction wct) {
        StageTaskListener targetStage;
        int sideStagePosition;
        if (stageType == STAGE_TYPE_MAIN) {
            targetStage = mMainStage;
            sideStagePosition = reverseSplitPosition(stagePosition);
        } else if (stageType == STAGE_TYPE_SIDE) {
            targetStage = mSideStage;
            sideStagePosition = stagePosition;
        } else {
        if (isSplitScreenVisible()) {
                // If the split screen is activated, retrieves target stage based on position.
            // If the split screen is foreground, retrieves target stage based on position.
            targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage;
            sideStagePosition = mSideStagePosition;
        } else {
                // Exit split if it running background.
                exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);

            targetStage = mSideStage;
            sideStagePosition = stagePosition;
        }
        }

        if (!isSplitActive()) {
            // prevent the fling divider to center transitioni if split screen didn't active.
            mIsDropEntering = true;
        }

            mSplitLayout.init();
            prepareEnterSplitScreen(wct, task, stagePosition);
            mSyncQueue.queue(wct);
            mSyncQueue.runInSync(t -> {
                updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
            });
        } else {
            setSideStagePosition(sideStagePosition, wct);
        final WindowContainerTransaction evictWct = new WindowContainerTransaction();
        targetStage.evictAllChildren(evictWct);

        // Apply surface bounds before animation start.
        SurfaceControl.Transaction startT = mTransactionPool.acquire();
        if (startT != null) {
            updateSurfaceBounds(mSplitLayout, startT, false /* applyResizingOffset */);
            startT.apply();
            mTransactionPool.release(startT);
        }
        // reparent the task to an invisible split root will make the activity invisible.  Reorder
        // the root task to front to make the entering transition from pip to split smooth.
        wct.reorder(mRootTaskInfo.token, true);
        wct.reorder(targetStage.mRootTaskInfo.token, true);
            targetStage.addTask(task, wct);

        if (!evictWct.isEmpty()) {
            wct.merge(evictWct, true /* transfer */);
            targetStage.evictAllChildren(wct);
            if (!isSplitScreenVisible()) {
                final StageTaskListener anotherStage = targetStage == mMainStage
                        ? mSideStage : mMainStage;
                anotherStage.reparentTopTask(wct);
                anotherStage.evictAllChildren(wct);
                wct.reorder(mRootTaskInfo.token, true);
            }
        mTaskOrganizer.applyTransaction(wct);
            setRootForceTranslucent(false, wct);
            mSyncQueue.queue(wct);
        }

        // Due to drag already pip task entering split by this method so need to reset flag here.
        mIsDropEntering = false;
        return true;
    }

+32 −23
Original line number Diff line number Diff line
@@ -145,39 +145,48 @@ public class StageCoordinatorTests extends ShellTestCase {
    }

    @Test
    public void testMoveToStage() {
    public void testMoveToStage_splitActiveBackground() {
        when(mStageCoordinator.isSplitActive()).thenReturn(true);

        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
        verify(mSideStage).addTask(eq(task), eq(wct));
        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
    }

    @Test
    public void testMoveToStage_splitActiveForeground() {
        when(mStageCoordinator.isSplitActive()).thenReturn(true);
        when(mStageCoordinator.isSplitScreenVisible()).thenReturn(true);
        // Assume current side stage is top or left.
        mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null);

        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        mStageCoordinator.moveToStage(task, STAGE_TYPE_MAIN, SPLIT_POSITION_BOTTOM_OR_RIGHT,
                new WindowContainerTransaction());
        verify(mMainStage).addTask(eq(task), any(WindowContainerTransaction.class));
        mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
        verify(mMainStage).addTask(eq(task), eq(wct));
        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());

        mStageCoordinator.moveToStage(task, STAGE_TYPE_SIDE, SPLIT_POSITION_BOTTOM_OR_RIGHT,
                new WindowContainerTransaction());
        verify(mSideStage).addTask(eq(task), any(WindowContainerTransaction.class));
        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
        mStageCoordinator.moveToStage(task, SPLIT_POSITION_TOP_OR_LEFT, wct);
        verify(mSideStage).addTask(eq(task), eq(wct));
        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());
        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
    }

    @Test
    public void testMoveToUndefinedStage() {
    public void testMoveToStage_splitInctive() {
        final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
        final WindowContainerTransaction wct = new WindowContainerTransaction();

        // Verify move to undefined stage while split screen not activated moves task to side stage.
        when(mStageCoordinator.isSplitScreenVisible()).thenReturn(false);
        mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null);
        mStageCoordinator.moveToStage(task, STAGE_TYPE_UNDEFINED, SPLIT_POSITION_BOTTOM_OR_RIGHT,
                new WindowContainerTransaction());
        verify(mSideStage).addTask(eq(task), any(WindowContainerTransaction.class));
        mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
        verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
                eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
        assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());

        // Verify move to undefined stage after split screen activated moves task based on position.
        when(mStageCoordinator.isSplitScreenVisible()).thenReturn(true);
        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
        mStageCoordinator.moveToStage(task, STAGE_TYPE_UNDEFINED, SPLIT_POSITION_TOP_OR_LEFT,
                new WindowContainerTransaction());
        verify(mMainStage).addTask(eq(task), any(WindowContainerTransaction.class));
        assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
    }

    @Test