Merge "Correct the pair-to-pair transition animation" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
2cb51370f9
@@ -192,6 +192,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
private final SplitScreenTransitions mSplitTransitions;
|
private final SplitScreenTransitions mSplitTransitions;
|
||||||
private final SplitscreenEventLogger mLogger;
|
private final SplitscreenEventLogger mLogger;
|
||||||
private final ShellExecutor mMainExecutor;
|
private final ShellExecutor mMainExecutor;
|
||||||
|
// Cache live tile tasks while entering recents, evict them from stages in finish transaction
|
||||||
|
// if user is opening another task(s).
|
||||||
|
private final ArrayList<Integer> mPausingTasks = new ArrayList<>();
|
||||||
private final Optional<RecentTasksController> mRecentTasks;
|
private final Optional<RecentTasksController> mRecentTasks;
|
||||||
|
|
||||||
private final Rect mTempRect1 = new Rect();
|
private final Rect mTempRect1 = new Rect();
|
||||||
@@ -658,6 +661,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
// Add task launch requests
|
// Add task launch requests
|
||||||
wct.startTask(mainTaskId, mainOptions);
|
wct.startTask(mainTaskId, mainOptions);
|
||||||
|
|
||||||
|
// leave recents animation by re-start pausing tasks
|
||||||
|
if (mPausingTasks.contains(mainTaskId)) {
|
||||||
|
mPausingTasks.clear();
|
||||||
|
}
|
||||||
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, false);
|
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
|
||||||
@@ -1630,7 +1637,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateRecentTasksSplitPair() {
|
private void updateRecentTasksSplitPair() {
|
||||||
if (!mShouldUpdateRecents) {
|
// Preventing from single task update while processing recents.
|
||||||
|
if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mRecentTasks.ifPresent(recentTasks -> {
|
mRecentTasks.ifPresent(recentTasks -> {
|
||||||
@@ -2582,6 +2590,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
final TransitionInfo.Change change = info.getChanges().get(iC);
|
final TransitionInfo.Change change = info.getChanges().get(iC);
|
||||||
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
|
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
|
||||||
if (taskInfo == null || !taskInfo.hasParentTask()) continue;
|
if (taskInfo == null || !taskInfo.hasParentTask()) continue;
|
||||||
|
if (mPausingTasks.contains(taskInfo.taskId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
final @StageType int stageType = getStageType(getStageOfTask(taskInfo));
|
final @StageType int stageType = getStageType(getStageOfTask(taskInfo));
|
||||||
if (stageType == STAGE_TYPE_MAIN
|
if (stageType == STAGE_TYPE_MAIN
|
||||||
&& (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
|
&& (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
|
||||||
@@ -2654,6 +2665,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
mShowDecorImmediately = true;
|
mShowDecorImmediately = true;
|
||||||
mSplitLayout.flingDividerToCenter();
|
mSplitLayout.flingDividerToCenter();
|
||||||
}
|
}
|
||||||
|
mPausingTasks.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
finishEnterSplitScreen(finishT);
|
finishEnterSplitScreen(finishT);
|
||||||
@@ -2811,12 +2823,33 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
|
|
||||||
/** Call this when starting the open-recents animation while split-screen is active. */
|
/** Call this when starting the open-recents animation while split-screen is active. */
|
||||||
public void onRecentsInSplitAnimationStart(TransitionInfo info) {
|
public void onRecentsInSplitAnimationStart(TransitionInfo info) {
|
||||||
|
if (isSplitScreenVisible()) {
|
||||||
|
// Cache tasks on live tile.
|
||||||
|
for (int i = 0; i < info.getChanges().size(); ++i) {
|
||||||
|
final TransitionInfo.Change change = info.getChanges().get(i);
|
||||||
|
if (TransitionUtil.isClosingType(change.getMode())
|
||||||
|
&& change.getTaskInfo() != null) {
|
||||||
|
final int taskId = change.getTaskInfo().taskId;
|
||||||
|
if (mMainStage.getTopVisibleChildTaskId() == taskId
|
||||||
|
|| mSideStage.getTopVisibleChildTaskId() == taskId) {
|
||||||
|
mPausingTasks.add(taskId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addDividerBarToTransition(info, false /* show */);
|
addDividerBarToTransition(info, false /* show */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Call this when the recents animation canceled during split-screen. */
|
||||||
|
public void onRecentsInSplitAnimationCanceled() {
|
||||||
|
mPausingTasks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/** Call this when the recents animation during split-screen finishes. */
|
/** Call this when the recents animation during split-screen finishes. */
|
||||||
public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct,
|
public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct,
|
||||||
SurfaceControl.Transaction finishT, TransitionInfo info) {
|
SurfaceControl.Transaction finishT) {
|
||||||
|
mPausingTasks.clear();
|
||||||
// Check if the recent transition is finished by returning to the current
|
// Check if the recent transition is finished by returning to the current
|
||||||
// split, so we can restore the divider bar.
|
// split, so we can restore the divider bar.
|
||||||
for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
|
for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
|
||||||
@@ -2840,6 +2873,27 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
logExit(EXIT_REASON_UNKNOWN);
|
logExit(EXIT_REASON_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Call this when the recents animation finishes by doing pair-to-pair switch. */
|
||||||
|
public void onRecentsPairToPairAnimationFinish(WindowContainerTransaction finishWct) {
|
||||||
|
// Pair-to-pair switch happened so here should evict the live tile from its stage.
|
||||||
|
// Otherwise, the task will remain in stage, and occluding the new task when next time
|
||||||
|
// user entering recents.
|
||||||
|
for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
|
||||||
|
final int taskId = mPausingTasks.get(i);
|
||||||
|
if (mMainStage.containsTask(taskId)) {
|
||||||
|
mMainStage.evictChildren(finishWct, taskId);
|
||||||
|
} else if (mSideStage.containsTask(taskId)) {
|
||||||
|
mSideStage.evictChildren(finishWct, taskId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If pending enter hasn't consumed, the mix handler will invoke start pending
|
||||||
|
// animation within following transition.
|
||||||
|
if (mSplitTransitions.mPendingEnter == null) {
|
||||||
|
mPausingTasks.clear();
|
||||||
|
updateRecentTasksSplitPair();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
|
private void addDividerBarToTransition(@NonNull TransitionInfo info, boolean show) {
|
||||||
final SurfaceControl leash = mSplitLayout.getDividerLeash();
|
final SurfaceControl leash = mSplitLayout.getDividerLeash();
|
||||||
if (leash == null || !leash.isValid()) {
|
if (leash == null || !leash.isValid()) {
|
||||||
@@ -2892,6 +2946,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
|
|||||||
pw.println(innerPrefix + "SplitLayout");
|
pw.println(innerPrefix + "SplitLayout");
|
||||||
mSplitLayout.dump(pw, childPrefix);
|
mSplitLayout.dump(pw, childPrefix);
|
||||||
}
|
}
|
||||||
|
if (!mPausingTasks.isEmpty()) {
|
||||||
|
pw.println(childPrefix + "mPausingTasks=" + mPausingTasks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -377,6 +377,13 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void evictChildren(WindowContainerTransaction wct, int taskId) {
|
||||||
|
final ActivityManager.RunningTaskInfo taskInfo = mChildrenTaskInfo.get(taskId);
|
||||||
|
if (taskInfo != null) {
|
||||||
|
wct.reparent(taskInfo.token, null /* parent */, false /* onTop */);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void reparentTopTask(WindowContainerTransaction wct) {
|
void reparentTopTask(WindowContainerTransaction wct) {
|
||||||
wct.reparentTasks(null /* currentParent */, mRootTaskInfo.token,
|
wct.reparentTasks(null /* currentParent */, mRootTaskInfo.token,
|
||||||
CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES,
|
CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES,
|
||||||
|
|||||||
@@ -540,9 +540,12 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
mixed.mInFlightSubAnimations = 0;
|
mixed.mInFlightSubAnimations = 0;
|
||||||
mActiveTransitions.remove(mixed);
|
mActiveTransitions.remove(mixed);
|
||||||
// If pair-to-pair switching, the post-recents clean-up isn't needed.
|
// 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();
|
wct = wct != null ? wct : new WindowContainerTransaction();
|
||||||
mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction, info);
|
if (mixed.mAnimType != MixedTransition.ANIM_TYPE_PAIR_TO_PAIR) {
|
||||||
|
mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction);
|
||||||
|
} else {
|
||||||
|
// notify pair-to-pair recents animation finish
|
||||||
|
mSplitHandler.onRecentsPairToPairAnimationFinish(wct);
|
||||||
}
|
}
|
||||||
mSplitHandler.onTransitionAnimationComplete();
|
mSplitHandler.onTransitionAnimationComplete();
|
||||||
finishCallback.onTransitionFinished(wct, wctCB);
|
finishCallback.onTransitionFinished(wct, wctCB);
|
||||||
@@ -552,6 +555,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
|
|||||||
final boolean handled = mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info,
|
final boolean handled = mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info,
|
||||||
startTransaction, finishTransaction, finishCB);
|
startTransaction, finishTransaction, finishCB);
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
|
mSplitHandler.onRecentsInSplitAnimationCanceled();
|
||||||
mActiveTransitions.remove(mixed);
|
mActiveTransitions.remove(mixed);
|
||||||
}
|
}
|
||||||
return handled;
|
return handled;
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
|||||||
// Make sure it cleans-up if recents doesn't restore
|
// Make sure it cleans-up if recents doesn't restore
|
||||||
WindowContainerTransaction commitWCT = new WindowContainerTransaction();
|
WindowContainerTransaction commitWCT = new WindowContainerTransaction();
|
||||||
mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
|
mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
|
||||||
mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
|
mock(SurfaceControl.Transaction.class));
|
||||||
assertFalse(mStageCoordinator.isSplitScreenVisible());
|
assertFalse(mStageCoordinator.isSplitScreenVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ public class SplitTransitionTests extends ShellTestCase {
|
|||||||
mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class));
|
mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class));
|
||||||
mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class));
|
mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class));
|
||||||
mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
|
mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
|
||||||
mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
|
mock(SurfaceControl.Transaction.class));
|
||||||
assertTrue(mStageCoordinator.isSplitScreenVisible());
|
assertTrue(mStageCoordinator.isSplitScreenVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user