Merge "Implement resize enter animation" into udc-dev am: 460be670c7

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22881925

Change-Id: I0b469ff94c4d56cef5988ce834bc6992a983dfaa
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Tony Huang
2023-05-15 05:21:32 +00:00
committed by Automerger Merge Worker
6 changed files with 107 additions and 128 deletions

View File

@@ -22,6 +22,8 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMA
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static com.android.wm.shell.common.split.SplitScreenConstants.FADE_DURATION;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
@@ -60,7 +62,6 @@ public class SplitDecorManager extends WindowlessWindowManager {
private static final String TAG = SplitDecorManager.class.getSimpleName(); private static final String TAG = SplitDecorManager.class.getSimpleName();
private static final String RESIZING_BACKGROUND_SURFACE_NAME = "ResizingBackground"; private static final String RESIZING_BACKGROUND_SURFACE_NAME = "ResizingBackground";
private static final String GAP_BACKGROUND_SURFACE_NAME = "GapBackground"; private static final String GAP_BACKGROUND_SURFACE_NAME = "GapBackground";
private static final long FADE_DURATION = 133;
private final IconProvider mIconProvider; private final IconProvider mIconProvider;
private final SurfaceSession mSurfaceSession; private final SurfaceSession mSurfaceSession;
@@ -263,6 +264,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
final SurfaceControl.Transaction animT = new SurfaceControl.Transaction(); final SurfaceControl.Transaction animT = new SurfaceControl.Transaction();
mScreenshotAnimator = ValueAnimator.ofFloat(1, 0); mScreenshotAnimator = ValueAnimator.ofFloat(1, 0);
mScreenshotAnimator.setDuration(FADE_DURATION);
mScreenshotAnimator.addUpdateListener(valueAnimator -> { mScreenshotAnimator.addUpdateListener(valueAnimator -> {
final float progress = (float) valueAnimator.getAnimatedValue(); final float progress = (float) valueAnimator.getAnimatedValue();
animT.setAlpha(mScreenshot, progress); animT.setAlpha(mScreenshot, progress);

View File

@@ -43,6 +43,11 @@ public class SplitScreenConstants {
*/ */
public static final int SPLIT_POSITION_BOTTOM_OR_RIGHT = 1; public static final int SPLIT_POSITION_BOTTOM_OR_RIGHT = 1;
/**
* Duration used for every split fade-in or fade-out.
*/
public static final int FADE_DURATION = 133;
@IntDef(prefix = {"SPLIT_POSITION_"}, value = { @IntDef(prefix = {"SPLIT_POSITION_"}, value = {
SPLIT_POSITION_UNDEFINED, SPLIT_POSITION_UNDEFINED,
SPLIT_POSITION_TOP_OR_LEFT, SPLIT_POSITION_TOP_OR_LEFT,

View File

@@ -22,6 +22,7 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.view.WindowManager.TRANSIT_TO_FRONT; import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static com.android.wm.shell.common.split.SplitScreenConstants.FADE_DURATION;
import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR; import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString; import static com.android.wm.shell.splitscreen.SplitScreen.stageTypeToString;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER; import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
@@ -34,7 +35,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.graphics.Rect;
import android.os.IBinder; import android.os.IBinder;
import android.view.SurfaceControl; import android.view.SurfaceControl;
import android.view.WindowManager; import android.view.WindowManager;
@@ -63,7 +63,7 @@ class SplitScreenTransitions {
private final Runnable mOnFinish; private final Runnable mOnFinish;
DismissSession mPendingDismiss = null; DismissSession mPendingDismiss = null;
TransitSession mPendingEnter = null; EnterSession mPendingEnter = null;
TransitSession mPendingResize = null; TransitSession mPendingResize = null;
private IBinder mAnimatingTransition = null; private IBinder mAnimatingTransition = null;
@@ -120,6 +120,7 @@ class SplitScreenTransitions {
@NonNull SurfaceControl.Transaction t, @NonNull WindowContainerToken mainRoot, @NonNull SurfaceControl.Transaction t, @NonNull WindowContainerToken mainRoot,
@NonNull WindowContainerToken sideRoot, @NonNull WindowContainerToken topRoot) { @NonNull WindowContainerToken sideRoot, @NonNull WindowContainerToken topRoot) {
// Play some place-holder fade animations // Play some place-holder fade animations
final boolean isEnter = isPendingEnter(transition);
for (int i = info.getChanges().size() - 1; i >= 0; --i) { for (int i = info.getChanges().size() - 1; i >= 0; --i) {
final TransitionInfo.Change change = info.getChanges().get(i); final TransitionInfo.Change change = info.getChanges().get(i);
final SurfaceControl leash = change.getLeash(); final SurfaceControl leash = change.getLeash();
@@ -142,17 +143,23 @@ class SplitScreenTransitions {
change.getEndRelOffset().x, change.getEndRelOffset().y); change.getEndRelOffset().x, change.getEndRelOffset().y);
} }
} }
boolean isRootOrSplitSideRoot = change.getParent() == null
|| topRoot.equals(change.getParent());
boolean isDivider = change.getFlags() == FLAG_IS_DIVIDER_BAR;
// For enter or exit, we only want to animate side roots and the divider but not the
// top-root.
if (!isRootOrSplitSideRoot || topRoot.equals(change.getContainer()) || isDivider) {
continue;
}
if (isPendingEnter(transition) && (mainRoot.equals(change.getContainer()) final boolean isTopRoot = topRoot.equals(change.getContainer());
|| sideRoot.equals(change.getContainer()))) { final boolean isMainRoot = mainRoot.equals(change.getContainer());
final boolean isSideRoot = sideRoot.equals(change.getContainer());
final boolean isDivider = change.getFlags() == FLAG_IS_DIVIDER_BAR;
final boolean isMainChild = mainRoot.equals(change.getParent());
final boolean isSideChild = sideRoot.equals(change.getParent());
if (isEnter && (isMainChild || isSideChild)) {
// Reset child tasks bounds on finish.
mFinishTransaction.setPosition(leash,
change.getEndRelOffset().x, change.getEndRelOffset().y);
mFinishTransaction.setCrop(leash, null);
} else if (isEnter && isTopRoot) {
// Ensure top root is visible at start.
t.setAlpha(leash, 1.f);
t.show(leash);
} else if (isEnter && isMainRoot || isSideRoot) {
t.setPosition(leash, change.getEndAbsBounds().left, change.getEndAbsBounds().top); t.setPosition(leash, change.getEndAbsBounds().left, change.getEndAbsBounds().top);
t.setWindowCrop(leash, change.getEndAbsBounds().width(), t.setWindowCrop(leash, change.getEndAbsBounds().width(),
change.getEndAbsBounds().height()); change.getEndAbsBounds().height());
@@ -161,10 +168,24 @@ class SplitScreenTransitions {
t.setLayer(leash, Integer.MAX_VALUE); t.setLayer(leash, Integer.MAX_VALUE);
t.show(leash); t.show(leash);
} }
// These container changes we don't want to animate them.
// We should only animate stage root, divider and child tasks are not under stage root.
if (isTopRoot || isMainChild || isSideChild || change.getTaskInfo() == null) {
continue;
}
if (isEnter && mPendingEnter.mResizeAnim) {
// We will run animation in next transition so skip anim here
continue;
} else if (isEnter && isMainRoot) {
// Main stage already on top so skip fade in animation to reduce flicker.
continue;
}
boolean isOpening = TransitionUtil.isOpeningType(info.getType()); boolean isOpening = TransitionUtil.isOpeningType(info.getType());
if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) { if (isOpening && (mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
// fade in // fade in
startExampleAnimation(leash, true /* show */); startFadeAnimation(leash, true /* show */);
} else if (!isOpening && (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK)) { } else if (!isOpening && (mode == TRANSIT_CLOSE || mode == TRANSIT_TO_BACK)) {
// fade out // fade out
if (info.getType() == TRANSIT_SPLIT_DISMISS_SNAP) { if (info.getType() == TRANSIT_SPLIT_DISMISS_SNAP) {
@@ -173,7 +194,7 @@ class SplitScreenTransitions {
// and don't animate it so it doesn't pop-in when reparented. // and don't animate it so it doesn't pop-in when reparented.
t.setAlpha(leash, 0.f); t.setAlpha(leash, 0.f);
} else { } else {
startExampleAnimation(leash, false /* show */); startFadeAnimation(leash, false /* show */);
} }
} }
} }
@@ -267,7 +288,7 @@ class SplitScreenTransitions {
Transitions.TransitionHandler handler, Transitions.TransitionHandler handler,
@Nullable TransitionConsumedCallback consumedCallback, @Nullable TransitionConsumedCallback consumedCallback,
@Nullable TransitionFinishedCallback finishedCallback, @Nullable TransitionFinishedCallback finishedCallback,
int extraTransitType) { int extraTransitType, boolean resizeAnim) {
if (mPendingEnter != null) { if (mPendingEnter != null) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition " ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
+ " skip to start enter split transition since it already exist. "); + " skip to start enter split transition since it already exist. ");
@@ -275,7 +296,7 @@ class SplitScreenTransitions {
} }
final IBinder transition = mTransitions.startTransition(transitType, wct, handler); final IBinder transition = mTransitions.startTransition(transitType, wct, handler);
setEnterTransition(transition, remoteTransition, consumedCallback, finishedCallback, setEnterTransition(transition, remoteTransition, consumedCallback, finishedCallback,
extraTransitType); extraTransitType, resizeAnim);
return transition; return transition;
} }
@@ -284,9 +305,10 @@ class SplitScreenTransitions {
@Nullable RemoteTransition remoteTransition, @Nullable RemoteTransition remoteTransition,
@Nullable TransitionConsumedCallback consumedCallback, @Nullable TransitionConsumedCallback consumedCallback,
@Nullable TransitionFinishedCallback finishedCallback, @Nullable TransitionFinishedCallback finishedCallback,
int extraTransitType) { int extraTransitType, boolean resizeAnim) {
mPendingEnter = new TransitSession( mPendingEnter = new EnterSession(
transition, consumedCallback, finishedCallback, remoteTransition, extraTransitType); transition, consumedCallback, finishedCallback, remoteTransition, extraTransitType,
resizeAnim);
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition " ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " splitTransition "
+ " deduced Enter split screen"); + " deduced Enter split screen");
@@ -409,78 +431,27 @@ class SplitScreenTransitions {
} }
} }
// TODO(shell-transitions): real animations private void startFadeAnimation(@NonNull SurfaceControl leash, boolean show) {
private void startExampleAnimation(@NonNull SurfaceControl leash, boolean show) {
final float end = show ? 1.f : 0.f; final float end = show ? 1.f : 0.f;
final float start = 1.f - end; final float start = 1.f - end;
final SurfaceControl.Transaction transaction = mTransactionPool.acquire(); final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
final ValueAnimator va = ValueAnimator.ofFloat(start, end); final ValueAnimator va = ValueAnimator.ofFloat(start, end);
va.setDuration(500); va.setDuration(FADE_DURATION);
va.addUpdateListener(animation -> { va.addUpdateListener(animation -> {
float fraction = animation.getAnimatedFraction(); float fraction = animation.getAnimatedFraction();
transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction); transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);
transaction.apply(); transaction.apply();
}); });
final Runnable finisher = () -> {
transaction.setAlpha(leash, end);
transaction.apply();
mTransactionPool.release(transaction);
mTransitions.getMainExecutor().execute(() -> {
mAnimations.remove(va);
onFinish(null /* wct */, null /* wctCB */);
});
};
va.addListener(new AnimatorListenerAdapter() { va.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
finisher.run(); transaction.setAlpha(leash, end);
} transaction.apply();
mTransactionPool.release(transaction);
@Override mTransitions.getMainExecutor().execute(() -> {
public void onAnimationCancel(Animator animation) { mAnimations.remove(va);
finisher.run(); onFinish(null /* wct */, null /* wctCB */);
} });
});
mAnimations.add(va);
mTransitions.getAnimExecutor().execute(va::start);
}
// TODO(shell-transitions): real animations
private void startExampleResizeAnimation(@NonNull SurfaceControl leash,
@NonNull Rect startBounds, @NonNull Rect endBounds) {
final SurfaceControl.Transaction transaction = mTransactionPool.acquire();
final ValueAnimator va = ValueAnimator.ofFloat(0.f, 1.f);
va.setDuration(500);
va.addUpdateListener(animation -> {
float fraction = animation.getAnimatedFraction();
transaction.setWindowCrop(leash,
(int) (startBounds.width() * (1.f - fraction) + endBounds.width() * fraction),
(int) (startBounds.height() * (1.f - fraction)
+ endBounds.height() * fraction));
transaction.setPosition(leash,
startBounds.left * (1.f - fraction) + endBounds.left * fraction,
startBounds.top * (1.f - fraction) + endBounds.top * fraction);
transaction.apply();
});
final Runnable finisher = () -> {
transaction.setWindowCrop(leash, 0, 0);
transaction.setPosition(leash, endBounds.left, endBounds.top);
transaction.apply();
mTransactionPool.release(transaction);
mTransitions.getMainExecutor().execute(() -> {
mAnimations.remove(va);
onFinish(null /* wct */, null /* wctCB */);
});
};
va.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
finisher.run();
}
@Override
public void onAnimationCancel(Animator animation) {
finisher.run();
} }
}); });
mAnimations.add(va); mAnimations.add(va);
@@ -569,6 +540,21 @@ class SplitScreenTransitions {
} }
} }
/** Bundled information of enter transition. */
class EnterSession extends TransitSession {
final boolean mResizeAnim;
EnterSession(IBinder transition,
@Nullable TransitionConsumedCallback consumedCallback,
@Nullable TransitionFinishedCallback finishedCallback,
@Nullable RemoteTransition remoteTransition,
int extraTransitType, boolean resizeAnim) {
super(transition, consumedCallback, finishedCallback, remoteTransition,
extraTransitType);
this.mResizeAnim = resizeAnim;
}
}
/** Bundled information of dismiss transition. */ /** Bundled information of dismiss transition. */
class DismissSession extends TransitSession { class DismissSession extends TransitSession {
final int mReason; final int mReason;

View File

@@ -395,7 +395,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct,
null, this, null /* consumedCallback */, null /* finishedCallback */, null, this, null /* consumedCallback */, null /* finishedCallback */,
isSplitScreenVisible() isSplitScreenVisible()
? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN); ? TRANSIT_SPLIT_SCREEN_OPEN_TO_SIDE : TRANSIT_SPLIT_SCREEN_PAIR_OPEN,
!mIsDropEntering);
} else { } else {
mSyncQueue.queue(wct); mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> { mSyncQueue.runInSync(t -> {
@@ -503,7 +504,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
prepareEnterSplitScreen(wct, null /* taskInfo */, position); prepareEnterSplitScreen(wct, null /* taskInfo */, position);
mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this, mSplitTransitions.startEnterTransition(TRANSIT_TO_FRONT, wct, null, this,
null /* consumedCallback */, null /* finishedCallback */, extraTransitType); null /* consumedCallback */, null /* finishedCallback */, extraTransitType,
!mIsDropEntering);
} }
/** Launches an activity into split by legacy transition. */ /** Launches an activity into split by legacy transition. */
@@ -661,7 +663,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitTransitions.startEnterTransition( mSplitTransitions.startEnterTransition(
TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null, TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
TRANSIT_SPLIT_SCREEN_PAIR_OPEN); TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
setEnterInstanceId(instanceId); setEnterInstanceId(instanceId);
} }
@@ -713,7 +715,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSplitTransitions.startEnterTransition( mSplitTransitions.startEnterTransition(
TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null, TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
TRANSIT_SPLIT_SCREEN_PAIR_OPEN); TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
setEnterInstanceId(instanceId); setEnterInstanceId(instanceId);
} }
@@ -1494,14 +1496,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private void prepareBringSplit(WindowContainerTransaction wct, private void prepareBringSplit(WindowContainerTransaction wct,
@Nullable ActivityManager.RunningTaskInfo taskInfo, @SplitPosition int startPosition) { @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) { if (taskInfo != null) {
wct.startTask(taskInfo.taskId, wct.startTask(taskInfo.taskId,
resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct)); resolveStartStage(STAGE_TYPE_UNDEFINED, startPosition, null, wct));
@@ -1510,13 +1504,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// and evict all tasks current under its. // and evict all tasks current under its.
if (!isSplitScreenVisible()) { if (!isSplitScreenVisible()) {
// Recreate so we need to reset position rather than keep position of background split. // Recreate so we need to reset position rather than keep position of background split.
mSplitLayout.resetDividerPosition(); mMainStage.reparentTopTask(wct);
updateWindowBounds(mSplitLayout, wct); prepareSplitLayout(wct);
final StageTaskListener anotherStage = targetStage == mMainStage
? mSideStage : mMainStage;
anotherStage.reparentTopTask(wct);
wct.reorder(mRootTaskInfo.token, true);
setRootForceTranslucent(false, wct);
} }
} }
@@ -1532,8 +1521,22 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mSideStage.addTask(taskInfo, wct); mSideStage.addTask(taskInfo, wct);
} }
mMainStage.activate(wct, true /* includingTopTask */); mMainStage.activate(wct, true /* includingTopTask */);
mSplitLayout.resetDividerPosition(); prepareSplitLayout(wct);
}
private void prepareSplitLayout(WindowContainerTransaction wct) {
if (mIsDropEntering) {
mSplitLayout.resetDividerPosition();
} else {
mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
}
updateWindowBounds(mSplitLayout, wct); updateWindowBounds(mSplitLayout, wct);
if (!mIsDropEntering) {
// Reset its smallest width dp to avoid is change layout before it actually resized to
// split bounds.
wct.setSmallestScreenWidthDp(mMainStage.mRootTaskInfo.token,
SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
}
wct.reorder(mRootTaskInfo.token, true); wct.reorder(mRootTaskInfo.token, true);
setRootForceTranslucent(false, wct); setRootForceTranslucent(false, wct);
} }
@@ -1548,6 +1551,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */); updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
t.show(mRootTaskLeash); t.show(mRootTaskLeash);
setSplitsVisible(true); setSplitsVisible(true);
mIsDropEntering = false;
updateRecentTasksSplitPair(); updateRecentTasksSplitPair();
if (!mLogger.hasStartedSession()) { if (!mLogger.hasStartedSession()) {
mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(), mLogger.logEnter(mSplitLayout.getDividerPositionAsFraction(),
@@ -1777,18 +1781,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Handle entering split screen while there is a split pair running in the background. // Handle entering split screen while there is a split pair running in the background.
if (stageListener == mSideStageListener && !isSplitScreenVisible() && isSplitActive() if (stageListener == mSideStageListener && !isSplitScreenVisible() && isSplitActive()
&& mSplitRequest == null) { && mSplitRequest == null) {
if (mIsDropEntering) {
mSplitLayout.resetDividerPosition();
} else {
mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
}
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
mMainStage.reparentTopTask(wct); prepareEnterSplitScreen(wct);
mMainStage.evictAllChildren(wct); mMainStage.evictAllChildren(wct);
mSideStage.evictOtherChildren(wct, taskId); mSideStage.evictOtherChildren(wct, taskId);
updateWindowBounds(mSplitLayout, wct);
wct.reorder(mRootTaskInfo.token, true);
setRootForceTranslucent(false, wct);
mSyncQueue.queue(wct); mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> { mSyncQueue.runInSync(t -> {
@@ -1983,20 +1979,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
exitSplitScreen(null /* childrenToTop */, EXIT_REASON_APP_FINISHED); exitSplitScreen(null /* childrenToTop */, EXIT_REASON_APP_FINISHED);
} }
} else if (isSideStage && hasChildren && !mMainStage.isActive()) { } else if (isSideStage && hasChildren && !mMainStage.isActive()) {
mSplitLayout.init();
final WindowContainerTransaction wct = new WindowContainerTransaction(); final WindowContainerTransaction wct = new WindowContainerTransaction();
if (mIsDropEntering) { prepareEnterSplitScreen(wct);
prepareEnterSplitScreen(wct);
} else {
// TODO (b/238697912) : Add the validation to prevent entering non-recovered status
onSplitScreenEnter();
mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
mMainStage.activate(wct, true /* includingTopTask */);
updateWindowBounds(mSplitLayout, wct);
wct.reorder(mRootTaskInfo.token, true);
setRootForceTranslucent(false, wct);
}
mSyncQueue.queue(wct); mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> { mSyncQueue.runInSync(t -> {
@@ -2353,7 +2337,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
prepareEnterSplitScreen(out); prepareEnterSplitScreen(out);
mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(), mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
null /* consumedCallback */, null /* finishedCallback */, null /* consumedCallback */, null /* finishedCallback */,
0 /* extraTransitType */); 0 /* extraTransitType */, !mIsDropEntering);
} }
} }
return out; return out;
@@ -2596,7 +2580,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
} }
private boolean startPendingEnterAnimation( private boolean startPendingEnterAnimation(
@NonNull SplitScreenTransitions.TransitSession enterTransition, @NonNull SplitScreenTransitions.EnterSession enterTransition,
@NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t,
@NonNull SurfaceControl.Transaction finishT) { @NonNull SurfaceControl.Transaction finishT) {
// First, verify that we actually have opened apps in both splits. // First, verify that we actually have opened apps in both splits.
@@ -2654,7 +2638,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
+ " to have been called with " + sideChild.getTaskInfo().taskId + " to have been called with " + sideChild.getTaskInfo().taskId
+ " before startAnimation()."); + " before startAnimation().");
} }
final TransitionInfo.Change finalMainChild = mainChild; final TransitionInfo.Change finalMainChild = mainChild;
final TransitionInfo.Change finalSideChild = sideChild; final TransitionInfo.Change finalSideChild = sideChild;
enterTransition.setFinishedCallback((callbackWct, callbackT) -> { enterTransition.setFinishedCallback((callbackWct, callbackT) -> {
@@ -2664,6 +2647,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
if (finalSideChild != null) { if (finalSideChild != null) {
mSideStage.evictOtherChildren(callbackWct, finalSideChild.getTaskInfo().taskId); mSideStage.evictOtherChildren(callbackWct, finalSideChild.getTaskInfo().taskId);
} }
if (enterTransition.mResizeAnim) {
mShowDecorImmediately = true;
mSplitLayout.flingDividerToCenter();
}
}); });
finishEnterSplitScreen(finishT); finishEnterSplitScreen(finishT);

