Merge "Improve pip to split transition" into tm-qpr-dev
This commit is contained in:
@@ -1481,9 +1481,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);
|
||||
@@ -1520,7 +1524,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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -399,56 +399,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;
|
||||
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);
|
||||
}
|
||||
|
||||
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 */);
|
||||
}
|
||||
mTaskOrganizer.applyTransaction(wct);
|
||||
// Due to drag already pip task entering split by this method so need to reset flag here.
|
||||
mIsDropEntering = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,39 +144,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, STAGE_TYPE_MAIN, SPLIT_POSITION_BOTTOM_OR_RIGHT,
|
||||
new WindowContainerTransaction());
|
||||
verify(mMainStage).addTask(eq(task), any(WindowContainerTransaction.class));
|
||||
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
|
||||
|
||||
mStageCoordinator.moveToStage(task, STAGE_TYPE_SIDE, 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(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 testMoveToUndefinedStage() {
|
||||
final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
|
||||
|
||||
// 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));
|
||||
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
|
||||
|
||||
// Verify move to undefined stage after split screen activated moves task based on position.
|
||||
public void testMoveToStage_splitActiveForeground() {
|
||||
when(mStageCoordinator.isSplitActive()).thenReturn(true);
|
||||
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());
|
||||
// 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, 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, 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 testMoveToStage_splitInctive() {
|
||||
final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user