diff options
4 files changed, 76 insertions, 77 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index 52f5a8cfd8e0..9f4849a8188d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -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,7 +1522,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mSurfaceTransactionHelper.round(tx, mLeash, isInPip()); wct.setBounds(mToken, taskBounds); - wct.setBoundsChangeTransaction(mToken, tx); + // 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); + } } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java index 94b9e907fa76..53449357a674 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java @@ -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) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index a1eaf851da23..def945e53f9b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -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) { + if (isSplitScreenVisible()) { + // If the split screen is foreground, retrieves target stage based on position. + targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage; + sideStagePosition = mSideStagePosition; + } else { targetStage = mSideStage; sideStagePosition = stagePosition; - } else { - if (isSplitScreenVisible()) { - // If the split screen is activated, 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; - } - - 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); + mSplitLayout.init(); + prepareEnterSplitScreen(wct, task, stagePosition); + mSyncQueue.queue(wct); + mSyncQueue.runInSync(t -> { + updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); + }); + } else { + setSideStagePosition(sideStagePosition, wct); + targetStage.addTask(task, wct); + targetStage.evictAllChildren(wct); + if (!isSplitScreenVisible()) { + final StageTaskListener anotherStage = targetStage == mMainStage + ? mSideStage : mMainStage; + anotherStage.reparentTopTask(wct); + anotherStage.evictAllChildren(wct); + wct.reorder(mRootTaskInfo.token, true); + } + setRootForceTranslucent(false, wct); + mSyncQueue.queue(wct); } - // 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 */); - } - mTaskOrganizer.applyTransaction(wct); + // Due to drag already pip task entering split by this method so need to reset flag here. + mIsDropEntering = false; return true; } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java index 2e2e49e40030..eda6fdc4dbd4 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java @@ -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 |