Improve dismiss split transition
Improve this transition by seperating it as 2 transitions: 1. Only dismiss invisible split side and extand another one side root task as full screen bounds. 2. After first transition finished, fade-out the decor surface and reparent the child task to TDA top. Bug: 200245358 Test: manual Change-Id: I1a0c4d1715765e7de0ce2628e978cab392d2b07e
This commit is contained in:
@@ -50,6 +50,8 @@ import com.android.launcher3.icons.IconProvider;
|
||||
import com.android.wm.shell.R;
|
||||
import com.android.wm.shell.common.SurfaceUtils;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Handles split decor like showing resizing hint for a specific split.
|
||||
*/
|
||||
@@ -212,7 +214,7 @@ public class SplitDecorManager extends WindowlessWindowManager {
|
||||
newBounds.height() / 2 - mIconSize / 2);
|
||||
|
||||
if (animate) {
|
||||
startFadeAnimation(show, false /* isResized */);
|
||||
startFadeAnimation(show, null /* finishedConsumer */);
|
||||
mShown = show;
|
||||
}
|
||||
}
|
||||
@@ -243,15 +245,29 @@ public class SplitDecorManager extends WindowlessWindowManager {
|
||||
mFadeAnimator.cancel();
|
||||
}
|
||||
if (mShown) {
|
||||
startFadeAnimation(false /* show */, true /* isResized */);
|
||||
mShown = false;
|
||||
fadeOutDecor(null /* finishedCallback */);
|
||||
} else {
|
||||
// Decor surface is hidden so release it directly.
|
||||
releaseDecor(t);
|
||||
}
|
||||
}
|
||||
|
||||
private void startFadeAnimation(boolean show, boolean isResized) {
|
||||
/** Fade-out decor surface with animation end callback, if decor is hidden, run the callback
|
||||
* directly. */
|
||||
public void fadeOutDecor(Runnable finishedCallback) {
|
||||
if (mShown) {
|
||||
startFadeAnimation(false /* show */, transaction -> {
|
||||
releaseDecor(transaction);
|
||||
if (finishedCallback != null) finishedCallback.run();
|
||||
});
|
||||
mShown = false;
|
||||
} else {
|
||||
if (finishedCallback != null) finishedCallback.run();
|
||||
}
|
||||
}
|
||||
|
||||
private void startFadeAnimation(boolean show,
|
||||
Consumer<SurfaceControl.Transaction> finishedConsumer) {
|
||||
final SurfaceControl.Transaction animT = new SurfaceControl.Transaction();
|
||||
mFadeAnimator = ValueAnimator.ofFloat(0f, 1f);
|
||||
mFadeAnimator.setDuration(FADE_DURATION);
|
||||
@@ -285,8 +301,8 @@ public class SplitDecorManager extends WindowlessWindowManager {
|
||||
animT.hide(mIconLeash);
|
||||
}
|
||||
}
|
||||
if (isResized) {
|
||||
releaseDecor(animT);
|
||||
if (finishedConsumer != null) {
|
||||
finishedConsumer.accept(animT);
|
||||
}
|
||||
animT.apply();
|
||||
animT.close();
|
||||
|
||||
@@ -32,6 +32,7 @@ import static com.android.wm.shell.animation.Interpolators.SLOWDOWN_INTERPOLATOR
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
|
||||
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
|
||||
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -449,11 +450,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
switch (snapTarget.flag) {
|
||||
case FLAG_DISMISS_START:
|
||||
flingDividePosition(currentPosition, snapTarget.position,
|
||||
() -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */));
|
||||
() -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */,
|
||||
EXIT_REASON_DRAG_DIVIDER));
|
||||
break;
|
||||
case FLAG_DISMISS_END:
|
||||
flingDividePosition(currentPosition, snapTarget.position,
|
||||
() -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */));
|
||||
() -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */,
|
||||
EXIT_REASON_DRAG_DIVIDER));
|
||||
break;
|
||||
default:
|
||||
flingDividePosition(currentPosition, snapTarget.position,
|
||||
@@ -509,6 +512,14 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
isLandscape ? DOCKED_LEFT : DOCKED_TOP /* dockSide */);
|
||||
}
|
||||
|
||||
/** Fling divider from current position to end or start position then exit */
|
||||
public void flingDividerToDismiss(boolean toEnd, int reason) {
|
||||
final int target = toEnd ? mDividerSnapAlgorithm.getDismissEndTarget().position
|
||||
: mDividerSnapAlgorithm.getDismissStartTarget().position;
|
||||
flingDividePosition(getDividePosition(), target,
|
||||
() -> mSplitLayoutHandler.onSnappedToDismiss(toEnd, reason));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void flingDividePosition(int from, int to, @Nullable Runnable flingFinishedCallback) {
|
||||
if (from == to) {
|
||||
@@ -758,7 +769,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
|
||||
public interface SplitLayoutHandler {
|
||||
|
||||
/** Calls when dismissing split. */
|
||||
void onSnappedToDismiss(boolean snappedToEnd);
|
||||
void onSnappedToDismiss(boolean snappedToEnd, int reason);
|
||||
|
||||
/**
|
||||
* Calls when resizing the split bounds.
|
||||
|
||||
@@ -45,6 +45,11 @@ class MainStage extends StageTaskListener {
|
||||
iconProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
void dismiss(WindowContainerTransaction wct, boolean toTop) {
|
||||
deactivate(wct, toTop);
|
||||
}
|
||||
|
||||
boolean isActive() {
|
||||
return mIsActive;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@ class SideStage extends StageTaskListener {
|
||||
iconProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
void dismiss(WindowContainerTransaction wct, boolean toTop) {
|
||||
removeAllTasks(wct, toTop);
|
||||
}
|
||||
|
||||
boolean removeAllTasks(WindowContainerTransaction wct, boolean toTop) {
|
||||
if (mChildrenTaskInfo.size() == 0) return false;
|
||||
wct.reparentTasks(
|
||||
|
||||
@@ -18,8 +18,6 @@ package com.android.wm.shell.splitscreen;
|
||||
|
||||
import static android.app.ActivityManager.START_SUCCESS;
|
||||
import static android.app.ActivityManager.START_TASK_TO_FRONT;
|
||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NO_USER_ACTION;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
@@ -107,15 +105,15 @@ public class SplitScreenController implements DragAndDropPolicy.Starter,
|
||||
RemoteCallable<SplitScreenController>, ShellTaskOrganizer.FocusListener {
|
||||
private static final String TAG = SplitScreenController.class.getSimpleName();
|
||||
|
||||
static final int EXIT_REASON_UNKNOWN = 0;
|
||||
static final int EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW = 1;
|
||||
static final int EXIT_REASON_APP_FINISHED = 2;
|
||||
static final int EXIT_REASON_DEVICE_FOLDED = 3;
|
||||
static final int EXIT_REASON_DRAG_DIVIDER = 4;
|
||||
static final int EXIT_REASON_RETURN_HOME = 5;
|
||||
static final int EXIT_REASON_ROOT_TASK_VANISHED = 6;
|
||||
static final int EXIT_REASON_SCREEN_LOCKED = 7;
|
||||
static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8;
|
||||
public static final int EXIT_REASON_UNKNOWN = 0;
|
||||
public static final int EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW = 1;
|
||||
public static final int EXIT_REASON_APP_FINISHED = 2;
|
||||
public static final int EXIT_REASON_DEVICE_FOLDED = 3;
|
||||
public static final int EXIT_REASON_DRAG_DIVIDER = 4;
|
||||
public static final int EXIT_REASON_RETURN_HOME = 5;
|
||||
public static final int EXIT_REASON_ROOT_TASK_VANISHED = 6;
|
||||
public static final int EXIT_REASON_SCREEN_LOCKED = 7;
|
||||
public static final int EXIT_REASON_SCREEN_LOCKED_SHOW_ON_TOP = 8;
|
||||
public static final int EXIT_REASON_CHILD_TASK_ENTER_PIP = 9;
|
||||
@IntDef(value = {
|
||||
EXIT_REASON_UNKNOWN,
|
||||
|
||||
@@ -189,6 +189,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
private boolean mShouldUpdateRecents;
|
||||
private boolean mExitSplitScreenOnHide;
|
||||
private boolean mIsDividerRemoteAnimating;
|
||||
private boolean mIsExiting;
|
||||
private boolean mResizingSplits;
|
||||
|
||||
/** The target stage to dismiss to when unlock after folded. */
|
||||
@@ -734,7 +735,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
|
||||
private void applyExitSplitScreen(@Nullable StageTaskListener childrenToTop,
|
||||
WindowContainerTransaction wct, @ExitReason int exitReason) {
|
||||
if (!mMainStage.isActive()) return;
|
||||
if (!mMainStage.isActive() || mIsExiting) return;
|
||||
|
||||
mRecentTasks.ifPresent(recentTasks -> {
|
||||
// Notify recents if we are exiting in a way that breaks the pair, and disable further
|
||||
@@ -746,21 +747,45 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
});
|
||||
mShouldUpdateRecents = false;
|
||||
|
||||
// When the exit split-screen is caused by one of the task enters auto pip,
|
||||
// we want the tasks to be put to bottom instead of top, otherwise it will end up
|
||||
// a fullscreen plus a pinned task instead of pinned only at the end of the transition.
|
||||
final boolean fromEnteringPip = exitReason == EXIT_REASON_CHILD_TASK_ENTER_PIP;
|
||||
mSideStage.removeAllTasks(wct, !fromEnteringPip && mSideStage == childrenToTop);
|
||||
mMainStage.deactivate(wct, !fromEnteringPip && mMainStage == childrenToTop);
|
||||
wct.reorder(mRootTaskInfo.token, false /* onTop */);
|
||||
mTaskOrganizer.applyTransaction(wct);
|
||||
if (childrenToTop == null) {
|
||||
mSideStage.removeAllTasks(wct, false /* toTop */);
|
||||
mMainStage.deactivate(wct, false /* toTop */);
|
||||
wct.reorder(mRootTaskInfo.token, false /* onTop */);
|
||||
onTransitionAnimationComplete();
|
||||
} else {
|
||||
// Expand to top side split as full screen for fading out decor animation and dismiss
|
||||
// another side split(Moving its children to bottom).
|
||||
mIsExiting = true;
|
||||
final StageTaskListener tempFullStage = childrenToTop;
|
||||
final StageTaskListener dismissStage = mMainStage == childrenToTop
|
||||
? mSideStage : mMainStage;
|
||||
tempFullStage.resetBounds(wct);
|
||||
wct.setSmallestScreenWidthDp(tempFullStage.mRootTaskInfo.token,
|
||||
mRootTaskInfo.configuration.smallestScreenWidthDp);
|
||||
dismissStage.dismiss(wct, false /* toTop */);
|
||||
}
|
||||
mSyncQueue.queue(wct);
|
||||
mSyncQueue.runInSync(t -> {
|
||||
t.setWindowCrop(mMainStage.mRootLeash, null)
|
||||
.setWindowCrop(mSideStage.mRootLeash, null);
|
||||
t.setPosition(mMainStage.mRootLeash, 0, 0)
|
||||
.setPosition(mSideStage.mRootLeash, 0, 0);
|
||||
setDividerVisibility(false, t);
|
||||
|
||||
// In this case, exit still under progress, fade out the split decor after first WCT
|
||||
// done and do remaining WCT after animation finished.
|
||||
if (childrenToTop != null) {
|
||||
childrenToTop.fadeOutDecor(() -> {
|
||||
WindowContainerTransaction finishedWCT = new WindowContainerTransaction();
|
||||
mIsExiting = false;
|
||||
childrenToTop.dismiss(finishedWCT, true /* toTop */);
|
||||
wct.reorder(mRootTaskInfo.token, false /* toTop */);
|
||||
mTaskOrganizer.applyTransaction(finishedWCT);
|
||||
onTransitionAnimationComplete();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
onTransitionAnimationComplete();
|
||||
Slog.i(TAG, "applyExitSplitScreen, reason = " + exitReasonToString(exitReason));
|
||||
// Log the exit
|
||||
if (childrenToTop != null) {
|
||||
@@ -930,9 +955,11 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
}
|
||||
|
||||
private void onStageChildTaskEnterPip(StageListenerImpl stageListener, int taskId) {
|
||||
exitSplitScreen(stageListener == mMainStageListener ? mMainStage : mSideStage,
|
||||
EXIT_REASON_CHILD_TASK_ENTER_PIP);
|
||||
private void onStageChildTaskEnterPip() {
|
||||
// When the exit split-screen is caused by one of the task enters auto pip,
|
||||
// we want both tasks to be put to bottom instead of top, otherwise it will end up
|
||||
// a fullscreen plus a pinned task instead of pinned only at the end of the transition.
|
||||
exitSplitScreen(null, EXIT_REASON_CHILD_TASK_ENTER_PIP);
|
||||
}
|
||||
|
||||
private void updateRecentTasksSplitPair() {
|
||||
@@ -1178,13 +1205,25 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
|
||||
final boolean hasChildren = stageListener.mHasChildren;
|
||||
final boolean isSideStage = stageListener == mSideStageListener;
|
||||
if (!hasChildren) {
|
||||
if (!hasChildren && !mIsExiting) {
|
||||
if (isSideStage && mMainStageListener.mVisible) {
|
||||
// Exit to main stage if side stage no longer has children.
|
||||
exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED);
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
exitSplitScreen(mMainStage, EXIT_REASON_APP_FINISHED);
|
||||
} else {
|
||||
mSplitLayout.flingDividerToDismiss(
|
||||
mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT,
|
||||
EXIT_REASON_APP_FINISHED);
|
||||
}
|
||||
} else if (!isSideStage && mSideStageListener.mVisible) {
|
||||
// Exit to side stage if main stage no longer has children.
|
||||
exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
|
||||
if (ENABLE_SHELL_TRANSITIONS) {
|
||||
exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
|
||||
} else {
|
||||
mSplitLayout.flingDividerToDismiss(
|
||||
mSideStagePosition != SPLIT_POSITION_BOTTOM_OR_RIGHT,
|
||||
EXIT_REASON_APP_FINISHED);
|
||||
}
|
||||
}
|
||||
} else if (isSideStage && !mMainStage.isActive()) {
|
||||
final WindowContainerTransaction wct = new WindowContainerTransaction();
|
||||
@@ -1208,12 +1247,12 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSnappedToDismiss(boolean bottomOrRight) {
|
||||
public void onSnappedToDismiss(boolean bottomOrRight, int reason) {
|
||||
final boolean mainStageToTop =
|
||||
bottomOrRight ? mSideStagePosition == SPLIT_POSITION_BOTTOM_OR_RIGHT
|
||||
: mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT;
|
||||
if (!ENABLE_SHELL_TRANSITIONS) {
|
||||
exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, EXIT_REASON_DRAG_DIVIDER);
|
||||
exitSplitScreen(mainStageToTop ? mMainStage : mSideStage, reason);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1615,7 +1654,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
/** Called to clean-up state and do house-keeping after the animation is done. */
|
||||
public void onTransitionAnimationComplete() {
|
||||
// If still playing, let it finish.
|
||||
if (!mMainStage.isActive()) {
|
||||
if (!mMainStage.isActive() && !mIsExiting) {
|
||||
// Update divider state after animation so that it is still around and positioned
|
||||
// properly for the animation itself.
|
||||
mSplitLayout.release();
|
||||
@@ -1911,8 +1950,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChildTaskEnterPip(int taskId) {
|
||||
StageCoordinator.this.onStageChildTaskEnterPip(this, taskId);
|
||||
public void onChildTaskEnterPip() {
|
||||
StageCoordinator.this.onStageChildTaskEnterPip();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,7 +71,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
|
||||
void onChildTaskStatusChanged(int taskId, boolean present, boolean visible);
|
||||
|
||||
void onChildTaskEnterPip(int taskId);
|
||||
void onChildTaskEnterPip();
|
||||
|
||||
void onRootTaskVanished();
|
||||
|
||||
@@ -103,6 +103,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* General function for dismiss this stage.
|
||||
*/
|
||||
void dismiss(WindowContainerTransaction wct, boolean toTop) {}
|
||||
|
||||
int getChildCount() {
|
||||
return mChildrenTaskInfo.size();
|
||||
}
|
||||
@@ -255,7 +260,7 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
return;
|
||||
}
|
||||
if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) {
|
||||
mCallbacks.onChildTaskEnterPip(taskId);
|
||||
mCallbacks.onChildTaskEnterPip();
|
||||
}
|
||||
sendStatusChanged();
|
||||
} else {
|
||||
@@ -297,6 +302,14 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
}
|
||||
}
|
||||
|
||||
void fadeOutDecor(Runnable finishedCallback) {
|
||||
if (mSplitDecorManager != null) {
|
||||
mSplitDecorManager.fadeOutDecor(finishedCallback);
|
||||
} else {
|
||||
finishedCallback.run();
|
||||
}
|
||||
}
|
||||
|
||||
void addTask(ActivityManager.RunningTaskInfo task, WindowContainerTransaction wct) {
|
||||
// Clear overridden bounds and windowing mode to make sure the child task can inherit
|
||||
// windowing mode and bounds from split root.
|
||||
@@ -330,6 +343,11 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
||||
}
|
||||
}
|
||||
|
||||
void resetBounds(WindowContainerTransaction wct) {
|
||||
wct.setBounds(mRootTaskInfo.token, null);
|
||||
wct.setAppBounds(mRootTaskInfo.token, null);
|
||||
}
|
||||
|
||||
void onSplitScreenListenerRegistered(SplitScreen.SplitScreenListener listener,
|
||||
@StageType int stage) {
|
||||
for (int i = mChildrenTaskInfo.size() - 1; i >= 0; --i) {
|
||||
|
||||
@@ -133,7 +133,7 @@ public class SplitLayoutTests extends ShellTestCase {
|
||||
|
||||
mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
|
||||
waitDividerFlingFinished();
|
||||
verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false));
|
||||
verify(mSplitLayoutHandler).onSnappedToDismiss(eq(false), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -145,7 +145,7 @@ public class SplitLayoutTests extends ShellTestCase {
|
||||
|
||||
mSplitLayout.snapToTarget(0 /* currentPosition */, snapTarget);
|
||||
waitDividerFlingFinished();
|
||||
verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true));
|
||||
verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -127,6 +127,9 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
mRootTask = new TestRunningTaskInfoBuilder().build();
|
||||
mRootLeash = new SurfaceControl.Builder(mSurfaceSession).setName("test").build();
|
||||
mStageCoordinator.onTaskAppeared(mRootTask, mRootLeash);
|
||||
|
||||
mSideStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
|
||||
mMainStage.mRootTaskInfo = new TestRunningTaskInfoBuilder().build();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -224,8 +227,8 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
|
||||
verify(mMainStage).reorderChild(eq(testTaskId), eq(true),
|
||||
any(WindowContainerTransaction.class));
|
||||
verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(false));
|
||||
verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(true));
|
||||
verify(mSideStage).dismiss(any(WindowContainerTransaction.class), eq(false));
|
||||
verify(mMainStage).resetBounds(any(WindowContainerTransaction.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -237,8 +240,8 @@ public class StageCoordinatorTests extends ShellTestCase {
|
||||
mStageCoordinator.exitSplitScreen(testTaskId, EXIT_REASON_RETURN_HOME);
|
||||
verify(mSideStage).reorderChild(eq(testTaskId), eq(true),
|
||||
any(WindowContainerTransaction.class));
|
||||
verify(mSideStage).removeAllTasks(any(WindowContainerTransaction.class), eq(true));
|
||||
verify(mMainStage).deactivate(any(WindowContainerTransaction.class), eq(false));
|
||||
verify(mSideStage).resetBounds(any(WindowContainerTransaction.class));
|
||||
verify(mMainStage).dismiss(any(WindowContainerTransaction.class), eq(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user