Merge changes Icb7ba7d1,If6d5e6ec into udc-dev
* changes: Fix black screen when recents finished after split Migrate moveToStage shell transition
This commit is contained in:
@@ -59,4 +59,17 @@ public class SplitScreenConstants {
|
||||
|
||||
/** Flag applied to a transition change to identify it as a divider bar for animation. */
|
||||
public static final int FLAG_IS_DIVIDER_BAR = FLAG_FIRST_CUSTOM;
|
||||
|
||||
public static final String splitPositionToString(@SplitPosition int pos) {
|
||||
switch (pos) {
|
||||
case SPLIT_POSITION_UNDEFINED:
|
||||
return "SPLIT_POSITION_UNDEFINED";
|
||||
case SPLIT_POSITION_TOP_OR_LEFT:
|
||||
return "SPLIT_POSITION_TOP_OR_LEFT";
|
||||
case SPLIT_POSITION_BOTTOM_OR_RIGHT:
|
||||
return "SPLIT_POSITION_BOTTOM_OR_RIGHT";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIV
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.splitPositionToString;
|
||||
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_MAIN;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
|
||||
@@ -378,40 +379,18 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition,
|
||||
WindowContainerTransaction wct) {
|
||||
StageTaskListener targetStage;
|
||||
int sideStagePosition;
|
||||
if (isSplitScreenVisible()) {
|
||||
// If the split screen is foreground, retrieves target stage based on position.
|
||||
targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage;
|
||||
sideStagePosition = mSideStagePosition;
|
||||
prepareEnterSplitScreen(wct, task, stagePosition);
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
|
||||
null, this, null /* consumedCallback */, null /* finishedCallback */,
|
||||
isSplitScreenVisible()
|
||||
? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN);
|
||||
} else {
|
||||
targetStage = mSideStage;
|
||||
sideStagePosition = stagePosition;
|
||||
}
|
||||
|
||||
if (!isSplitActive()) {
|
||||
mSplitLayout.init();
|
||||
prepareEnterSplitScreen(wct, task, stagePosition);
|
||||
mSyncQueue.queue(wct);
|
||||
mSyncQueue.runInSync(t -> {
|
||||
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
|
||||
setDividerVisibility(true, t);
|
||||
});
|
||||
} 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);
|
||||
}
|
||||
|
||||
// Due to drag already pip task entering split by this method so need to reset flag here.
|
||||
mIsDropEntering = false;
|
||||
return true;
|
||||
@@ -1509,9 +1488,51 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
*/
|
||||
void prepareEnterSplitScreen(WindowContainerTransaction wct,
|
||||
@Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
|
||||
if (mMainStage.isActive()) return;
|
||||
|
||||
onSplitScreenEnter();
|
||||
if (isSplitActive()) {
|
||||
prepareBringSplit(wct, taskInfo, startPosition);
|
||||
} else {
|
||||
prepareActiveSplit(wct, taskInfo, startPosition);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareBringSplit(WindowContainerTransaction wct,
|
||||
@Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
|
||||
StageTaskListener targetStage;
|
||||
if (isSplitScreenVisible()) {
|
||||
// If the split screen is foreground, retrieves target stage based on position.
|
||||
targetStage = startPosition == mSideStagePosition ? mSideStage : mMainStage;
|
||||
} else {
|
||||
targetStage = mSideStage;
|
||||
}
|
||||
|
||||
if (taskInfo != null) {
|
||||
wct.startTask(taskInfo.taskId,
|
||||
resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct));
|
||||
targetStage.evictAllChildren(wct);
|
||||
}
|
||||
// If running background, we need to reparent current top visible task to another stage
|
||||
// and evict all tasks current under its.
|
||||
if (!isSplitScreenVisible()) {
|
||||
// Recreate so we need to reset position rather than keep position of background split.
|
||||
mSplitLayout.resetDividerPosition();
|
||||
updateWindowBounds(mSplitLayout, wct);
|
||||
final StageTaskListener anotherStage = targetStage == mMainStage
|
||||
? mSideStage : mMainStage;
|
||||
anotherStage.evictAllChildren(wct);
|
||||
anotherStage.reparentTopTask(wct);
|
||||
wct.reorder(mRootTaskInfo.token, true);
|
||||
setRootForceTranslucent(false, wct);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareActiveSplit(WindowContainerTransaction wct,
|
||||
@Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) {
|
||||
if (!ENABLE_SHELL_TRANSITIONS) {
|
||||
// Legacy transition we need to create divider here, shell transition case we will
|
||||
// create it on #finishEnterSplitScreen
|
||||
mSplitLayout.init();
|
||||
}
|
||||
if (taskInfo != null) {
|
||||
setSideStagePosition(startPosition, wct);
|
||||
mSideStage.addTask(taskInfo, wct);
|
||||
@@ -2383,7 +2404,17 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
|
||||
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
|
||||
if (taskInfo == null || !taskInfo.hasParentTask()) continue;
|
||||
if (taskInfo == null) continue;
|
||||
if (taskInfo.token.equals(mRootTaskInfo.token)) {
|
||||
if (isOpeningType(change.getMode())) {
|
||||
// Split is opened by someone so set it as visible.
|
||||
setSplitsVisible(true);
|
||||
} else if (isClosingType(change.getMode())) {
|
||||
// Split is closed by someone so set it as invisible.
|
||||
setSplitsVisible(false);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
final StageTaskListener stage = getStageOfTask(taskInfo);
|
||||
if (stage == null) continue;
|
||||
if (isOpeningType(change.getMode())) {
|
||||
@@ -2823,12 +2854,18 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
final String childPrefix = innerPrefix + " ";
|
||||
pw.println(prefix + TAG + " mDisplayId=" + mDisplayId);
|
||||
pw.println(innerPrefix + "mDividerVisible=" + mDividerVisible);
|
||||
pw.println(innerPrefix + "isSplitActive=" + isSplitActive());
|
||||
pw.println(innerPrefix + "isSplitVisible=" + isSplitScreenVisible());
|
||||
pw.println(innerPrefix + "MainStage");
|
||||
pw.println(childPrefix + "stagePosition=" + getMainStagePosition());
|
||||
pw.println(childPrefix + "stagePosition=" + splitPositionToString(getMainStagePosition()));
|
||||
pw.println(childPrefix + "isActive=" + mMainStage.isActive());
|
||||
mMainStage.dump(pw, childPrefix);
|
||||
pw.println(innerPrefix + "MainStageListener");
|
||||
mMainStageListener.dump(pw, childPrefix);
|
||||
pw.println(innerPrefix + "SideStage");
|
||||
pw.println(childPrefix + "stagePosition=" + getSideStagePosition());
|
||||
pw.println(childPrefix + "stagePosition=" + splitPositionToString(getSideStagePosition()));
|
||||
mSideStage.dump(pw, childPrefix);
|
||||
pw.println(innerPrefix + "SideStageListener");
|
||||
mSideStageListener.dump(pw, childPrefix);
|
||||
if (mMainStage.isActive()) {
|
||||
pw.println(innerPrefix + "SplitLayout");
|
||||
|
||||
@@ -421,6 +421,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
public void dump(@NonNull PrintWriter pw, String prefix) {
|
||||
final String innerPrefix = prefix + " ";
|
||||
final String childPrefix = innerPrefix + " ";
|
||||
pw.println(prefix + this);
|
||||
if (mChildrenTaskInfo.size() > 0) {
|
||||
pw.println(prefix + "Children list:");
|
||||
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
|
||||
final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.valueAt(i);
|
||||
pw.println(childPrefix + "Task#" + i + " taskID=" + taskInfo.taskId
|
||||
+ " baseActivity=" + taskInfo.baseActivity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
/** Pip was entered while handling an intent with its own remoteTransition. */
|
||||
static final int TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE = 3;
|
||||
|
||||
/** Recents transition while split-screen active. */
|
||||
/** Recents transition while split-screen foreground. */
|
||||
static final int TYPE_RECENTS_DURING_SPLIT = 4;
|
||||
|
||||
/** The default animation for this mixed transition. */
|
||||
@@ -152,7 +152,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
@NonNull TransitionRequestInfo request) {
|
||||
if (mPipHandler.requestHasPipEnter(request) && mSplitHandler.isSplitScreenVisible()) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a PiP-enter request while "
|
||||
+ "Split-Screen is active, so treat it as Mixed.");
|
||||
+ "Split-Screen is foreground, so treat it as Mixed.");
|
||||
if (request.getRemoteTransition() != null) {
|
||||
throw new IllegalStateException("Unexpected remote transition in"
|
||||
+ "pip-enter-from-split request");
|
||||
@@ -183,13 +183,13 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
mixed.mLeftoversHandler = handler.first;
|
||||
mActiveTransitions.add(mixed);
|
||||
return handler.second;
|
||||
} else if (mSplitHandler.isSplitActive()
|
||||
} else if (mSplitHandler.isSplitScreenVisible()
|
||||
&& isOpeningType(request.getType())
|
||||
&& request.getTriggerTask() != null
|
||||
&& request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
|
||||
&& request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_HOME) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a going-home request while "
|
||||
+ "Split-Screen is active, so treat it as Mixed.");
|
||||
+ "Split-Screen is foreground, so treat it as Mixed.");
|
||||
Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler =
|
||||
mPlayer.dispatchRequest(transition, request, this);
|
||||
if (handler == null) {
|
||||
@@ -211,7 +211,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
|
||||
@Override
|
||||
public Transitions.TransitionHandler handleRecentsRequest(WindowContainerTransaction outWCT) {
|
||||
if (mRecentsHandler != null && mSplitHandler.isSplitActive()) {
|
||||
if (mRecentsHandler != null && mSplitHandler.isSplitScreenVisible()) {
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
@@ -219,9 +219,9 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
|
||||
@Override
|
||||
public void setRecentsTransition(IBinder transition) {
|
||||
if (mSplitHandler.isSplitActive()) {
|
||||
if (mSplitHandler.isSplitScreenVisible()) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
|
||||
+ "Split-Screen is active, so treat it as Mixed.");
|
||||
+ "Split-Screen is foreground, so treat it as Mixed.");
|
||||
final MixedTransition mixed = new MixedTransition(
|
||||
MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
|
||||
mixed.mLeftoversHandler = mRecentsHandler;
|
||||
@@ -351,7 +351,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
@NonNull SurfaceControl.Transaction finishTransaction,
|
||||
@NonNull Transitions.TransitionFinishCallback finishCallback) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Animating a mixed transition for "
|
||||
+ "entering PIP while Split-Screen is active.");
|
||||
+ "entering PIP while Split-Screen is foreground.");
|
||||
TransitionInfo.Change pipChange = null;
|
||||
TransitionInfo.Change wallpaper = null;
|
||||
final TransitionInfo everythingElse = subCopy(info, TRANSIT_TO_BACK, true /* changes */);
|
||||
|
||||
@@ -152,10 +152,15 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
when(mStageCoordinator.isSplitActive()).thenReturn(true);
|
||||
|
||||
final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
final WindowContainerTransaction wct = spy(new WindowContainerTransaction());
|
||||
|
||||
mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
|
||||
verify(mSideStage).addTask(eq(task), eq(wct));
|
||||
verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
|
||||
eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
|
||||
verify(mMainStage).reparentTopTask(eq(wct));
|
||||
verify(mMainStage).evictAllChildren(eq(wct));
|
||||
verify(mSideStage).evictAllChildren(eq(wct));
|
||||
verify(mSplitLayout).resetDividerPosition();
|
||||
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
|
||||
assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
|
||||
}
|
||||
@@ -171,14 +176,11 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
|
||||
mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
|
||||
verify(mMainStage).addTask(eq(task), eq(wct));
|
||||
verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
|
||||
eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
|
||||
verify(mMainStage).evictAllChildren(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
|
||||
|
||||
Reference in New Issue
Block a user