Merge "Implement resize enter animation" into udc-dev am: 460be670c7 am: 17ab0a3fb7
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22881925 Change-Id: Ibfe10c2560483b3f342be615efe0c096daade55b Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,19 +431,20 @@ 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 = () -> {
|
va.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
transaction.setAlpha(leash, end);
|
transaction.setAlpha(leash, end);
|
||||||
transaction.apply();
|
transaction.apply();
|
||||||
mTransactionPool.release(transaction);
|
mTransactionPool.release(transaction);
|
||||||
@@ -429,58 +452,6 @@ class SplitScreenTransitions {
|
|||||||
mAnimations.remove(va);
|
mAnimations.remove(va);
|
||||||
onFinish(null /* wct */, null /* wctCB */);
|
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);
|
|
||||||
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;
|
||||||
|
|||||||
@@ -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 */);
|
||||||
|
prepareSplitLayout(wct);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareSplitLayout(WindowContainerTransaction wct) {
|
||||||
|
if (mIsDropEntering) {
|
||||||
mSplitLayout.resetDividerPosition();
|
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);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user