Merge "Fix transition when leaving a split pair by home key" into udc-dev
This commit is contained in:
@@ -66,13 +66,11 @@ class SplitScreenTransitions {
|
||||
private final Transitions mTransitions;
|
||||
private final Runnable mOnFinish;
|
||||
|
||||
DismissTransition mPendingDismiss = null;
|
||||
DismissSession mPendingDismiss = null;
|
||||
TransitSession mPendingEnter = null;
|
||||
TransitSession mPendingRecent = null;
|
||||
TransitSession mPendingResize = null;
|
||||
|
||||
private IBinder mAnimatingTransition = null;
|
||||
OneShotRemoteHandler mPendingRemoteHandler = null;
|
||||
private OneShotRemoteHandler mActiveRemoteHandler = null;
|
||||
|
||||
private final Transitions.TransitionFinishCallback mRemoteFinishCB = this::onFinish;
|
||||
@@ -101,27 +99,30 @@ class SplitScreenTransitions {
|
||||
mFinishCallback = finishCallback;
|
||||
mAnimatingTransition = transition;
|
||||
mFinishTransaction = finishTransaction;
|
||||
if (mPendingRemoteHandler != null) {
|
||||
mPendingRemoteHandler.startAnimation(transition, info, startTransaction,
|
||||
finishTransaction, mRemoteFinishCB);
|
||||
mActiveRemoteHandler = mPendingRemoteHandler;
|
||||
mPendingRemoteHandler = null;
|
||||
return;
|
||||
|
||||
final TransitSession pendingTransition = getPendingTransition(transition);
|
||||
if (pendingTransition != null) {
|
||||
if (pendingTransition.mCanceled) {
|
||||
// The pending transition was canceled, so skip playing animation.
|
||||
startTransaction.apply();
|
||||
onFinish(null /* wct */, null /* wctCB */);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pendingTransition.mRemoteHandler != null) {
|
||||
pendingTransition.mRemoteHandler.startAnimation(transition, info, startTransaction,
|
||||
finishTransaction, mRemoteFinishCB);
|
||||
mActiveRemoteHandler = pendingTransition.mRemoteHandler;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
playInternalAnimation(transition, info, startTransaction, mainRoot, sideRoot, topRoot);
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -260,10 +261,6 @@ class SplitScreenTransitions {
|
||||
return mPendingEnter != null && mPendingEnter.mTransition == transition;
|
||||
}
|
||||
|
||||
boolean isPendingRecent(IBinder transition) {
|
||||
return mPendingRecent != null && mPendingRecent.mTransition == transition;
|
||||
}
|
||||
|
||||
boolean isPendingDismiss(IBinder transition) {
|
||||
return mPendingDismiss != null && mPendingDismiss.mTransition == transition;
|
||||
}
|
||||
@@ -276,8 +273,6 @@ class SplitScreenTransitions {
|
||||
private TransitSession getPendingTransition(IBinder transition) {
|
||||
if (isPendingEnter(transition)) {
|
||||
return mPendingEnter;
|
||||
} else if (isPendingRecent(transition)) {
|
||||
return mPendingRecent;
|
||||
} else if (isPendingDismiss(transition)) {
|
||||
return mPendingDismiss;
|
||||
} else if (isPendingResize(transition)) {
|
||||
@@ -311,14 +306,8 @@ class SplitScreenTransitions {
|
||||
@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)
|
||||
mPendingRemoteHandler = new OneShotRemoteHandler(
|
||||
mTransitions.getMainExecutor(), remoteTransition);
|
||||
mPendingRemoteHandler.setTransition(transition);
|
||||
}
|
||||
mPendingEnter = new TransitSession(
|
||||
transition, consumedCallback, finishedCallback, remoteTransition);
|
||||
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
|
||||
+ " deduced Enter split screen");
|
||||
@@ -344,7 +333,7 @@ class SplitScreenTransitions {
|
||||
/** Sets a transition to dismiss split. */
|
||||
void setDismissTransition(@NonNull IBinder transition, @SplitScreen.StageType int dismissTop,
|
||||
@SplitScreenController.ExitReason int reason) {
|
||||
mPendingDismiss = new DismissTransition(transition, reason, dismissTop);
|
||||
mPendingDismiss = new DismissSession(transition, reason, dismissTop);
|
||||
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
|
||||
+ " deduced Dismiss due to %s. toTop=%s",
|
||||
@@ -372,32 +361,10 @@ class SplitScreenTransitions {
|
||||
+ " deduced Resize split screen");
|
||||
}
|
||||
|
||||
void setRecentTransition(@NonNull IBinder transition,
|
||||
@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)
|
||||
mPendingRemoteHandler = new OneShotRemoteHandler(
|
||||
mTransitions.getMainExecutor(), remoteTransition);
|
||||
mPendingRemoteHandler.setTransition(transition);
|
||||
}
|
||||
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
|
||||
+ " deduced Enter recent panel");
|
||||
}
|
||||
|
||||
void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t,
|
||||
IBinder mergeTarget, Transitions.TransitionFinishCallback finishCallback) {
|
||||
if (mergeTarget != mAnimatingTransition) return;
|
||||
|
||||
if (isPendingEnter(transition) && isPendingRecent(mergeTarget)) {
|
||||
// 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) {
|
||||
mActiveRemoteHandler.mergeAnimation(transition, info, t, mergeTarget, finishCallback);
|
||||
} else {
|
||||
@@ -425,19 +392,13 @@ class SplitScreenTransitions {
|
||||
// An entering transition got merged, appends the rest operations to finish entering
|
||||
// split screen.
|
||||
mStageCoordinator.finishEnterSplitScreen(finishT);
|
||||
mPendingRemoteHandler = null;
|
||||
}
|
||||
|
||||
mPendingEnter.onConsumed(aborted);
|
||||
mPendingEnter = null;
|
||||
mPendingRemoteHandler = null;
|
||||
} else if (isPendingDismiss(transition)) {
|
||||
mPendingDismiss.onConsumed(aborted);
|
||||
mPendingDismiss = null;
|
||||
} else if (isPendingRecent(transition)) {
|
||||
mPendingRecent.onConsumed(aborted);
|
||||
mPendingRecent = null;
|
||||
mPendingRemoteHandler = null;
|
||||
} else if (isPendingResize(transition)) {
|
||||
mPendingResize.onConsumed(aborted);
|
||||
mPendingResize = null;
|
||||
@@ -451,9 +412,6 @@ class SplitScreenTransitions {
|
||||
if (isPendingEnter(mAnimatingTransition)) {
|
||||
mPendingEnter.onFinished(wct, mFinishTransaction);
|
||||
mPendingEnter = null;
|
||||
} else if (isPendingRecent(mAnimatingTransition)) {
|
||||
mPendingRecent.onFinished(wct, mFinishTransaction);
|
||||
mPendingRecent = null;
|
||||
} else if (isPendingDismiss(mAnimatingTransition)) {
|
||||
mPendingDismiss.onFinished(wct, mFinishTransaction);
|
||||
mPendingDismiss = null;
|
||||
@@ -462,7 +420,6 @@ class SplitScreenTransitions {
|
||||
mPendingResize = null;
|
||||
}
|
||||
|
||||
mPendingRemoteHandler = null;
|
||||
mActiveRemoteHandler = null;
|
||||
mAnimatingTransition = null;
|
||||
|
||||
@@ -568,10 +525,11 @@ class SplitScreenTransitions {
|
||||
}
|
||||
|
||||
/** Session for a transition and its clean-up callback. */
|
||||
static class TransitSession {
|
||||
class TransitSession {
|
||||
final IBinder mTransition;
|
||||
TransitionConsumedCallback mConsumedCallback;
|
||||
TransitionFinishedCallback mFinishedCallback;
|
||||
OneShotRemoteHandler mRemoteHandler;
|
||||
|
||||
/** Whether the transition was canceled. */
|
||||
boolean mCanceled;
|
||||
@@ -579,10 +537,24 @@ class SplitScreenTransitions {
|
||||
TransitSession(IBinder transition,
|
||||
@Nullable TransitionConsumedCallback consumedCallback,
|
||||
@Nullable TransitionFinishedCallback finishedCallback) {
|
||||
this(transition, consumedCallback, finishedCallback, null /* remoteTransition */);
|
||||
}
|
||||
|
||||
TransitSession(IBinder transition,
|
||||
@Nullable TransitionConsumedCallback consumedCallback,
|
||||
@Nullable TransitionFinishedCallback finishedCallback,
|
||||
@Nullable RemoteTransition remoteTransition) {
|
||||
mTransition = transition;
|
||||
mConsumedCallback = consumedCallback;
|
||||
mFinishedCallback = finishedCallback;
|
||||
|
||||
if (remoteTransition != null) {
|
||||
// Wrapping the remote transition for ease-of-use. (OneShot handles all the binder
|
||||
// linking/death stuff)
|
||||
mRemoteHandler = new OneShotRemoteHandler(
|
||||
mTransitions.getMainExecutor(), remoteTransition);
|
||||
mRemoteHandler.setTransition(transition);
|
||||
}
|
||||
}
|
||||
|
||||
/** Sets transition consumed callback. */
|
||||
@@ -621,11 +593,11 @@ class SplitScreenTransitions {
|
||||
}
|
||||
|
||||
/** Bundled information of dismiss transition. */
|
||||
static class DismissTransition extends TransitSession {
|
||||
class DismissSession extends TransitSession {
|
||||
final int mReason;
|
||||
final @SplitScreen.StageType int mDismissTop;
|
||||
|
||||
DismissTransition(IBinder transition, int reason, int dismissTop) {
|
||||
DismissSession(IBinder transition, int reason, int dismissTop) {
|
||||
super(transition, null /* consumedCallback */, null /* finishedCallback */);
|
||||
this.mReason = reason;
|
||||
this.mDismissTop = dismissTop;
|
||||
|
||||
@@ -2226,15 +2226,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
} else if (isOpening && inFullscreen) {
|
||||
final int activityType = triggerTask.getActivityType();
|
||||
if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) {
|
||||
if (request.getRemoteTransition() != null) {
|
||||
// starting recents/home, so don't handle this and let it fall-through to
|
||||
// the remote handler.
|
||||
return null;
|
||||
}
|
||||
// Need to use the old stuff for non-remote animations, otherwise we don't
|
||||
// exit split-screen.
|
||||
mSplitTransitions.setRecentTransition(transition, null /* remote */,
|
||||
this::onRecentsInSplitAnimationFinish);
|
||||
// starting recents/home, so don't handle this and let it fall-through to
|
||||
// the remote handler.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2363,8 +2357,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
if (mSplitTransitions.isPendingEnter(transition)) {
|
||||
shouldAnimate = startPendingEnterAnimation(
|
||||
transition, info, startTransaction, finishTransaction);
|
||||
} else if (mSplitTransitions.isPendingRecent(transition)) {
|
||||
onRecentsInSplitAnimationStart(startTransaction);
|
||||
} else if (mSplitTransitions.isPendingDismiss(transition)) {
|
||||
shouldAnimate = startPendingDismissAnimation(
|
||||
mSplitTransitions.mPendingDismiss, info, startTransaction, finishTransaction);
|
||||
@@ -2589,7 +2581,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
|
||||
private boolean startPendingDismissAnimation(
|
||||
@NonNull SplitScreenTransitions.DismissTransition dismissTransition,
|
||||
@NonNull SplitScreenTransitions.DismissSession dismissTransition,
|
||||
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t,
|
||||
@NonNull SurfaceControl.Transaction finishT) {
|
||||
prepareDismissAnimation(dismissTransition.mDismissTop, dismissTransition.mReason, info,
|
||||
@@ -2626,7 +2618,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
/** Call this when the recents animation during split-screen finishes. */
|
||||
public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct,
|
||||
SurfaceControl.Transaction finishT) {
|
||||
SurfaceControl.Transaction finishT, TransitionInfo info) {
|
||||
// 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) {
|
||||
@@ -2643,8 +2635,14 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/275664132): Remove dismissing split screen here to fit in back-to-split support.
|
||||
// Dismiss the split screen if it's not returning to split.
|
||||
prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, finishWct);
|
||||
for (TransitionInfo.Change change : info.getChanges()) {
|
||||
if (change.getTaskInfo() != null && TransitionUtil.isClosingType(change.getMode())) {
|
||||
finishT.setCrop(change.getLeash(), null).hide(change.getLeash());
|
||||
}
|
||||
}
|
||||
setSplitsVisible(false);
|
||||
setDividerVisibility(false, finishT);
|
||||
logExit(EXIT_REASON_UNKNOWN);
|
||||
|
||||
@@ -187,17 +187,18 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
&& isOpeningType(request.getType())
|
||||
&& request.getTriggerTask() != null
|
||||
&& request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
|
||||
&& (request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_HOME
|
||||
|| request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_RECENTS)
|
||||
&& request.getRemoteTransition() != null) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
|
||||
&& 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.");
|
||||
Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler =
|
||||
mPlayer.dispatchRequest(transition, request, this);
|
||||
if (handler == null) {
|
||||
android.util.Log.e(Transitions.TAG, " No handler for remote? This is unexpected"
|
||||
+ ", there should at-least be RemoteHandler.");
|
||||
return null;
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
|
||||
" Lean on the remote transition handler to fetch a proper remote via"
|
||||
+ " TransitionFilter");
|
||||
handler = new Pair<>(
|
||||
mPlayer.getRemoteTransitionHandler(),
|
||||
new WindowContainerTransaction());
|
||||
}
|
||||
final MixedTransition mixed = new MixedTransition(
|
||||
MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
|
||||
@@ -515,7 +516,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
||||
// If pair-to-pair switching, the post-recents clean-up isn't needed.
|
||||
if (mixed.mAnimType != MixedTransition.ANIM_TYPE_PAIR_TO_PAIR) {
|
||||
wct = wct != null ? wct : new WindowContainerTransaction();
|
||||
mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction);
|
||||
mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction, info);
|
||||
}
|
||||
mSplitHandler.onTransitionAnimationComplete();
|
||||
finishCallback.onTransitionFinished(wct, wctCB);
|
||||
|
||||
@@ -324,6 +324,10 @@ public class Transitions implements RemoteCallable<Transitions> {
|
||||
mRemoteTransitionHandler.removeFiltered(remoteTransition);
|
||||
}
|
||||
|
||||
RemoteTransitionHandler getRemoteTransitionHandler() {
|
||||
return mRemoteTransitionHandler;
|
||||
}
|
||||
|
||||
/** Registers an observer on the lifecycle of transitions. */
|
||||
public void registerObserver(@NonNull TransitionObserver observer) {
|
||||
mObservers.add(observer);
|
||||
|
||||
@@ -71,7 +71,7 @@ class DismissSplitScreenByGoHome(flicker: FlickerTest) : SplitScreenBase(flicker
|
||||
// TODO(b/245472831): Move back to presubmit after shell transitions landing.
|
||||
@FlakyTest(bugId = 245472831)
|
||||
@Test
|
||||
fun secondaryAppLayerBecomesInvisible() = flicker.layerBecomesInvisible(primaryApp)
|
||||
fun secondaryAppLayerBecomesInvisible() = flicker.layerBecomesInvisible(secondaryApp)
|
||||
|
||||
// TODO(b/245472831): Move back to presubmit after shell transitions landing.
|
||||
@FlakyTest(bugId = 245472831)
|
||||
|
||||
@@ -278,7 +278,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
||||
// Make sure it cleans-up if recents doesn't restore
|
||||
WindowContainerTransaction commitWCT = new WindowContainerTransaction();
|
||||
mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
|
||||
mock(SurfaceControl.Transaction.class));
|
||||
mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
|
||||
assertFalse(mStageCoordinator.isSplitScreenVisible());
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
||||
mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class));
|
||||
mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class));
|
||||
mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
|
||||
mock(SurfaceControl.Transaction.class));
|
||||
mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
|
||||
assertTrue(mStageCoordinator.isSplitScreenVisible());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user