summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java15
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java69
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java55
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