Merge "Add fallback logic to cancel entering split screen" into tm-qpr-dev
This commit is contained in:
@@ -108,6 +108,14 @@ class SplitScreenTransitions {
|
||||
private void playInternalAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
|
||||
@NonNull SurfaceControl.Transaction t, @NonNull WindowContainerToken mainRoot,
|
||||
@NonNull WindowContainerToken sideRoot, @NonNull WindowContainerToken topRoot) {
|
||||
final TransitSession pendingTransition = getPendingTransition(transition);
|
||||
if (pendingTransition != null && pendingTransition.mCanceled) {
|
||||
// The pending transition was canceled, so skip playing animation.
|
||||
t.apply();
|
||||
onFinish(null /* wct */, null /* wctCB */);
|
||||
return;
|
||||
}
|
||||
|
||||
// Play some place-holder fade animations
|
||||
for (int i = info.getChanges().size() - 1; i >= 0; --i) {
|
||||
final TransitionInfo.Change change = info.getChanges().get(i);
|
||||
@@ -170,9 +178,7 @@ class SplitScreenTransitions {
|
||||
}
|
||||
|
||||
boolean isPendingTransition(IBinder transition) {
|
||||
return isPendingEnter(transition)
|
||||
|| isPendingDismiss(transition)
|
||||
|| isPendingRecent(transition);
|
||||
return getPendingTransition(transition) != null;
|
||||
}
|
||||
|
||||
boolean isPendingEnter(IBinder transition) {
|
||||
@@ -187,22 +193,38 @@ class SplitScreenTransitions {
|
||||
return mPendingDismiss != null && mPendingDismiss.mTransition == transition;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TransitSession getPendingTransition(IBinder transition) {
|
||||
if (isPendingEnter(transition)) {
|
||||
return mPendingEnter;
|
||||
} else if (isPendingRecent(transition)) {
|
||||
return mPendingRecent;
|
||||
} else if (isPendingDismiss(transition)) {
|
||||
return mPendingDismiss;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Starts a transition to enter split with a remote transition animator. */
|
||||
IBinder startEnterTransition(
|
||||
@WindowManager.TransitionType int transitType,
|
||||
WindowContainerTransaction wct,
|
||||
@Nullable RemoteTransition remoteTransition,
|
||||
Transitions.TransitionHandler handler,
|
||||
@Nullable TransitionCallback callback) {
|
||||
@Nullable TransitionConsumedCallback consumedCallback,
|
||||
@Nullable TransitionFinishedCallback finishedCallback) {
|
||||
final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
|
||||
setEnterTransition(transition, remoteTransition, callback);
|
||||
setEnterTransition(transition, remoteTransition, consumedCallback, finishedCallback);
|
||||
return transition;
|
||||
}
|
||||
|
||||
/** Sets a transition to enter split. */
|
||||
void setEnterTransition(@NonNull IBinder transition,
|
||||
@Nullable RemoteTransition remoteTransition, @Nullable TransitionCallback callback) {
|
||||
mPendingEnter = new TransitSession(transition, callback);
|
||||
@Nullable RemoteTransition remoteTransition,
|
||||
@Nullable TransitionConsumedCallback consumedCallback,
|
||||
@Nullable TransitionFinishedCallback finishedCallback) {
|
||||
mPendingEnter = new TransitSession(transition, consumedCallback, finishedCallback);
|
||||
|
||||
if (remoteTransition != null) {
|
||||
// Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
|
||||
@@ -237,8 +259,9 @@ class SplitScreenTransitions {
|
||||
}
|
||||
|
||||
void setRecentTransition(@NonNull IBinder transition,
|
||||
@Nullable RemoteTransition remoteTransition, @Nullable TransitionCallback callback) {
|
||||
mPendingRecent = new TransitSession(transition, callback);
|
||||
@Nullable RemoteTransition remoteTransition,
|
||||
@Nullable TransitionFinishedCallback finishCallback) {
|
||||
mPendingRecent = new TransitSession(transition, null /* consumedCb */, finishCallback);
|
||||
|
||||
if (remoteTransition != null) {
|
||||
// Wrapping it for ease-of-use (OneShot handles all the binder linking/death stuff)
|
||||
@@ -248,7 +271,7 @@ class SplitScreenTransitions {
|
||||
}
|
||||
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
|
||||
+ " deduced Enter recent panel");
|
||||
+ " deduced Enter recent panel");
|
||||
}
|
||||
|
||||
void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
|
||||
@@ -256,14 +279,9 @@ class SplitScreenTransitions {
|
||||
if (mergeTarget != mAnimatingTransition) return;
|
||||
|
||||
if (isPendingEnter(transition) && isPendingRecent(mergeTarget)) {
|
||||
mPendingRecent.mCallback = new TransitionCallback() {
|
||||
@Override
|
||||
public void onTransitionFinished(WindowContainerTransaction finishWct,
|
||||
SurfaceControl.Transaction finishT) {
|
||||
// Since there's an entering transition merged, recent transition no longer
|
||||
// need to handle entering split screen after the transition finished.
|
||||
}
|
||||
};
|
||||
// Since there's an entering transition merged, recent transition no longer
|
||||
// need to handle entering split screen after the transition finished.
|
||||
mPendingRecent.setFinishedCallback(null);
|
||||
}
|
||||
|
||||
if (mActiveRemoteHandler != null) {
|
||||
@@ -277,7 +295,7 @@ class SplitScreenTransitions {
|
||||
}
|
||||
|
||||
boolean end() {
|
||||
// If its remote, there's nothing we can do right now.
|
||||
// If It's remote, there's nothing we can do right now.
|
||||
if (mActiveRemoteHandler != null) return false;
|
||||
for (int i = mAnimations.size() - 1; i >= 0; --i) {
|
||||
final Animator anim = mAnimations.get(i);
|
||||
@@ -290,20 +308,20 @@ class SplitScreenTransitions {
|
||||
@Nullable SurfaceControl.Transaction finishT) {
|
||||
if (isPendingEnter(transition)) {
|
||||
if (!aborted) {
|
||||
// An enter transition got merged, appends the rest operations to finish entering
|
||||
// An entering transition got merged, appends the rest operations to finish entering
|
||||
// split screen.
|
||||
mStageCoordinator.finishEnterSplitScreen(finishT);
|
||||
mPendingRemoteHandler = null;
|
||||
}
|
||||
|
||||
mPendingEnter.mCallback.onTransitionConsumed(aborted);
|
||||
mPendingEnter.onConsumed(aborted);
|
||||
mPendingEnter = null;
|
||||
mPendingRemoteHandler = null;
|
||||
} else if (isPendingDismiss(transition)) {
|
||||
mPendingDismiss.mCallback.onTransitionConsumed(aborted);
|
||||
mPendingDismiss.onConsumed(aborted);
|
||||
mPendingDismiss = null;
|
||||
} else if (isPendingRecent(transition)) {
|
||||
mPendingRecent.mCallback.onTransitionConsumed(aborted);
|
||||
mPendingRecent.onConsumed(aborted);
|
||||
mPendingRecent = null;
|
||||
mPendingRemoteHandler = null;
|
||||
}
|
||||
@@ -312,23 +330,16 @@ class SplitScreenTransitions {
|
||||
void onFinish(WindowContainerTransaction wct, WindowContainerTransactionCallback wctCB) {
|
||||
if (!mAnimations.isEmpty()) return;
|
||||
|
||||
TransitionCallback callback = null;
|
||||
if (wct == null) wct = new WindowContainerTransaction();
|
||||
if (isPendingEnter(mAnimatingTransition)) {
|
||||
callback = mPendingEnter.mCallback;
|
||||
mPendingEnter.onFinished(wct, mFinishTransaction);
|
||||
mPendingEnter = null;
|
||||
}
|
||||
if (isPendingDismiss(mAnimatingTransition)) {
|
||||
callback = mPendingDismiss.mCallback;
|
||||
mPendingDismiss = null;
|
||||
}
|
||||
if (isPendingRecent(mAnimatingTransition)) {
|
||||
callback = mPendingRecent.mCallback;
|
||||
} else if (isPendingRecent(mAnimatingTransition)) {
|
||||
mPendingRecent.onFinished(wct, mFinishTransaction);
|
||||
mPendingRecent = null;
|
||||
}
|
||||
|
||||
if (callback != null) {
|
||||
if (wct == null) wct = new WindowContainerTransaction();
|
||||
callback.onTransitionFinished(wct, mFinishTransaction);
|
||||
} else if (isPendingDismiss(mAnimatingTransition)) {
|
||||
mPendingDismiss.onFinished(wct, mFinishTransaction);
|
||||
mPendingDismiss = null;
|
||||
}
|
||||
|
||||
mPendingRemoteHandler = null;
|
||||
@@ -363,10 +374,7 @@ class SplitScreenTransitions {
|
||||
onFinish(null /* wct */, null /* wctCB */);
|
||||
});
|
||||
};
|
||||
va.addListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) { }
|
||||
|
||||
va.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
finisher.run();
|
||||
@@ -376,9 +384,6 @@ class SplitScreenTransitions {
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
finisher.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) { }
|
||||
});
|
||||
mAnimations.add(va);
|
||||
mTransitions.getAnimExecutor().execute(va::start);
|
||||
@@ -432,24 +437,66 @@ class SplitScreenTransitions {
|
||||
|| info.getType() == TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
|
||||
}
|
||||
|
||||
/** Clean-up callbacks for transition. */
|
||||
interface TransitionCallback {
|
||||
/** Calls when the transition got consumed. */
|
||||
default void onTransitionConsumed(boolean aborted) {}
|
||||
/** Calls when the transition got consumed. */
|
||||
interface TransitionConsumedCallback {
|
||||
void onConsumed(boolean aborted);
|
||||
}
|
||||
|
||||
/** Calls when the transition finished. */
|
||||
default void onTransitionFinished(WindowContainerTransaction finishWct,
|
||||
SurfaceControl.Transaction finishT) {}
|
||||
/** Calls when the transition finished. */
|
||||
interface TransitionFinishedCallback {
|
||||
void onFinished(WindowContainerTransaction wct, SurfaceControl.Transaction t);
|
||||
}
|
||||
|
||||
/** Session for a transition and its clean-up callback. */
|
||||
static class TransitSession {
|
||||
final IBinder mTransition;
|
||||
TransitionCallback mCallback;
|
||||
TransitionConsumedCallback mConsumedCallback;
|
||||
TransitionFinishedCallback mFinishedCallback;
|
||||
|
||||
TransitSession(IBinder transition, @Nullable TransitionCallback callback) {
|
||||
/** Whether the transition was canceled. */
|
||||
boolean mCanceled;
|
||||
|
||||
TransitSession(IBinder transition,
|
||||
@Nullable TransitionConsumedCallback consumedCallback,
|
||||
@Nullable TransitionFinishedCallback finishedCallback) {
|
||||
mTransition = transition;
|
||||
mCallback = callback != null ? callback : new TransitionCallback() {};
|
||||
mConsumedCallback = consumedCallback;
|
||||
mFinishedCallback = finishedCallback;
|
||||
|
||||
}
|
||||
|
||||
/** Sets transition consumed callback. */
|
||||
void setConsumedCallback(@Nullable TransitionConsumedCallback callback) {
|
||||
mConsumedCallback = callback;
|
||||
}
|
||||
|
||||
/** Sets transition finished callback. */
|
||||
void setFinishedCallback(@Nullable TransitionFinishedCallback callback) {
|
||||
mFinishedCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the transition. This should be called before playing animation. A canceled
|
||||
* transition will skip playing animation.
|
||||
*
|
||||
* @param finishedCb new finish callback to override.
|
||||
*/
|
||||
void cancel(@Nullable TransitionFinishedCallback finishedCb) {
|
||||
mCanceled = true;
|
||||
setFinishedCallback(finishedCb);
|
||||
}
|
||||
|
||||
void onConsumed(boolean aborted) {
|
||||
if (mConsumedCallback != null) {
|
||||
mConsumedCallback.onConsumed(aborted);
|
||||
}
|
||||
}
|
||||
|
||||
void onFinished(WindowContainerTransaction finishWct,
|
||||
SurfaceControl.Transaction finishT) {
|
||||
if (mFinishedCallback != null) {
|
||||
mFinishedCallback.onFinished(finishWct, finishT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,7 +506,7 @@ class SplitScreenTransitions {
|
||||
final @SplitScreen.StageType int mDismissTop;
|
||||
|
||||
DismissTransition(IBinder transition, int reason, int dismissTop) {
|
||||
super(transition, null /* callback */);
|
||||
super(transition, null /* consumedCallback */, null /* finishedCallback */);
|
||||
this.mReason = reason;
|
||||
this.mDismissTop = dismissTop;
|
||||
}
|
||||
|
||||
@@ -226,33 +226,36 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
};
|
||||
|
||||
private final SplitScreenTransitions.TransitionCallback mRecentTransitionCallback =
|
||||
new SplitScreenTransitions.TransitionCallback() {
|
||||
@Override
|
||||
public void onTransitionFinished(WindowContainerTransaction finishWct,
|
||||
SurfaceControl.Transaction finishT) {
|
||||
// Check if the recent transition is finished by returning to the current split, so we
|
||||
// can restore the divider bar.
|
||||
for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
|
||||
final WindowContainerTransaction.HierarchyOp op =
|
||||
finishWct.getHierarchyOps().get(i);
|
||||
final IBinder container = op.getContainer();
|
||||
if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
|
||||
&& (mMainStage.containsContainer(container)
|
||||
|| mSideStage.containsContainer(container))) {
|
||||
updateSurfaceBounds(mSplitLayout, finishT, false /* applyResizingOffset */);
|
||||
setDividerVisibility(true, finishT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
private final SplitScreenTransitions.TransitionFinishedCallback
|
||||
mRecentTransitionFinishedCallback =
|
||||
new SplitScreenTransitions.TransitionFinishedCallback() {
|
||||
@Override
|
||||
public void onFinished(WindowContainerTransaction finishWct,
|
||||
SurfaceControl.Transaction finishT) {
|
||||
// Check if the recent transition is finished by returning to the current
|
||||
// split, so we
|
||||
// can restore the divider bar.
|
||||
for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
|
||||
final WindowContainerTransaction.HierarchyOp op =
|
||||
finishWct.getHierarchyOps().get(i);
|
||||
final IBinder container = op.getContainer();
|
||||
if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
|
||||
&& (mMainStage.containsContainer(container)
|
||||
|| mSideStage.containsContainer(container))) {
|
||||
updateSurfaceBounds(mSplitLayout, finishT,
|
||||
false /* applyResizingOffset */);
|
||||
setDividerVisibility(true, finishT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Dismiss the split screen if it's not returning to split.
|
||||
prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, finishWct);
|
||||
setSplitsVisible(false);
|
||||
setDividerVisibility(false, finishT);
|
||||
logExit(EXIT_REASON_UNKNOWN);
|
||||
}
|
||||
};
|
||||
// Dismiss the split screen if it's not returning to split.
|
||||
prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, finishWct);
|
||||
setSplitsVisible(false);
|
||||
setDividerVisibility(false, finishT);
|
||||
logExit(EXIT_REASON_UNKNOWN);
|
||||
}
|
||||
};
|
||||
|
||||
protected StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
|
||||
ShellTaskOrganizer taskOrganizer, DisplayController displayController,
|
||||
@@ -389,15 +392,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
prepareEnterSplitScreen(wct);
|
||||
mSplitTransitions.startEnterTransition(TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct,
|
||||
null, this, new SplitScreenTransitions.TransitionCallback() {
|
||||
@Override
|
||||
public void onTransitionFinished(WindowContainerTransaction finishWct,
|
||||
SurfaceControl.Transaction finishT) {
|
||||
if (!evictWct.isEmpty()) {
|
||||
finishWct.merge(evictWct, true);
|
||||
}
|
||||
null, this, null /* consumedCallback */, (finishWct, finishT) -> {
|
||||
if (!evictWct.isEmpty()) {
|
||||
finishWct.merge(evictWct, true);
|
||||
}
|
||||
});
|
||||
} /* finishedCallback */);
|
||||
} else {
|
||||
if (!evictWct.isEmpty()) {
|
||||
wct.merge(evictWct, true /* transfer */);
|
||||
@@ -434,28 +433,25 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, null /* wct */);
|
||||
wct.sendPendingIntent(intent, fillInIntent, options);
|
||||
|
||||
// If split screen is not activated, we're expecting to open a pair of apps to split.
|
||||
final int transitType = mMainStage.isActive()
|
||||
? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN;
|
||||
prepareEnterSplitScreen(wct, null /* taskInfo */, position);
|
||||
|
||||
mSplitTransitions.startEnterTransition(TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE, wct, null, this,
|
||||
new SplitScreenTransitions.TransitionCallback() {
|
||||
@Override
|
||||
public void onTransitionConsumed(boolean aborted) {
|
||||
// Switch the split position if launching as MULTIPLE_TASK failed.
|
||||
if (aborted
|
||||
&& (fillInIntent.getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
|
||||
setSideStagePositionAnimated(
|
||||
SplitLayout.reversePosition(mSideStagePosition));
|
||||
}
|
||||
mSplitTransitions.startEnterTransition(transitType, wct, null, this,
|
||||
aborted -> {
|
||||
// Switch the split position if launching as MULTIPLE_TASK failed.
|
||||
if (aborted && (fillInIntent.getFlags() & FLAG_ACTIVITY_MULTIPLE_TASK) != 0) {
|
||||
setSideStagePositionAnimated(
|
||||
SplitLayout.reversePosition(mSideStagePosition));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionFinished(WindowContainerTransaction finishWct,
|
||||
SurfaceControl.Transaction finishT) {
|
||||
if (!evictWct.isEmpty()) {
|
||||
finishWct.merge(evictWct, true);
|
||||
}
|
||||
} /* consumedCallback */,
|
||||
(finishWct, finishT) -> {
|
||||
if (!evictWct.isEmpty()) {
|
||||
finishWct.merge(evictWct, true);
|
||||
}
|
||||
});
|
||||
} /* finishedCallback */);
|
||||
}
|
||||
|
||||
/** Launches an activity into split by legacy transition. */
|
||||
@@ -564,9 +560,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
/**
|
||||
* Starts with the second task to a split pair in one transition.
|
||||
*
|
||||
* @param wct transaction to start the first task
|
||||
* @param wct transaction to start the first task
|
||||
* @param instanceId if {@code null}, will not log. Otherwise it will be used in
|
||||
* {@link SplitscreenEventLogger#logEnter(float, int, int, int, int, boolean)}
|
||||
* {@link SplitscreenEventLogger#logEnter(float, int, int, int, int, boolean)}
|
||||
*/
|
||||
private void startWithTask(WindowContainerTransaction wct, int mainTaskId,
|
||||
@Nullable Bundle mainOptions, float splitRatio,
|
||||
@@ -592,7 +588,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
wct.startTask(mainTaskId, mainOptions);
|
||||
|
||||
mSplitTransitions.startEnterTransition(
|
||||
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this, null);
|
||||
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, wct, remoteTransition, this, null, null);
|
||||
setEnterInstanceId(instanceId);
|
||||
}
|
||||
|
||||
@@ -639,7 +635,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
|
||||
/**
|
||||
* @param wct transaction to start the first task
|
||||
* @param wct transaction to start the first task
|
||||
* @param instanceId if {@code null}, will not log. Otherwise it will be used in
|
||||
* {@link SplitscreenEventLogger#logEnter(float, int, int, int, int, boolean)}
|
||||
*/
|
||||
@@ -1082,15 +1078,15 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
switch (exitReason) {
|
||||
// One of the apps doesn't support MW
|
||||
case EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW:
|
||||
// User has explicitly dragged the divider to dismiss split
|
||||
// User has explicitly dragged the divider to dismiss split
|
||||
case EXIT_REASON_DRAG_DIVIDER:
|
||||
// Either of the split apps have finished
|
||||
// Either of the split apps have finished
|
||||
case EXIT_REASON_APP_FINISHED:
|
||||
// One of the children enters PiP
|
||||
// One of the children enters PiP
|
||||
case EXIT_REASON_CHILD_TASK_ENTER_PIP:
|
||||
// One of the apps occludes lock screen.
|
||||
// One of the apps occludes lock screen.
|
||||
case EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP:
|
||||
// User has unlocked the device after folded
|
||||
// User has unlocked the device after folded
|
||||
case EXIT_REASON_DEVICE_FOLDED:
|
||||
return true;
|
||||
default:
|
||||
@@ -1839,7 +1835,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|| activityType == ACTIVITY_TYPE_RECENTS) {
|
||||
// Enter overview panel, so start recent transition.
|
||||
mSplitTransitions.setRecentTransition(transition, request.getRemoteTransition(),
|
||||
mRecentTransitionCallback);
|
||||
mRecentTransitionFinishedCallback);
|
||||
} else if (mSplitTransitions.mPendingRecent == null) {
|
||||
// If split-task is not controlled by recents animation
|
||||
// and occluded by the other fullscreen task, dismiss both.
|
||||
@@ -1853,8 +1849,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
// One task is appearing into split, prepare to enter split screen.
|
||||
out = new WindowContainerTransaction();
|
||||
prepareEnterSplitScreen(out);
|
||||
mSplitTransitions.setEnterTransition(
|
||||
transition, request.getRemoteTransition(), null /* callback */);
|
||||
mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
|
||||
null /* consumedCallback */, null /* finishedCallback */);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
@@ -1873,7 +1869,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
final @WindowManager.TransitionType int type = request.getType();
|
||||
if (isSplitActive() && !isOpeningType(type)
|
||||
&& (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0)) {
|
||||
&& (mMainStage.getChildCount() == 0 || mSideStage.getChildCount() == 0)) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " One of the splits became "
|
||||
+ "empty during a mixed transition (one not handled by split),"
|
||||
+ " so make sure split-screen state is cleaned-up. "
|
||||
@@ -2031,17 +2027,21 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/250853925): fallback logic. Probably start a new transition to exit split before
|
||||
// applying anything here. Ideally consolidate with transition-merging.
|
||||
if (info.getType() == TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE) {
|
||||
if (mainChild == null && sideChild == null) {
|
||||
throw new IllegalStateException("Launched a task in split, but didn't receive any"
|
||||
+ " task in transition.");
|
||||
Log.w(TAG, "Launched a task in split, but didn't receive any task in transition.");
|
||||
mSplitTransitions.mPendingEnter.cancel(null /* finishedCb */);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (mainChild == null || sideChild == null) {
|
||||
throw new IllegalStateException("Launched 2 tasks in split, but didn't receive"
|
||||
Log.w(TAG, "Launched 2 tasks in split, but didn't receive"
|
||||
+ " 2 tasks in transition. Possibly one of them failed to launch");
|
||||
final int dismissTop = mainChild != null ? STAGE_TYPE_MAIN :
|
||||
(sideChild != null ? STAGE_TYPE_SIDE : STAGE_TYPE_UNDEFINED);
|
||||
mSplitTransitions.mPendingEnter.cancel(
|
||||
(cancelWct, cancelT) -> prepareExitSplitScreen(dismissTop, cancelWct));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2305,7 +2305,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
final int stageType = isMainStage ? STAGE_TYPE_MAIN : STAGE_TYPE_SIDE;
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
prepareExitSplitScreen(stageType, wct);
|
||||
mSplitTransitions.startDismissTransition(wct,StageCoordinator.this, stageType,
|
||||
mSplitTransitions.startDismissTransition(wct, StageCoordinator.this, stageType,
|
||||
EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW);
|
||||
mSplitUnsupportedToast.show();
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
||||
|
||||
IBinder transition = mSplitScreenTransitions.startEnterTransition(
|
||||
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, new WindowContainerTransaction(),
|
||||
new RemoteTransition(testRemote), mStageCoordinator, null);
|
||||
new RemoteTransition(testRemote), mStageCoordinator, null, null);
|
||||
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
|
||||
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
|
||||
boolean accepted = mStageCoordinator.startAnimation(transition, info,
|
||||
@@ -421,7 +421,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
||||
TransitionInfo enterInfo = createEnterPairInfo();
|
||||
IBinder enterTransit = mSplitScreenTransitions.startEnterTransition(
|
||||
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, new WindowContainerTransaction(),
|
||||
new RemoteTransition(new TestRemoteTransition()), mStageCoordinator, null);
|
||||
new RemoteTransition(new TestRemoteTransition()), mStageCoordinator, null, null);
|
||||
mMainStage.onTaskAppeared(mMainChild, createMockSurface());
|
||||
mSideStage.onTaskAppeared(mSideChild, createMockSurface());
|
||||
mStageCoordinator.startAnimation(enterTransit, enterInfo,
|
||||
|
||||
Reference in New Issue
Block a user