View File

@@ -182,7 +182,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder transition = mSplitScreenTransitions.startEnterTransition( IBinder transition = mSplitScreenTransitions.startEnterTransition(
TRANSIT_OPEN, new WindowContainerTransaction(), TRANSIT_OPEN, new WindowContainerTransaction(),
new RemoteTransition(testRemote, "Test"), mStageCoordinator, null, null, new RemoteTransition(testRemote, "Test"), mStageCoordinator, null, null,
TRANSIT_SPLIT_SCREEN_PAIR_OPEN); TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
mMainStage.onTaskAppeared(mMainChild, createMockSurface()); mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface()); mSideStage.onTaskAppeared(mSideChild, createMockSurface());
boolean accepted = mStageCoordinator.startAnimation(transition, info, boolean accepted = mStageCoordinator.startAnimation(transition, info,
@@ -408,7 +408,7 @@ public class SplitTransitionTests extends ShellTestCase {
IBinder enterTransit = mSplitScreenTransitions.startEnterTransition( IBinder enterTransit = mSplitScreenTransitions.startEnterTransition(
TRANSIT_OPEN, new WindowContainerTransaction(), TRANSIT_OPEN, new WindowContainerTransaction(),
new RemoteTransition(new TestRemoteTransition(), "Test"), new RemoteTransition(new TestRemoteTransition(), "Test"),
mStageCoordinator, null, null, TRANSIT_SPLIT_SCREEN_PAIR_OPEN); mStageCoordinator, null, null, TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
mMainStage.onTaskAppeared(mMainChild, createMockSurface()); mMainStage.onTaskAppeared(mMainChild, createMockSurface());
mSideStage.onTaskAppeared(mSideChild, createMockSurface()); mSideStage.onTaskAppeared(mSideChild, createMockSurface());
mStageCoordinator.startAnimation(enterTransit, enterInfo, mStageCoordinator.startAnimation(enterTransit, enterInfo,

View File

@@ -158,7 +158,6 @@ public class StageCoordinatorTests extends ShellTestCase {
verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task), verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
eq(SPLIT_POSITION_BOTTOM_OR_RIGHT)); eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
verify(mMainStage).reparentTopTask(eq(wct)); verify(mMainStage).reparentTopTask(eq(wct));
verify(mSplitLayout).resetDividerPosition();
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition()); assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition()); assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
} }